Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Über die Autoren
Über dieses Buch
Linux vs. BSD
1 Der Kernel
2 Die Grundlagen aus Anwendersicht
3 Die Shell
4 Reguläre Ausdrücke
5 Tools zur Dateibearbeitung
6 Die Editoren
7 Shellskriptprogrammierung
8 Benutzerverwaltung
9 Grundlegende Verwaltungsaufgaben
10 Netzwerk-Grundlagen
11 Anwendersoftware für das Netzwerk
12 Netzwerkdienste
13 Mailserver unter Linux
14 LAMP
15 DNS-Server
16 Secure Shell
17 Die grafische Oberfläche
18 Window-Manager und Desktops
19 X11-Programme
20 Multimedia und Spiele
21 Softwareentwicklung
22 Crashkurs in C und Perl
23 Sicherheit
24 Prozesse und IPC
25 Bootstrap und Shutdown
26 Dateisysteme
27 Virtualisierung und Emulatoren
A Die Installation
B Lösungen zu den einzelnen Aufgaben
C Kommandoreferenz
D X11-InputDevices
E MBR
F Die Buch-DVDs
G Glossar
H Literatur

Download:
- ZIP, ca. 6,3 MB
Buch bestellen
Ihre Meinung?

Spacer
 <<   zurück
Linux von Johannes Plötner, Steffen Wendzel
Das distributionsunabhängige Handbuch
Buch: Linux

Linux
2., aktualisierte und erweiterte Auflage
1119 S., 39,90 Euro
Galileo Computing
ISBN 978-3-8362-1090-4
gp 21 Softwareentwicklung
  gp 21.1 Interpreter und Compiler
    gp 21.1.1 C und C++
    gp 21.1.2 Perl
    gp 21.1.3 Java
    gp 21.1.4 Tcl
    gp 21.1.5 Was es sonst noch gibt
  gp 21.2 Shared Libraries
    gp 21.2.1 Vorteile der Shared Libraries
    gp 21.2.2 Statisches Linken
    gp 21.2.3 Die Dateien
  gp 21.3 Debugging
    gp 21.3.1 Vorbereitung
    gp 21.3.2 Konsolenarbeit
    gp 21.3.3 ddd
  gp 21.4 Profiling
    gp 21.4.1 Compileroption
    gp 21.4.2 gprof verwenden
    gp 21.4.3 Profiling-Daten lesen
  gp 21.5 Tracing
  gp 21.6 Hilfe beim Finden von Bugs
    gp 21.6.1 ProPolice
    gp 21.6.2 flawfinder und RATS
    gp 21.6.3 Electric Fence
  gp 21.7 Integrierte Entwicklungsumgebungen
  gp 21.8 make
    gp 21.8.1 Makefile
    gp 21.8.2 Makefile-Makros
    gp 21.8.3 Shell-Variablen in Makefiles
    gp 21.8.4 Einzelne Targets übersetzen
    gp 21.8.5 Spezielle Targets
    gp 21.8.6 Tipps im Umgang mit make
  gp 21.9 Die GNU Autotools
  gp 21.10 lex/flex und yacc/bison
    gp 21.10.1 flex grundlegend anwenden
    gp 21.10.2 bison/yacc grundlegend anwenden
  gp 21.11 Unix-Software veröffentlichen
    gp 21.11.1 Wichtige Dateien
  gp 21.12 Manpages erstellen
    gp 21.12.1 groff nutzen
    gp 21.12.2 Die Manpage installieren
  gp 21.13 Versionsmanagement
    gp 21.13.1 CVS
    gp 21.13.2 Subversion
  gp 21.14 Wichtige Bibliotheken
    gp 21.14.1 Entwicklung grafischer Oberflächen
    gp 21.14.2 Weitere Bibliotheken
  gp 21.15 Zusammenfassung
  gp 21.16 Aufgaben


Galileo Computing

21.6 Hilfe beim Finden von Bugs  downtop

Dieser Abschnitt wird sich damit befassen, wie man mithilfe verschiedener Programme, Bugs in Softwareprojekten finden kann. Zu diesem Zweck werden wir das folgende C-Programm analysieren, das ich absichtlich mit diversen Bugs versehen habe.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <err.h> 
 
