Второй апдейт по стажировке Positive Technologies

Второй учебный блок и, соответственно, домашнее задание, были посвящены внедрению операторов SQL. Кратко разберу каждую из 7 инъекций домашнего задания.

  • Первая инъекция — hello world среди SQLi. Входные данные никак не фильтруются, итоговый запрос к базе в коде выглядит следующим образом:

SELECT * FROM users WHERE id=’$id’ LIMIT 0,1

Одинарная кавычка, конечно же, ломает запрос, вывод ошибки включён и страница не стесняясь сообщает, что с ней не так. При этом вывода никакого нет, так что при помощи UNION базу не изучить, эффективнее всего, как по мне, использовать подход error-based. Использовал более старый вектор, в конечном итоге:

?id=-1’+or+(select+count(*)+from+(select+1+union+select+2+union+select+3)x+group+by+mid(database(),floor(rand(0)*2),64))+—+1

  • Вторая инъекция — отличный образец того, какое маленькое различие в ответах иногда необходимо заметить, чтобы верифицировать вектор. И в случае штатного и в случае ошибочного вывода, пользователь видит одну и ту же надпись, однако в исходном коде, в ветке обработки ошибки MySQL, присутствует дополнительная строка:

echo ‘<font color= «#0000ff» font size= 3>’;

Это можно заметить, открыв исходный код страницы в браузере или сравнив ответы в Burp Comparer. Имея возможность отличать нормальный ответ от ошибочного, инъекцию можно разматывать как boolean blind, но я решил, что сойдёт и time-based, потому конечный вектор проверяет количество символов в названии базы данных:

?id=1″+and+if(length(database())+<+10,sleep(2),sleep(0))+—+1

  • Третье задание представляет собой форму для ввода логина и пароля. Инъекция позволяет обойти авторизацию, но поскольку задачей было получить какие-либо деликатные данные, то можно представить, что аккаунт в сервисе у нас уже имеется, а значит вместе с валидными логином и паролем можно попытаться провести инъекцию c целью получения этих самых деликатных данных. Какая-либо фильтрация входных данных отсутствует, ровно как и пригодный для модифицирования вывод. Как и в случае с заданием 2, успешный и ошибочный ответы отличаются только одной строкой в html:

echo ‘<font color= «#FFFF00» font size = 4>’;

Можно отличать ответы и действовать в соответствии с подходом boolean blind, но я снова выбрал time-based, конечный вектор в тело POST-запроса авторизации (логин и пароль валидны, как я уже отметил):

uname=secure&passwd=crappy»)+and+if(length(database())+<+10,sleep(2),sleep(0))+—+1&submit=Submit

  • Четвёртую инъекцию осложняла фильтрация. Фильтровались все разновидности комментариев, пробелы, а также ключевые слова SQL: union и select в трёх формах каждое (например union, Union и UNION). Имеется модифицируемый вывод, так что лучшим является подход union-based, вот только надо обойти фильтрацию.

Фильтрация пробела обошлась про помощи символа %09. Фильтрацию ключевых слов можно было обойти как при помощи camel-case (например SeLeCt, ведь такое написание не фильтруется кодом), так и эксплуатируя недостаток фильтра — он применяется всего один раз, так что если на вход подать uniunionon, то средняя часть будет вырезана и половины uni и on всё же образуют нужное ключевое слово. В вектор включил оба варианта байпасса. Наконец, фильтрация символов комментирования, необходимых для нормализации запроса, обходится при помощи точки с запятой и нулевого символа. Конечный вектор:

?id=0″%09uniunionon%09seLect%091,database(),user();%00

  • Пятая инъекция представляет собой форму авторизации, аналогичную третьему заданию, только теперь логин и пароль обрабатываются целой чередой фильтров. Попробовав залогиниться с известными учётными данными, можно заметить, что пользователю демонстрируется адрес страницы, с которой он перешёл. За это явно отвечает заголовок Referer POST-запроса. Подставив кавычку и сломав запрос, можно увидеть, что ошибка ругается на », ‘192.168.2.40’), что свидетельствует о том, что инъекция происходит не в SELECT, а в INSERT и помимо referer’a записывается ещё и IP. Осознав это, можно прогуглить подходящий вектор за 30 секунд. В конечном итоге я воспользовался подходом error-based, логинясь с валидными учётными данными и модифицируя Referer следующим образом:

‘ or updatexml(1,concat(0x0a,(database())),0) or ‘

  • Шестая инъекция была настроена неправильно, из-за чего проходилась тривиально. Изначально предполагалось, что там нужно будет задействовать уязвимость, основанную на мультибайтовых кодировках, но тот, кто редактировал запрос, просто забыл облачить переданный пользователем параметр в кавычки, обход применения которых и был главной сложностью задания, так что конечный вектор уже знакомый:

?id=1+and+updatexml(1,concat(0x0a,(database())),0)+—+1

  • Седьмая инъекция была в ORDER BY, что было очевидно из контекста. Помимо этого, ничего примечательного, вектор всё тот же, только параметр называется иначе:

?sort=’+or+updatexml(1,concat(0x0a,(database())),0)+—+1

Третья лекция об атаках на клиентов, уже прошла, следующий апдейт будет посвящён домашней работе на эту тему.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *