Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
phar:// czyli zło w PHP, które czai się już 10 lat. Pierwsze exploity…
Temat problemów bezpieczeństwa formatu plików phar, został uznany tutaj za jeden z 10 najbardziej innowacyjnych hacków 2018 roku.
W czym problem? Sam dostęp do pliku złośliwego phar, np. w ten sposób: file_get_contents(’phar:///tmp/phartest.jpg/’); powoduje wykonanie złośliwego kodu po stronie odczytującej.
Dlaczego? W pliku phar, można umieścić zawartość zserializowaną, która przy odczycie jest automatycznie deserializowana. Takie zachowanie często prowadzi właśnie do wykonania kodu w OS.
Co więcej, plik phar może mieć dowolne rozszerzenie (nawet .jpg .txt) i co więcej można spokojnie tworzyć poligloty (pliki które są prawidłowymi .jpeg-ami i phar-ami). Obsługa formatu phar jest domyślnie włączona w PHP (pierwszy raz phar pojawia się w PHP 5.3.0 – 2009 rok!).
Idealnym kandydatem do wykorzystania problemu wydaje się być podatność XXE (gdzie kontrolujemy jakim protokołem odczytamy plik – może być to phar://). Akcja na diagramie poniżej:
Pierwsze skowronki tutaj czy tutaj.
–ms
I dlaczego jest to bardziej niebezpieczne od np.
include(unserialize(’/tmp/phartest.jpg/’));
?
Sorry ale problem z wykonaniem kodu podczas deserializacji to zupełnie inny problem.
z prostego powodu: żeby wykorzystać podatność via phar, w ogóle nie musisz robić żadnego unserialize()
samo odczytanie phar zwykłą funkcją php-ową powoduje automatyczną/cichą deserializację, o czym prawie nikt nie wiedział…
Archiwa PHAR mają charakter wykonywalnych aplikacji lub bibliotek wykonywalnego kodu. To nie jest ukryte w postaci drobnego druku na 30-tej stronie manuala: to jest w pierwszym zdaniu pierwszej strony. Powinny być traktowane dokładnie tak samo, jak skrypty shella czy binarki. To nie gołe `unserialize`, po którym faktycznie możnaby się nie spodziewać, że wykona jakiś kod. PHAR w swojej podstawowej funkcji jest związany z odpalaniem/dołączaniem programów.
Niewąpltiwie jest to nowo odkryty wektor ataków. Ale to są bugi w oprogramowaniu, które dopuszcza do użycia dowolnego URL-a w kontekście, gdzie nie powinno do tego dojść. Żadne czające się zło czy bug w PHP. Równorzędnym twierdzeniem byłoby, że zło czai się w przeglądarkach z obsługą JavaScriptu, bo istnieją aplikacje, które pozwalają zrobić XSS.
„Archiwa PHAR mają charakter wykonywalnych aplikacji lub bibliotek wykonywalnego kodu. To nie jest ukryte w postaci drobnego druku na 30-tej stronie manuala: to jest w pierwszym zdaniu pierwszej strony. ”
Podrzucisz to pierwsze zdanie pierwszej strony manuala? I nie chodzi o coś takiego: include 'phar:///path/to/myphar.phar/file.php’;
tylko o funkcje typu file_exists(’sciezka_do_pliku_phar’).
Jak znasz jakiś inny format, który daje automatyczne wykonanie kodu zaszytego w tym pliku przez odpalenie funkcji typu file_exists() – to daj znać :) Staniesz się sławny (patrz ostatni link w tym komentarzu).
Jeszcze inne obrazowe porównanie – to tak jak byś dostał plik exe w załączniku w zipie e-mailem. I oczywiście ten plik jest wykonywany, ale przez samo pokazanie Ci tego pliku
program pocztowy tego przecież nie wykonuje. W przypadku phar jest inaczej…
Nie bez powodu temat znalazł się na liście najbardziej innowacyjnych researchów z webappsec (2018 rok, 6. pozycja), mających potencjał na kolejne lata:
https://portswigger.net/blog/top-10-web-hacking-techniques-of-2018
> Podrzucisz to pierwsze zdanie pierwszej strony manuala?
Drugi link w tym artykule, pierwsze zdanie: „The phar extension provides a way to put entire PHP applications into a single file called a „phar” […]”.
I taki właśnie obraz tej technologii jest utrzymany w całej dokumentacji do PHAR-ów. Zatem nie wyobrażam sobie, by komuś programującemu w PHP i pracującemu z PHAR-ami mogło się wydawać, że może bezpiecznie dopuścić URL w układzie phar:// podawany z niezaufanego źródła.
Rzeczywiście można dyskutować, czy po pewnych wybranych operacjach — jak przytoczone `file_exists` — można się spodziewać wykonania kodu. Jednak do tych szczególnych przypadków dochodzimy od strony „uruchamiamy program” (w granicy: istnieją operacje, które mogą niczego nie uruchamiać), a nie — jak np. w przypadku wyświetlenia obrazka — „nie wykonujemy niczego” (w granicy: istnieją operacje, które mogą coś wykonać). Widać różnicę, o której mówię?
Gdybym dostał binarkę w mailu, to nie spodziewam się jej uruchomienia przez to, że odczytuję maila. I tutaj umieszczenie samego PHAR na serwerze również nie pociąga za sobą negatywnych skutków. Szkodę wyrządza dopiero operacja, którą lepiej zobrazowałoby wywołanie `ldd` na tej binarce z maila.
Bez obietnicy sławy mogę podpowiedzieć, że w PHP można definiować własne stream wrappery, więc sama idea wykonania kodu z `file_exists` to nie byłoby z mojej strony żadne osiągnięcie. Lekko przerysowując sytuację w celu zobrazowania sytuacji: jeśli potrzeba przykładu innych URLi, które mogą *gdzieś* (nie w PHP) wykonać kod: „javascript:alert(’foo’)”. Jeśli chodzi o rzeczy wbudowane w PHP: „http://127.0.0.1:/executeSomethingBlehBleh”. O co mi chodzi? O zauważenie, że bug leży w aplikacjach, które dopuściły użycie dowolnego adresu przez niezaufane źródło, a nie w samym schemacie phar://.
Innowacyjności klasy exloitów nie odrzucam. Faktycznie są ładne.
No więc właśnie: „The phar extension provides a way to put entire PHP applications into a single file called a „phar” […]”.
Patrz wyżej, to tak jak masz plik exe – oczywiście jest on wykonywalny. Ale magicznie się nie wykona dopóki go nie klikniesz. W phar jest inaczej (można powiedzieć, że samo zobaczenie że exe istnieje na listingu plików już go wykonuje (!)) i o tym jest tekst.
Przeczytaj proszę jeszcze raz tekst – tu nie chodzi o to że do phara możesz wpakować pliki PHP – bo to jest normalne i powiedzmy bezpieczne.
Hint: http://php.net/manual/en/phar.fileformat.manifestfile.php (pierwsza tabela, ostatni wiersz)
„Bez obietnicy sławy mogę podpowiedzieć, że w PHP można definiować własne stream wrappery”.
W PHP to można definiować wszystko, to jasne. Ale chodzi o to co jest w *domyślnej* konfiguracji, bez żadnego dodatkowego „definiowania” i znowu wracamy do istoty tekstu u nas.
PS
Generalnie naprawdę nie mamy ambicji żeby Cię przekonywać, że coś z punktu widzenia security jest istotne :-) Kto chce skorzystać – skorzysta, oby tylko nie w niecnych celach.