-15% na nową książkę sekuraka: Wprowadzenie do bezpieczeństwa IT. Przy zamówieniu podaj kod: 10000

XPATH a SQL injection

28 czerwca 2013, 21:30 | Teksty | 1 komentarz

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):

xpath_przyklad

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.

Dla pierwszych trzech osób, które prześlą obie informacje powyżej – na adres: sekurak@sekurak.pl – mamy mała niespodziankę – miesięczną licencję na komercyjną wersję oprogramowania burp suite pro!

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

 

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



Komentarze

  1. J@#634B

    Gdzie można znaleźć rozwiązanie zadania?

    Odpowiedz

Odpowiedz