Podstawy bezpieczeństwa PHP – Full Path Disclosure
Napisał: Patryk Krawaczyński
23/05/2010 w Ataki Internetowe, Bezpieczeństwo Brak komentarzy. (artykuł nr 259, ilość słów: 624)
F
ull Path Disclosure (FPD) – polega na ujawnieniu pełnej ścieżki dostępu (np. /var/www/test.php) do wadliwie skonstruowanego lub źle wywołanego skryptu. Błąd FPD najczęściej wywoływany jest poprzez wstrzykiwanie nieoczekiwanych i niefiltrowanych znaków oraz poleceń do parametrów skryptów na stronie internetowej. Skrypt, który przyjmuje określone parametry po wstrzyknięciu nieoczekiwanego znaku zwraca komunikat błędu, w którym zawarte są informacje na temat napotkanego błędu oraz pełna ścieżka dostępu do wywołanego skryptu.
Luki tego typu klasyfikowane są generalnie jako niskiego lub średniego zagrożenia, jednak mogą zostać wykorzystane pośrednio jako środki do przeprowadzania innych znacznie groźniejszych ataków np. Local File Include, czy SQL Injection z wykorzystaniem funkcji MySQL load_file(). FPD bazuje głównie na publicznym wyświetlaniu błędów programistycznych, gdzie powinny być one dostępne tylko dla oczu webdeveloperów i tylko w środowiskach testowych, a nie produkcyjnych. Na przykład wywołanie strony:
www.nfsec.pl/index.php?strona=startowa
W zmodyfikowanej wersji:
www.nfsec.pl/index.php?strona[]=startowa
Może doprowadzić do wyświetlenia komunikatu błędu w przeglądarce każdego odwiedzającego użytkownika:
Warning: opendir(Array): failed to open dir: No such file or directory in /var/www/index.php on line 84
Jedną z metod generowania błędów w źle skonstruowanych skryptach jest nie przekazanie im żadnych parametrów. Skrypt zamiast zwrócić wcześniej zdefiniowany przez programistę komunikat o jego braku od razu generuje błąd. Niestety na pierwszym miejscu w tego rodzaju atakach zawsze dominuje brak walidacji wprowadzanych danych. Przykładem braku walidacji może być tutaj masowe użycie funkcji add_action(), w platformie WordPress (<= 2.9.2) bez jej sprawdzenia za pomocą funkcji function_exists():
www.blog.wordpress.org/wp-includes/kses.php
Zwróci błąd:
Fatal error: Call to undefined function add_action() in /var/strona/wp-includes/kses.php on line 1196
Inną popularną i bardzo skuteczną metodą generowania błędów FPD jest przekazanie zerowej sesji PHP za pomocą wstrzyknięcia kodu Javascript. Obsługę sesji PHP możemy wychwycić za pomocą dodatku do przeglądarki Firefox LiveHTTPHeaders lub po prostu używając dość oldschoolowego narzędzia telnet łącząc się z wybranym serwerem na porcie 80 i za pomocą nagłówka HTTP zażądać treści strony. W przypadku Firefoksa w nagłówku HTTP powinniśmy wychwycić:
Set-Cookie: PHPSESSID=nkunm0leo0mnb2pgmj9kkvcsk5; path=/
Od strony sesji nawiązanej za pomocą programu telnet wygląda to następująco:
nfsec~$ telnet virtualnyhost.pl 80 Trying 1.2.3.4... Connected to virtualnyhost.pl. Escape character is '^]'. GET / HTTP/1.1 Host: virtualnyhost.pl HTTP/1.1 200 OK Server: Apache Content-Type: text/html Keep-Alive: timeout=20 Set-Cookie: PHPSESSID=7ov981080nbelcpvccvii2gro2; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Content-Length: 1 Date: Sun, 23 May 2010 17:07:52 GMT Connection: keep-alive
Bardzo prostym sposobem jest również użycie kodu Javascript w pasku adresu przeglądarki do wyświetlenia zawartości ciasteczka:
javascript:alert(document.cookie);
Jeśli obsługa sesji PHP jest włączona możemy przejść do kroku wstrzyknięcia zerowej sesji:
javascript:void(document.cookie="PHPSESSID=");
lub
javascript:alert(document.cookie="PHPSESSID=");
Następnie wystarczy przeładować stronę, aby zobaczyć komunikat następującej treści:
Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /var/www/virtualnyhost.pl/www/index.php on line 2
Wszystkie powyższe czynności możemy wykonać również za pomocą pojedynczej sesji telnet:
nfsec~$ telnet virtualnyhost.pl Trying 1.2.3.4... Connected to nfsec.pl. Escape character is '^]'. GET / HTTP/1.1 Host: virtualnyhost.pl Cookie: PHPSESSID=SHOWMEYOURSISHOWYOUMY HTTP/1.1 200 OK Cache-Control: max-age=172800 Expires: Tue, 25 May 2010 17:30:26 GMT Vary: Accept-Encoding Content-Type: text/html Content-Length: 997 Server: Apache Date: Sun, 23 May 2010 17:30:26 GMT Connection: keep-alive Warning: session_start() [function.session-start]: The session id contains (...)
Obrona przed ujawnianiem pełnej ścieżki dostępu jest najprostszym procesem spośród wszystkich błędów w aplikacjach napisanych w języku PHP, gdyż sprowadza się do wyłączenia raportowania błędów i przekierowaniu ich do zdefiniowanego pliku z logami. Możemy wykonać to za pomocą głównego pliku konfiguracyjnego php.ini:
error_reporting = E_ALL & ~E_NOTICE display_errors = Off log_errors = On error_log = /var/log/php/php.log
Jeśli nie posiadamy dostępu do plików konfiguracyjnych PHP np. ze względu na używanie wirtualnego hostingu, a nasz usługodawca używa serwera Apache do obsługi stron, raportowanie błędów możemy wyłączyć za pomocą pliku .htaccess:
php_flag display_errors off
Lub z poziomu samej aplikacji PHP:
ini_set('display_errors', false);
Full path disclosure jest głównie używane podczas technik rozpoznawania celu ze wstępnym zamiarem jego ataku. Jako półśrodek może doprowadzić do udanego ataku za pomocą innej techniki, dlatego tego rodzaju luka w podstawowej konfiguracji interpretera PHP nie powinna zostać przeoczona.