Blind SQL Injection z wykorzystaniem regexpów

Przeglądając wczoraj różne informacje trafiłem na dokument Blind Sql Injection with Regular Expressions Attack. Temat jest ciekawy, jedno z głównych pytań, które mnie się nasunęło brzmi – ale po co. Po chwili przyszła jednak refleksja – może i ma to sens.

Temat sql injection poruszałem już wiele razy, między innymi w moim przewodniku po bezpieczeństwie aplikacji internetowych (na przykład tutaj: Lekcja 7: (blind) SQL injection). Cała koncepcja blind sql injection sprowadza się do tego, by zadawać pytania, które dają odpowiedź tak/nie i na podstawie tej odpowiedzi dowiedzieć się czegoś, o obiekcie, o który pytamy. A że tym obiektem są zwykle dane, zwykle dane tekstowe, chodzi o ich poznanie. Dokładnie tak, jak miało to miejsce w tym wyzwaniu.

Oczywiście zadanie to można zrealizować szybciej, lub wolniej. Przykładowo odgadnięcie wartości test może wyglądać tak:

Czy pierwsza litera to A –> NIE Czy pierwsza litera to B –> NIE Czy pierwsza litera to C –> NIE (...) Czy pierwsza litera to Z –> NIE Czy pierwsza litera to a –> NIE (...) Czy pierwsza litera to t –> TAK

Takie podejście jest skrajnie nieefektywne. Na podstawie prawdopodobieństwa występowania poszczególnych znaków w danym języku można oszacować ile zapytań trzeba wykonać w celu odgadnięcia określonej litery.

Oczywiście prawie nikt w ten sposób nie postępuje. Weźmy taki dopuszczalny i uszeregowny zakres znaków:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

Zamiast pytać po kolei, można szybciej (to tylko przykład):

Czy pierwsza litera jest większa niż A –> NIE Czy pierwsza litera jest większa niż o –> TAK Czy pierwsza litera jest większa niż o –> TAK Czy pierwsza litera jest większa niż u –> NIE (...) Czy pierwsza litera to t –> TAK

Po prostu zawężamy przedział, w którym może wystąpić nasze rozwiązanie przy każdym pytaniu zmniejszając go o połowę. Takie rozwiązanie jest zdecydowanie bardziej efektywne.

Pomysł opisany we wspomnianym dokumencie jest podobny, przy czym zamiast relacji większy/mniejszy wykorzystywane są wyrażenia regularne. Przykładowo:

Czy pierwsza litera zawiera się w [A-Z] –> NIE Czy pierwsza litera zawiera się w [a-o] –> NIE Czy pierwsza litera zawiera się w [p-u] –> TAK (...)

Pewną różnicę można znaleźć w przykładzie z wartością hasha w postaci heksadecymalnej. Tam dopuszczalne były znaki 0123456789abcdef. Korzystając z wyrażeń regularnych może odrobinę łatwiej jest operować na takim zakresie, choć jest to również możliwe przy pomocy “klasycznej” relacji większy/mniejszy rozbudowanej do kilku warunków.

Ogólnie rzecz biorąc wydaje mi się, że wydajność (ilość potrzebnych zapytań) podejścia wykorzystującego wyrażenia regularne i tego bazującego na relacji większy/mniejszy będzie zbliżona. Przecież to tak naprawdę to samo podejście, tylko realizowane przy pomocy dwóch różnych narzędzi.

Mogę sobie jednak wyobrazić sytuację, w której podejście oparte na wyrażeniach regularnych będzie wydajniejsze. Może ono bazować na:

Dzięki takiej dodatkowej wiedzy podejście wykorzystujące wyrażenia regularne może być bardziej efektywne. Oczywiście tu również można korzystać z relacji mniejszy/większy/równy, ale zapisanie takich warunków z wykorzystaniem wyrażeń regularnych będzie po prostu łatwiejsze i krótsze. To drugie nie jest bez znaczenia, czasami ilość znaków, które atakujący ma do dyspozycji jest ograniczona. Sam natknąłem się w trakcie testów na kilkanaście takich przypadków, w których sqlmap nie dał rady wyeksploitować podatności właśnie dlatego, że miał tendencję do budowania nieco zbyt rozbudowanych zapytań SQL.

Oryginał tego wpisu dostępny jest pod adresem Blind SQL Injection z wykorzystaniem regexpów

Autor: Paweł Goleń