int 
main(int argc, char *argv[]) 
{ 
        char buf[16] = { '\0' }; 
        char *p; 
 
        if (argc > 1) 
                strcpy(buf, argv[1]); 
 
        p = (char *) calloc(15, 1); 
        if (p) { 
                int i; 
                for (i = 0; i <= 16; i++) 
                        p[i] = buf[i]; 
                printf("%s\n", p); 
        } else 
                err(1, "calloc"); 
 
        return 0; 
}

Listing 21.28    bug1.c

Dieses Programm ist anfällig für den typischen Buffer-Overflow. Das bedeutet, dass ein statischer Buffer (hier mit einer Größe von 16 Byte (0xf)) überschrieben wird. Überschrieben werden kann der Buffer, falls das erste Argument, das dem Programm übergeben wurde, größer als 15 Bytes ist. Denn in diesem Fall wird das sechzehnte Zeichen, das eigentlich eine abschließende Null sein sollte, überschrieben. Werden noch mehr Bytes überschrieben, so werden andere Variablen der Stackframe oder auch auf dem Stack gesicherte Registerwerte überschrieben. Dieses Problem haben wir bereits sehr genau in unserem Buch »Praxisbuch Netzwerksicherheit« beschrieben.

Das zweite große Problem ist, dass der Pointer »p« kleiner als der Buffer »buf« ist. Da in ihn allerdings der gesamte Buffer sowie zwei zusätzliche Bytes kopiert werden, wird auch dieser Heap-Buffer überschrieben. <Auch zum Thema Heap-Overflows finden Sie weitere Informationen in unserem »Praxisbuch Netzwerksicherheit«.> Man bezeichnet ein solches Problem, bei dem ein Buffer um ein Byte überschrieben wird, als Off-by-One Overflow. In unserem Fall liegt ein zweifacher Off-by-One Bug vor, da die Schleife erstens nur bis 15 (und nicht 16) durchlaufen sollte und zweitens ein < anstelle von <= verwendet werden müsste.


Galileo Computing

21.6.1 ProPolice  downtop

Seit der Version 3.4 ist der sogenannte ProPolice Patch – eine Entwicklung von IBM – für den GNU C Compiler verfügbar. <Seit gcc-4.1 ist sie fester Bestandteil des gcc.> Diese Erweiterung macht es möglich, dass Buffer-Overflows innerhalb einer Stackframe verhindert werden können. Zu diesem Zweck wird der Stack etwas modifiziert: Lokale Stack-Variablen, die keine Buffer sind, werden vor den Buffern plaziert, sodass Buffer (deren Elemente in die entgegengesetzte Richtung aufsteigen) nur andere Buffer überschreiben können. Hinter den Buffern wird zudem ein spezieller Canary-Wert eingefügt.

Dieser Zufallswert wird bei einem Overflow überschrieben, wodurch die Veränderung des Wertes entdeckt werden kann. In diesem Fall wird das Programm abgebrochen.

Wir setzen die ProPolice-Eerweiterung seit geraumer Zeit in der Entwicklung der »Hardened Linux«-Distribution ein. Auch andere Distributionen (etwa Ubuntu oder Adamantix) benutzen diese Erweiterung mittlerweile standardmäßig.

Ein Test

Versuchen wir nun, das obige Programm zu einem Overflow zu führen. Anschließend werden wir es mit ProPolice schützen (-fstack-protector) und sehen, dass das Programm gekillt wird.

Achtung: Bei Ubuntu muss zur Übersetzung ohne die Stack Protection explizit -fno-stack-protector gesetzt werden, da sie automatisch aktiv ist.

$ gcc -o bug1 bug1.c 
$ ./bug1 123 
123 
$ ./bug1 `perl -e 'print "A"x99'` 
AAAAAAAAAAAAAAAA 
 
Segmentation fault (core dumped) 
$ gcc -o bug1 bug1.c -fstack-protector 
$ ./bug1 `perl -e 'print "A"x99'` 
AAAAAAAAAAAAAAAAA 
*** stack smashing detected ***: ./bug1 terminated 
Abort (core dumped)

Listing 21.29    ProPolice Protection

Mit ProPolice steht dem Programmierer also eine Erweiterung zur Verfügung, die oft in der Lage ist, Schlimmeres zu verhindern. <Es gibt Möglichkeiten, ProPolice zu umgehen, aber diese hier zu besprechen würde zu weit führen.>


Galileo Computing

21.6.2 flawfinder und RATS  downtop

Besser noch ist es, wenn man in der Lage ist, solche Bugs während der Entwicklung zu finden, um die gezielte Programmbeendigung durch die ProPolice gar nicht erst stattfinden zu lassen.

Hierbei helfen Programme wie flawfinder, das mittlerweile nicht mehr weiterentwickelte pscan oder RATS.

Für all diese Tools gilt allerdings, dass ihre Ausgaben von Hand überprüft werden müssen. Es handelt sich bei allen Angaben immer nur um mögliche Bugs und Sicherheitsprobleme.

flawfinder

flawfinder wurde von David Wheeler entwickelt und wird zur Analyse von C/C++-Code eingesetzt. Es untersucht den Quellcode nach bestimmten tückischen Funktionen, die zu Problemen führen können. Zudem erkennt es einige gängige Fehlerquellen.

$ flawfinder bug1.c 
Flawfinder version 1.26, (C) 2001-2004 David A. Wheeler. 
Number of dangerous functions in C/C++ ruleset: 158 
Examining bug1.c 
bug1.c:13:  [4] (buffer) strcpy: 
  Does not check for buffer overflows when copying to 
  destination. Consider using strncpy or strlcpy 
  (warning, strncpy is easily misused). 
bug1.c:9:  [2] (buffer) char: 
  Statically-sized arrays can be overflowed. Perform 
  bounds checking, use functions that limit length, 
  or ensure that the size is larger than the maximum 
  possible length. 
 
Hits = 2 
Lines analyzed = 26 in 0.54 seconds (678 lines/second) 
Physical Source Lines of Code (SLOC) = 21 
Hits@level = [0]   0 [1]   0 [2]   1 [3]   0 [4]   1 
[5]   0 
Hits@level+ = [0+]   2 [1+]   2 [2+]   2 [3+]   1 [4+] 
1 [5+]   0 
Hits/KSLOC@level+ = [0+] 95.2381 [1+] 95.2381 [2+] 
95.2381 [3+] 47.619 [4+] 47.619 [5+]   0 
Minimum risk level = 1 
Not every hit is necessarily a security vulnerability. 
There may be other security vulnerabilities; review 
your code!

Listing 21.30    flawfinder untersucht bug.cc

Wie Sie sehen, weist flawfinder auf zwei Probleme hin: Zum einen wird die unsichere Funktion strcpy() verwendet, die einen Buffer ohne Längenüberprüfung in einen anderen kopiert. Dies kann durch entsprechende Verwendung von strncpy oder auch strlcpy() verhindert werden, aber auch diese Funktionen müssen fehlerfrei verwendet werden, damit sie nicht zu Bugs führen.

Zum anderen wird auf die statische Größe des Buffers hingewiesen, was oftmals zu Overflow-Problemen führen kann. Den Off-by-One Bug hat flawfinder also nicht entdeckt.

RATS

Das Programm RATS funktioniert ähnlich wie flawfinder, unterstützt aber auch PHP-, Python- und Perl-Code. Wie Sie sehen, findet RATS in unserem Fall keine weiteren Fehler und liefert ein gleichwertiges Ergebnis wie flawfinder.

$ rats bug1.c 
Entries in perl database: 33 
Entries in python database: 62 
Entries in c database: 336 
Entries in php database: 55 
Analyzing bug1.c 
bug1.c:9: High: fixed size local buffer 
Extra care should be taken to ensure that character 
arrays that are allocated on the stack are used 
safely.  They are prime targets for buffer overflow 
attacks. 
 
bug1.c:13: High: strcpy 
Check to be sure that argument 2 passed to this 
function call will not copy more data than can be 
handled, resulting in a buffer overflow. 
 
Total lines analyzed: 27 
Total time 0.019469 seconds 
1386 lines per second

Listing 21.31    RATS scannt bug1.c.


