Это страница с дополнительным материалом, который предназначен для помощи студентам, изучающим курс SQL Injection Master.
Материалы на этой странице подробно объясняют, как работает Blind Based инъекция.
Функция WHERE()
Перед началом работы с BLIND инъекциями давайте сначала разберём как работает функция WHERE.
MySQL функция WHERE используется для фильтрации результатов в функциях SELECT, INSERT, UPDATE или DELETE.
Возьмём нашу тестовую базу sql_test и таблицу auto
MariaDB [(none)]>SELECT*FROMsql_test.auto;+----+--------+-------------------+--------+--------------+-------+------+| id | brand | model | color | engine_power | drive | year |+----+--------+-------------------+--------+--------------+-------+------+| 1 | Mazda | 626 | Black | 90 | front | 1996 || 2 | Opel | Astra | Gray | 101 | front | 1999 || 3 | Ford | Transit | Green | 140 | rear | 2007 || 4 | Audi | 100 | Red | 133 | front | 1991 || 5 | Jeep | Grand Cherokee IV | Silver | 243 | full | 2011 || 6 | Nissan | Murano II | Orange | 249 | full | 2010 || 7 | Isuzu | Rodeo | Olive | 130 | rear | 2000 || 8 | Suzuki | Baleno | Blue | 96 | front | 2000 || 9 | Lexus | GX II | Yellow | 296 | full | 2021 || 10 | Honda | Civic VIII | White | 140 | front | 2008 |+----+--------+-------------------+--------+--------------+-------+------+10rowsinset (0.000 sec)# Базовая таблица от которой мы будем отталкиваться
Отправим в неё запрос на вывод всех колонок, где цвет соответствует значению 'black'
Получив такой запрос MySQL начнёт проверять записи таблицы и выводить строки которые соответствует заданному условию.
То есть, если цвет в строке равен цвету из запроса проверка вернёт значение ИСТИНА (TRUE)(запоминаем этот момент) и вернёт эту строку.
Теперь добавляем к нашему запросу ещё одно условие с помощью оператора AND:
Однако, если мы укажем другое значение id, то вывод будет другой:
То есть вывод какой-либо строки из БД будет только тогда, когда у нас оба условия возвращают ИСТИНУ (1).
Логические операторы
Дальше нам стоит вспомнить школьную информатику, а конкретно как работает логическое AND (И)
Для простоты я буду заменять слова ИСТИНА на 1 и ЛОЖЬ на 0.
Логическая схема довольно простая для понимания:
1 AND 1 равно 1
1 AND 0 равно 0
0 AND 1 равно 0
0 AND 0 равно 0
Как мы видим из схемы, только при условии двух ИСТИН в результате мы получим ИСТИНУ.
Поскольку у нас два условия, то на экран будут выводиться только те строки, которые удовлетворяют одновременно двум условиям (проверка обоих условий возвращает нам ИСТИНУ).
Это довольно простая логика, только в одном случае, когда оба условия возвращают нам 1 в итоге мы имеем 1 и вывод данных на экран.
Ищем символ обрамления в слепых инъекциях
Теперь потихоньку возвращаемся к инъекциям, и первый вопрос который возникает - а как найти символы обрамления в слепой инъекции?
Поскольку страницы с ошибкой MySQL нет, не можем ориентироваться на её вывод, однако мы помним список всех возможных обрамлений и этого будет достаточно! (Если забыли, то вспоминаем SQLIM-Base)
Но сперва нам необходимо найти "точку опоры".
Под "точкой опоры" подразумевается то значение, при котором из базы на сайт будет выводиться какая-то информация (иногда нам не нужно её искать самостоятельно, а достаточно проверить соседние ссылки, часто в них уже бывают рабочие значения).
После нахождения "точки опоры" мы начинаем поочерёдно проверять все возможные символы обрамления по следующей схеме:
Подставляем символ обрамления после "точки опоры" и смотрим реакцию сайта.
Если вывод сайта изменился, то подставляем символы комментария и смотрим реакцию сайта.
Если вывод сайта вернулся в норму, то вы нашли верный символ обрамления!
Если вывод не вернулся в норму, то вы нашли неверный символ обрамления, пробуйте другие
Если вывод сайта не изменился, то подставляем другой символ обрамления и смотрим реакцию сайта.
Этот метод не гарантирует 100% нахождения символов обрамления (поскольку нам может мешать WAF), но должен вам помочь понять - как его можно попробовать найти в слепую.
Возвращаемся к инъекциям
Теория
Из-за того, что для получения итоговой ИСТИНЫ нам необходимо, чтобы оба проверочных значения нам возвращали ИСТИНУ, а для этого нам нужно использовать "точку опоры".
Самое главное, что неважно сколько информации будет выводиться, при использовании "точки опоры" - одно слово на странице или полноценный блок новостей с картинками, главное, что эти данные выводятся из БД!
Рассмотрим работу инъекции на примере:
Если в БД есть запись со значением id равным 1, то мы увидим вывод информации из БД на сайт (под информацией понимаются любые данные, которые выводятся при обычной работе сайта).
Если на сайт ничего не вывелось, то продолжаем искать "точку опоры"!
После нахождения точки опоры мы начинаем искать символ обрамления (процесс поиска расписан выше, дублировать его не буду)
Поскольку "точка опоры" в первой части нам всегда будет возвращать ИСТИНУ, то с помощью манипулирования вторым условием, через инъекцию, мы можем со 100% вероятностью угадывать буквы, символы или слова.
В данном примере мы увидим отображение данных из БД на сайт, поскольку точка опоры id=1 возвращает ИСТИНУ и условие 1=1 тоже возвращает ИСТИНУ, в итоге будет ИСТИНА.
А в этом примере мы не увидим отображение данных из БД на сайт, поскольку точка опоры id=1 возвращает ИСТИНУ, а условие 2=1 возвращает ЛОЖЬ и в итоге будет ЛОЖЬ.
Отлично, теорию поняли, но данные-то как доставать?
Практика
Теперь мы можем усложнять нашу инъекцию для получения данных из БД.
В данном примере мы сравниваем первую букву пользователя с буквой 'r'. Поскольку точка опоры id=1 возвращает ИСТИНУ, а у нашего пользователя 'root@localhost' первая буква в его имени действительно 'r' то второе условие тоже возвращает ИСТИНУ, а значит итоговое значение будет ИСТИНА и данные из БД будут отображены на сайте.
В данном примере мы сравниваем вторую букву пользователя с буквой 'a'. Поскольку точка опоры id=1 возвращает ИСТИНУ, а у нашего пользователя 'root@localhost' вторая буква в его имени 'o' то второе условие возвращает ЛОЖЬ, а значит итоговое значение будет ЛОЖЬ и данные из БД не будут отображены на сайте.
Таким образом, сравнивая посимвольно все буквы мы можем получить полное имя пользователя.
И мы ничем не ограниченны, можем получать имена БД, таблиц, колонок и значений из колонок!
Время на это потратится довольно много, но существуют специальные скрипты, которые смогут это сделать в автоматизированном режиме. О ни мы узнаем в следующих модулях курса.
Так же не стоит забывать, что методов подбора символов в BLIND инъекциях очень много, один вариант показан выше, ещё два альтернативных варианта разобраны в нашей методичке, но принцип у них одинаковый!
Burp Suite Tips
Отслеживаем изменения в ответе сервера
При работе в модуле Repeter стоит обратить внимание на правый нижний угол окна.
Там отображается размер и время ответа сервера. Это очень пригодится при работе с Blind Based и Time Based инъекциями!
Вы всегда можете оперативно проверить как отреагировал сервер на изменение в запросе.
Работа с кириллицей в запросе
При отправке кириллицы в качестве значения переменной Burp Suite часто отправляет данные криво и веб серверы не могут их нормально обработать.
Чтобы это исправить нам нужно поменять один параметр в настройках:
Burp -> Settings -> User interface -> Inspector and message editor -> Character sets -> Use a specific character set: UTF-8
Burp Suite Settings
После этого, что в Intruder, что в Repiter можно спокойно писать кириллицей и запросы будут нормально отправляться!
Заключение
Всем спасибо за внимание, надеюсь этот материал помог вам структурировать полученные знания из методички!
Кстати, если кто-то хочет потренироваться на своём стенде, то я разместил архив с php страницей и экспортом тестовой БД. [Скачать]
Если кто-то не доверяет файлам из интернета, то всегда можно проверить код php файла, он предельно простой и в нём нет никаких скрытых закладок!
MariaDB [(none)]> SELECT * FROM sql_test.auto WHERE color='black';
+----+-------+-------+-------+--------------+-------+------+
| id | brand | model | color | engine_power | drive | year |
+----+-------+-------+-------+--------------+-------+------+
| 1 | Mazda | 626 | Black | 90 | front | 1996 |
+----+-------+-------+-------+--------------+-------+------+
1 row in set (0.003 sec)
# Согласно условию, нам вывелась только одна запись, у которой цвет соответствует значению 'black'.
MariaDB [(none)]> SELECT * FROM sql_test.auto WHERE color='black' AND id=1;
+----+-------+-------+-------+--------------+-------+------+
| id | brand | model | color | engine_power | drive | year |
+----+-------+-------+-------+--------------+-------+------+
| 1 | Mazda | 626 | Black | 90 | front | 1996 |
+----+-------+-------+-------+--------------+-------+------+
1 row in set (0.001 sec)
# Нам вывелась только одна запись, у которой цвет соответствует значению 'black' и id записи соответствует 1.
MariaDB [(none)]> SELECT * FROM sql_test.auto WHERE color='black' AND id=10;
Empty set (0.001 sec)
# Нам ничего не вывелось, поскольку в таблице нет записи, у которой цвет соответствует значению 'black' и id записи соответствует 10.
MariaDB [(none)]> SELECT * FROM sql_test.auto WHERE color='black' AND 1;
+----+-------+-------+-------+--------------+-------+------+
| id | brand | model | color | engine_power | drive | year |
+----+-------+-------+-------+--------------+-------+------+
| 1 | Mazda | 626 | Black | 90 | front | 1996 |
+----+-------+-------+-------+--------------+-------+------+
1 row in set (0.001 sec)
# Первая часть (color='black') возвращает нам 1, вторая часть возвращает нам 1, значит согласно таблице логического 'И' итог у нас 1 и на экран выводится запись.
MariaDB [(none)]> SELECT * FROM sql_test.auto WHERE color='black' AND 0;
Empty set (0.001 sec)
# Первая часть (color='black') возвращает нам 1, вторая часть возвращает нам 0, значит согласно таблице логического 'И' итог у нас 0 и на экран ничего не выводится.
[GET_Request]
http://localhost/news.php?id=1
[SQL_Query]
SELECT * FROM sql_test.news WHERE id='1';
[GET_Request]
http://localhost/news.php?id=1' AND 1=1 -- -
[GET_Request]
http://localhost/news.php?id=1' AND 2=1 -- -
[GET_Request]
http://localhost/news.php?id=1' AND (MID((SELECT user()),1,1))='r' -- -
[GET_Request]
http://localhost/news.php?id=1' AND (MID((SELECT user()),2,1))='a' -- -