Lip
19

Zabugowane błędy

autor: p____h  //  ::easy::, Security

Dzisiaj trochę o PHP – z naciskiem na argumenty dlaczego error_reporting() jest dobry i powinno się z niego korzystać. Niestety, bardzo rzadko spotykam się z kodami, w których figuruje banalna linijka: error_reporting(0);
A szkoda – błędy wypluwane przez interpreter powinien widzieć tylko administrator (serwer produkcyjny?), a komunikację z użytkownikiem powinno zapewniać napisane GUI.

Zerknijmy na dość interesujący przykład, na którym pokażę, że wyświetlanie błędów może przynieść jeszcze więcej szkód niż pożytku. Wybór dość przestarzały: Smarty 2 (a dokładnie najnowsza z „dwójki” wersja o numerku 2.6.26).  Zerknijmy na dostarczone demo.  Nie musicie znać Smartów – w sumie też ich nie znam  zbyt dobrze. Interesuje nas plik templates/index.tpl. Jak łatwo zgadnąć – przechowuje on dane jakiegoś szablonu głównego (w końcu nazywa się index).
Pobawimy się tylko tym:

{include file=$smarty.get.page|cat:.php” title=foo}

Zamieńmy ją na taki oto twór:

{include file=$smarty.get.page|cat:".php" title=foo}

który robi nic innego jak PHP-owy

include($_GET['page'].".tpl");

Tak, spokojnie, zdaję sobie sprawę, że tak pisać nie wolno. Załóżmy jednak, że spotkaliśmy się właśnie z takim kodem (zwłaszcza, że Smarty zrobią parę rzeczy za nas). Odpalmy więc nasz index.php z parametrem ?page=header. Okazuje się, że wszystko działa (plik header.tpl został poprawnie dołączony). Widząc jednak takie pole aż prosi się o wypróbowanie Poison Null Byte, czy też Path Traversal. Zachęcam do zabawy i poszukiwań – jak już pewnie zauważyliście standardowe %00 / \ ‚ „ są filtrowanie. Ba… nie można nawet zabawić się z ../.

No ale, nie o tym. Zrobimy coś, co w include() z PHP jest nie do zrobienia. Zróbmy sobie XSS’a!
?page=<script>alert(0);</script>

Niespodzianka!  Warning: Smarty error: unable to read resource: [nasz nieparsowany input].
Rzadko zdarzają się tego typu niespodzianki. Zwłaszcza, że mało osób próbuje poddać obróbce dane, które za chwile może wypluć interpreter – zaciemniłoby to obraz komunikatu. Sprawdziłem kilka brzegowych wersji (m.in. 2.6.0 i 2.6.26) – wnioskuję więc, że podobny błąd występuje w całej serii 2.6.x. W tym przypadku najlepszym rozwiązaniem byłoby defense in depth, czyli rozbicie problemu na kilka warstw. Pierwszą warstwą byłoby parsowanie wszystkiego, co może kiedykolwiek trafić do użytkownika. Druga warstwa to linijka error_reporting(0);, która w dodatku ukryłaby przez userami wiele komunikatów, których nie powinni widzieć.

  

Dodaj komentarz

*

Audio-CAPTCHA