ITS-5.4

Transcription

ITS-5.4
5.4 Schwachstellenanalyse
Typische Beispiele für Schwachstellen (vulnerabilities):
 Pufferüberlauf
 Skript-Manipulation (SQL-Injektion)
 ungeschützte kritische Abschnitte
 Bisweilen hilft Datenflussanalyse des verdächtigen Codes.
ITS-5.4
1
5.4.1 Pufferüberlauf
Das Problem (2.5):
 Unsichere Programmiersprachen (wie C, C++, ...) lassen zu,
dass beim Beschreiben eines Feldes jenseits der Feldgrenzen
geschrieben wird.
 Die Effekte solcher Programmfehler sind undefiniert
- üblicherweise werden benachbarte Daten in
Mitleidenschaft gezogen.
ITS-5.4
2
 Wenn Eingabedaten direkt oder indirekt in gefährdete Felder
fließen, können Angreifer solche Programmfehler ausnutzen:
mit gezielt gewählten Eingabedaten können Sicherheitsverletzungen bewirkt werden.
 Mehr als die Hälfte aller Sicherheitswarnungen des CERT
betreffen Angriffe, die mit Pufferüberlauf arbeiten!
Der Schaden:
 Gezieltes Einschleusen von Daten in andere Variable
- oder gar Einschleusen von eigenem Code.
Voraussetzung:
Kenntnis des Codes (und des Übersetzers)
(aber: security by obscurity ist keine Lösung!)
ITS-5.4
3
Beachte:
„Is it a bug or a feature?“
 Die Schwachstelle kann ein unbeabsichtigter Qualitätsmangel sein
(Mangel an Stabilität/Robustheit gegenüber falschen Eingaben),
 oder es handelt sich um eine absichtlich eingebaute Geheimtür
(Hintereingang, backdoor).
ITS-5.4
4
Die Lösung:
am besten:
nur sichere Programmiersprachen benutzen
(Notbehelf: Keller-Manipulation entdecken:
2.6, so auch mit MS Visual C++ /GS *)
am zweitbesten:
Felder, insbesondere Zeichenketten, nur mit
sicheren Bibliotheksfunktionen bearbeiten
sonst:
extreme Vorsicht,
extensive Code Reviews,
werkzeuggestützte Code-Analyse
Literatur:
M. Howard, D. LeBlanc: Writing Secure Code.
Microsoft Press 2003
* Compiler option /GS:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vclrfGSBufferSecurity.asp
ITS-5.4
5
5.4.1.1 Angriffs-Varianten
gezielte Änderung einer benachbarten Variablen

(zur Erinnerung: Aufgabe 2.2)

Zerstörung der Keller-Organisation (Rücksprungadresse!)
und damit Abschießen eines Servers ( denial of service)
(2.6)

gezielte Einschleusung von eigenem Code, der durch
gezielte Manipulation der Rücksprungadresse im Keller
aktiviert wird  Mutation eines Servers oder
SUID-Programms zum Schadprogramm

ähnliches auf der Halde (erheblich schwieriger, kommt aber vor)
ITS-5.4
6
5.4.1.2 Vorsicht beim Kopieren von Zeichenketten!
(2.6)
gets, fgets
string, strcasecmp, strncasecmp, strcat, strncat,
strlcat, strchr, strrchr, strcmp, strncmp, strcpy,
strncpy, strlcpy, strcspn, strspn, strdup, strlen,
strpbrk, strstr, strtok, strtok_r
printf, fprintf, sprintf, snprintf
(Windows:)
StringCchCopy, StringCchCat, ...
ITS-5.4
count characters (!)
7
Vorsicht mit Unicode-Zeichen: 1 Zeichen = 2 Bytes !
// WCHAR = wide character = Unicode character
WCHAR src[] = "To be or not to be"; // 18 chars
WCHAR dest[16]; // 32 bytes
...
StringCchCopyW(dest,sizeof(dest),src);
32 !
 kopiert maximal 32 Unicode-Zeichen, nicht nur 16 !
Merkregel:
Makro verwenden
#define Length(x) = sizeof(x)/sizeof(x[0])
...
StringCchCopyW(dest,Length(dest),src);
ITS-5.4
8
5.4.1.3 Verwandtes Problem: printf
... bedingt durch drei Schwächen des Formatierers von C/C++ :

printf("... %s ... %i ... %n ...", string, number, &count);
speichere Anzahl bisher verarbeiteter Zeichen
übernimm Zeichenkette bzw. Ganzzahl

Variable Parameterliste ohne Längenüberprüfung !
 printf greift ins Leere - d.h. irgendwo in den Keller - ,
wenn weniger Argumente als vom Formatierer gewünscht

printf(string);
ITS-5.4
ist erlaubt (Konsequenz von )
9
printf("%s", text);
ist in Ordnung
printf(text);
ist Schwachstelle! Vermeiden!
(wenn char *text aus der Eingabe kommt)
Strategie des Angreifers:



statt Text einen langen Formatierer
eingeben, der wie folgt konstruiert ist:
an geeigneter Stelle ist ein %n enthalten
an geeigneter Stelle ist die Adresse einer Zelle enthalten,
auf die sich das %n beziehen soll
vor dem %n wird mit hinreichend vielen % gesteuert,
welcher Wert in diese Zelle gelangen soll
 Damit prinzipiell jede Umwandlung zum Schadprogramm möglich:
ITS-5.4
10
Der Trick dabei:
Der Formatierer wird von printf abgearbeitet;
dabei wird für die vielen % auf den Keller zugegriffen
und damit irgendwann auch auf den Formatierer selbst und damit werden Teile von ihm als Argumente interpretiert,
und damit wird die Adresse für das %n untergeschoben:
..... %x
%x
angewandt auf
.........
%x%x
%x
(ohne Leerzeichen)
%x%n
Ausgabe:...78257825 78256e25
Knifflig:
ITS-5.4
%n \xC0\x2A\xF5\x01
\xC0\x2A\xF5\x01
?*?
richtig beginnen mit ..... , und Adresse i.a.
an anderer Stelle plazieren
(Bekannt - zunächst im Untergrund - seit den 90er Jahren)
11
5.4.1.4 Verwendung sicherer Bibliotheksfunktionen
Typ string in der Standard Template Library von C++:
#include <string>
using namespace std;
int main() {
string s; .....
ähnlich dem String in Java (aber Werttyp, nicht Verweistyp)
StringCchCopy, StringCchCat, ...
sind etwas sicherer als gets, strcpy, ...
ITS-5.4
12
5.4.1.5 Eingaben vollständig überprüfen!
Spezifikation (!):
Präzise spezifizieren, welche Eingaben erlaubt sind!
Korrekte Implementierung:
Alle nicht erlaubten Eingaben sofort zurückweisen!
ITS-5.4
13
5.4.1.6 Werkzeuggestützte Code-Analyse
Mustererkennung (etwas besser als mit grep strcpy)
J. Viega et al.: ITS4: A Static Vulnerability Scanner for ...
www.acsac.org/2000/papers/78.pdf [2000], www.cigital.com/its4
integer range constraints
D. Wagner et al.: A First Step towards Automated Detection ...
www.cs.berkeley.edu/~daw/papers/overruns-ndss00.pdf [2000]
Erweiterung von LCLint: semantisch annotierte Bibliotheksfunktionen
D. Larochelle et al.: Statically Detecting Likely Buffer Overflow ...
www.cs.virginia.edu/~evans/usenix01-abstract.html [2001]
Erweiterung des Übersetzers: Regelmenge zur Code-Prüfung
K. Ashcraft et al.: Using Programmer-Written Compiler Extensions ...
http://portal.acm.org/citation.cfm?id=830533 zur [2002]
Beachte:
ITS-5.4
Weder schließen diese Ansätze Fehlalarme aus
noch entdecken sie alle Fehler !
14
Artikel der Woche:
D. Wagner et al.: A First Step towards Automated Detection
of Buffer Overrun Vulnerabilities.
Proc. 10. ACM Conf. on Computer and Communications Security, 2003
www.cs.berkeley.edu/~daw/papers/overruns-ndss00.pdf
ITS-5.4
15
5.4.1.7 Testen
kann eingesetzt werden, um Pufferüberläufe nachzuweisen
Fuzzing:
Programm wird mit Zufallseingaben bombardiert,
je verrückter, desto besser. Reaktionen des Programms:
 kein Absturz
 Absturz, also Programmfehler  sicherheitskritisch?!
http://sourceforge.net/projects/sharefuzz
http://www.cs.wisc.edu/~bart/fuzz/fuzz.html
ITS-5.4
16
Gezieltere Vorgehensweise:
E. Haugh, M. Bishop:
Testing C Programs for Buffer Overflow Vulnerabilities
http://seclab.cs.ucdavis.edu/papers/HaughBishopNDSS2003.ps
Dynamische Variante der statischen Analyse von D. Wagner et al.
Werkzeug STOBO (Systematic Testing of Buffer Overflows):
char dst[256];
wird durch STOBO instrumentiert:
char dst[256];
__STOBO_stack_buf(dst, sizeof(dst));
Damit wird die vereinbarte Puffergröße dynamisch in einer
Tabelle festgehalten.
ITS-5.4
17
Bei den Testläufen werden die Längen der jeweils beteiligten
Puffer und Zeichenketten überprüft.
Auch wenn die Testdaten keinen Pufferüberlauf verursachen,
können eventuell mögliche Pufferüberläufe erkannt werden ...
... und es werden entsprechende Warnungen ausgegeben.
Die entsprechenden Programmstellen sind dann zu prüfen.
ITS-5.4
18
5.4.2 SQL-Injektion
Allgemeines Szenario mit Skriptsprache:
 Programm kooperiert mit Interpretierer für eine Skriptsprache
 Die zu interpretierenden Skripte werden aus vordefinierten
Teilen und Benutzereingaben zusammengesetzt
 Bei unzureichender Überprüfung der Eingaben können
irreguläre Eingaben die Skripte zu Schadcode machen
Beispiel:
ITS-5.4
SQL ist eine Skriptsprache für Datenbanken,
die vom Datenbanksystem interpretiert wird (4.4.2)
19
Beispiel: SQL in Java-Programm mit JDBC (java.sql):
( Statement ist Schnittstelle zu objektifizierter SQL-Abfrage)
Statement s = connection.createStatement();
s.execute(“SELECT title FROM books
WHERE author=‘Joyce’;”);
ResultSet r = s.getResultSet();
String userid = getInput(); // from some input stream
s.execute(“SELECT * FROM accounts
WHERE user=‘” + userid + “’;”);
gebräuchlich, aber riskant:
ITS-5.4
20
Szenario:
 Normalbenutzer hat keine Rechte an accounts (4.4.2)
 setuid- oder Server-Prozess hat select-Recht an accounts*
String userid = getInput(); // from some input stream
s.execute(“SELECT * FROM accounts
WHERE user=‘” + userid + “’;”);
ResultSet r = s.getResultSet();
..... // output results
reguläre Eingabe z.B. “lohr”
 liefert eine Zeile der Tabelle
irreguläre Eingabe z.B. “lohr’ OR ‘x’=‘x” injizierter SQL-Code
 WHERE user= ‘lohr’ OR ‘x’=‘x’;
 liefert Inhalt der gesamten Tabelle!
ITS-5.4
* connection als DB-Verwalter hergestellt (Passwort!)
21
… und viel schlimmer:
s.execute(“SELECT * FROM accounts
WHERE user=‘” + userid + “’;”);
mit folgender Eingabe für userid :
“lohr’;
DROP TABLE accounts;
SELECT * FROM bla WHERE attr1=‘?”
bewirkt
SELECT * FROM accounts WHERE user=‘lohr’;
DROP TABLE accounts;
SELECT * FROM bla WHERE attr1=‘?’;
und damit das Löschen der Tabelle accounts !
(Vor.: mehrfache SQL Statements werden unterstützt)
ITS-5.4
22
… und viele andere Angriffe!
Schutzmaßnahme:
Parametrisierte SQL-Befehle verwenden, z.B. so in Java:
PreparedStatement s = connection.prepareStatement(
"SELECT * FROM accounts WHERE user = ?");
s.setString(1,userid);
ResultSet r = s.executeQuery();
ITS-5.4
23
5.4.3 Vorsicht mit kritischen Abschnitten!
Gefahr:
Programmierer geht irrigerweise davon aus,
dass während der Ausführung seines Programms
keine Änderungen in der Umgebung stattfinden z.B. im Dateisystem.
Angreifer nutzt dies aus.
Szenario:
Programm
Angreifer
prüfe Datei x
ändere x
bearbeite x
ITS-5.4
24
if(!access(file,W_OK) ) {
// write access ok
// gap for attack is here
int fd = open(file,O_WRONLY,0);
write(fd,text,sizeof(text));
printf("written alright\n"); }
else printf("no write access\n");
"TOCTOU" : time of check - time of use
Wo könnte dieser Code stehen?
In einem setuid-Programm von root, das in eine vom Aufrufer
übergebene Datei schreibt. Um nicht aus Versehen in eine für
den Aufrufer nicht schreibbare Datei zu schreiben - denn root
kann überallhin schreiben! - wird zuvor geprüft, ob der Aufrufer
das Schreibrecht hat (access legt die real UID zugrunde!).
[! Professionell wäre, die EUID umzusetzen anstatt access zu verwenden!]
ITS-5.4
25
Was macht der Angreifer?
Er bringt es fertig, in der gefährdeten Lücke die Datei, die sich
hinter file verbirgt, durch eine andere zu ersetzen, z.B. durch
die Passwort-Datei - die dann überschrieben wird!
$ ln -s myWritableFile link
$ setuidprog link &
.....
if(!access(file,W_OK) ) {
$ rm link; ln -s /etc/passwd link
// gap for attack
int fd = open(file,O_WRONLY,0);
Timing überlegen! Automatisiert wiederholt versuchen!
(Mehr zum Thema z.B. Viega/McGraw: Building Secure Software)
ITS-5.4
Und Garfinkel/Spafford S. 122 ?!
26