Galileo Computing

21.6.3 Electric Fence  toptop

Um den Heap-Overflow in bug1.c zu finden, brauchen wir ein weiteres Tool: Electric Fence.

Electric Fence ist eine Bibliothek, die in der Lage ist, Zugriffe auf nicht reservierten Speicher zu finden. Oftmals gehört ein Speicher, der überschrieben wurde, noch zum Kontext des Programms, wodurch das Programm weiterläuft und der Bug nicht aufgedeckt wird. Flawfinder sorgt hingegen dafür, dass das Programm in einem solchen Fall sofort abstürzt.

Wie wir sehen, stürzt das Programm in unserem Fall tatsächlich nicht ab, auch wenn wir dem Programm ganze 16 Bytes übergeben. Beachten Sie zudem, dass die Anzahl der übergebenen Bytes auf den Heap-Buffer keinen Einfluss hat, da immer so viel Bytes in ihn kopiert werden, wie es Schleifendurchläufe gibt.

Achtung: Auch hier gilt, dass bei Distributionen wie Ubuntu, die standardmäßig die Stack Protection aktiviert haben, diese explizit abgestellt werden muss.

$ gcc -o bug1 bug1.c 
$ ./bug1 `perl -e 'print "A"x16;'` 
AAAAAAAAAAAAAAAA

Listing 21.32    Das Programm stürzt nicht ab.

Nun übersetzen wir das Programm mit der Electrice Fence Library. Um es im GNU Debugger analysieren zu können, übergeben wir zudem den Parameter -g. Da die Anzahl der Bytes für den Overflow im Heap-Buffer nicht relevant ist, können wir das Programm ohne Parameter starten.

$ gcc -g -o bug1 bug1.c -fno-stack-protector -lefence 
$ ./bug1 
 
  Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens. 
Segmentation fault (core dumped)

Listing 21.33    Electrice Fence

Wie Sie sehen, lässt Electric Fence das Programm tatsächlich abstürzen. Nun werden wir eine Analyse im GNU Debugger durchführen.

$ gdb bug1 
GNU gdb 6.6-debian 
Copyright (C) 2006 Free Software Foundation, Inc. 
GDB is free software, covered by the GNU General 
Public License, and you are welcome to change it 
and/or distribute copies of it under certain 
conditions. 
Type "show copying" to see the conditions. 
There is absolutely no warranty for GDB.  Type 
"show warranty" for details. 
This GDB was configured as "i486-linux-gnu"... 
Using host libthread_db library 
"/lib/tls/i686/cmov/libthread_db.so.1". 
(gdb) run 
Starting program: 
/home/swendzel/books/kompendium2/examples/bugs/bug1 
[Thread debugging using libthread_db enabled] 
[New Thread –1210296640 (LWP 6405)] 
 
  Electric Fence 2.1 Copyright (C) 1987-1998 
        Bruce Perens. 
 
Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread –1210296640 (LWP 6405)] 
0x0804857c in main (argc=1, argv=0xbfb06284) at bug1.c:19 
19                              p[i] = buf[i]; 
(gdb) list 19 
14 
15              p = (char *) calloc(15, 1); 
16              if (p) { 
17                      int i; 
18                      for (i = 0; i <= 16; i++) 
19                              p[i] = buf[i]; 
20                      printf("%s\n", p); 
21              } else 
22                      err(1, "calloc"); 
23 
(gdb) quit 
The program is running.  Exit anyway? (y or n) y

Listing 21.34    bug1 im gdb

Fazit

Electric Fence hat unseren Speicherzugriffsfehler gefunden. In Kombination mit einem anderen Programm wie flawfinder oder RATS steht einem hiermit eine sehr vernünftige Toolchain zur Analyse von Code zur Verfügung.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






 <<   zurück
  
  Zum Katalog
Zum Katalog: Linux






 Linux
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: Einstieg in Linux






 Einstieg in Linux


Zum Katalog: Debian GNU/Linux






 Debian GNU/Linux


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu GNU/Linux


Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-
 Programmierung


Zum Katalog: Praxisbuch Netzwerk-Sicherheit






 Praxisbuch
 Netzwerk-Sicherheit


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de