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.
Blind SQL Injection z wykorzystaniem regexpów
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:
- prawdopodobieństwie wystąpienia określonego znaku w danym języku,
- prawdopodobieństwie wystąpienia określonego znaku w danym języku, pod warunkiem, że wcześniej wystąpił określony znak (który już znamy),
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.
Tak, jest to nawiązanie do wcześniejszego wpisu: Blind SQL Injection z wykorzystaniem regexpów. Postanowiłem sprawdzić, czy rzeczywiście uda się zmniejszyć ilość pytań, które trzeba zadać, by odgadnąć słowo. Rezultat: 66976481 63650628. Lepiej?Najpierw kr
Przesłany: Jun 19, 20:25