Для будущих студентов курса "Безопасность веб-приложений" публикуем авторскую статью эксперта OTUS, вирусного аналитика в международной компании - Александра Колесникова
Статья расскажет, как использовать SQLmap и похожих инструментов для автоматизации решений заданий по sql injection на одном из популярных CTF ресурсов. В статье зайдем немного дальше, чем просто модификация risk-level «if you know what i mean». Задания не будут полностью разобраны для решения, флаги необходимо найти самостоятельно.
Также будет продемонстрировано, как можно самостоятельно изменять инструменты для покрытия большего количества уязвимостей в веб.
О проекте SQLMap
Существует множество статей, которые описывают стандартный функционал SQLMap, например здесь и здесь. Проект можно найти здесь. Инструкции по установке находятся там же, в разделе Wiki. По мнению автора, это единственное полное руководство, которое можно использовать для работы с инструментом. По сути, нас интересуют части, которые отвечают за атаки с помощью инструмента. Первая остановка - директория с полезной нагрузкой. Файлы, которые находятся в этой директории, используется для хранения информации, используемой для проведения атаки:
Файлы названы в соответствии с техникой для проведения атаки: «boolean blind», «error based», «inline query», «stacked query», «time blind», «union query». Все эти техники могут быть использованы за счет risk, level и — technique флагов. Вот такой неочевидный интерфейс. Инструмент хоть и с открытым исходным кодом, но все равно нужно изучать документацию. Второй точкой соприкосновения должна стать вот эта директория проекта. С ней мы будем работать за счет параметра —tamper.
Стратегия решения заданий
Существует достаточно много площадок, где можно потренироваться в поиске уязвимостей: от игровых CTF площадок до серьезных систем, которые открыли опцию Bug bounty в программах на ресурсах типа HackerOne. Мы будем использовать часть заданий этого ресурса. Раздел называется SQL Injection.
Данные задания, в отличии от других ресурсов, позволяют изучить особенности нескольких типов баз данных: MySQL, SQLite, Oracle, PostgreSQL. В каждом задании присутствует своя боль особенность, благодаря которой можно будет научиться чему-то новому.
Начнем с простого task-а - это форма, которую нужно обойти:
![](https://habrastorage.org/getpro/habr/upload_files/510/f5a/6cb/510f5a6cb31a97cd750c1cdeaf685809.png)
Параметры, очевидно, будут передаваться в POST запросе, поэтому приготовим данные для запуска sqlmap:
Необходимо перехватить запрос, который мы будем отправлять на сервер, чтобы мы могли определить названия параметров и название скрипта, который обрабатывает запрос на backend.
Сохранить данные, которые нужны для доступа к заданию: Cookie.
Составить шаблон команды для sqlmap.
Выполним все пункты:
Заголовок, который можно будет использовать для проведения запросов, можно обнаружить прямо в браузере.
Для этого открываем "Инструменты разработчика", переходим в раздел "Сеть" и находим запрос, который отправляли с тестовыми данными:
На картинке вы видите часть заголовков - их всех нужно скопировать и сохранить в файл; так же следует поступить с параметрами.
Должно получиться так, как показано на рисунке ниже:
Командная строка для запуска инструмента:
sqlmap -r ./requestFromBrowser -p user—risk=1 —level=1 —batch —random-agent -b
Команда должна просто показать баннер базы данных. Если эта информация получена, то задание решено. Все, что нужно сделать, это использовать дополнительные флаги для дампа данных.
Смотрим, что получается при выполнении команды:
Результат достигнут, но он далек от идеала. Подобную уязвимость можно эксплуатировать одним запросом, просто используя браузер. Инструмент же отправил тысячи запросов. Давайте попробуем оптимизировать его поведение и добавим флаг, который заставит выбирать только один тип атаки - «Error Based», и уберем опасный параметр - batch (автопрокликивание).
В результате даже лог инструмента намного короче:
Для полного решения задания читатель может воспользоваться запросом, который предоставил sqlmap.
Следующее задание будет с небольшой особенностью. Оно очень похоже на предыдущее - необходимо забайпасить форму:
Испробуем ту же командную строку, но предварительно сохраним запрос в файл, как это делали на первом задании.
Практически идеально, но инструмент затрудняется найти какую-то конкретную базу данных. Он предполагает, что это PostgreSQL. Проверим на ресурсе. Отправим запрос с ‘ в полях username и password.
Похоже, что в этом случае sqlmap едва ли сможет справиться с этим запросом. В этом случае исправить поведение инструмента не получится, но он нам дал верную догадку - действительно для обслуживания этой формы используется PostgreSQL, об этом можно судить по синтаксису, который мы видим на рисунке выше. Но можем ли мы все таки пройти это задание? Попробуем добавить новый payload в список уже существующих для postgreSQL.
Откроем вот этот файл и добавим следующее значение:
<test>
<title> PostgreSQL CTF Test</title>
<stype>2</stype>
<level>1</level>
<risk>3</risk>
<clause>1,8,9</clause>
<where>1</where>
<vector>')) OR TRUE --</vector>
<request>
<payload>'))OR TRUE --</payload>
</request>
<response>
<grep> DELIMETERSTART[DELIMETERSTOP[</grep>
</response>
<details>
<dbms>PostgreSQL</dbms>
</details>
</test>
Все параметры называются именно так, как используются в sqlmap, поэтому не стоит их комментировать. Стоит лишь указать, что цель всех заданий получить строку формата «FLAG-[any value]» поэтому мы можем его ожидать на странице, которая будет возвращена сервером. Атрибут нужно добавить до PostgreSQL проверок. И, соответственно, модифицируем параметры запуска:
sqlmap -r ./request2 -p username
--risk=1 --level=3 --random-agent -b —technique=E
В результате получим следующий результат:
Да, мы не получили официального ответа от инструмента, что это действительно postgreSQL, но мы теперь знаем, что значение «FLAG-» появилось на странице, а это значит, что наша полезная нагрузка отработала и задание пройдено.
Следующее задание будет еще сложнее, чем предыдущее, но будет использовать тот же принцип работы. В задании все так же форма логина. Нужно только сохранить данные о запросе:
И запускаем, но чтобы сэкономить время на изучение происходящего на сервере - добавим параметр логирования запросов и ответов -t ./log. Не буду просто вставлять картинки - результат не утешительный, инструмент не может найти подхода к этой форме. Лучше посмотрим, что он получал в ответ:
Фильтр «danger|username» взят после просмотра лога. Именно эти ключевые слова показывают payload от sqlmap и ответ от сервера. Несложно видеть, что большинство запросов были заблокированы импровизированным WAF. Чтобы понять, что именно блокируется WAF, раскодируем строку, которая выделена на рисунке, и проверим все символы.
Судя по всему, у нас есть ограничение в виде запрещенного символа «=». Что с этим делать? В этом случае не придется мешать работе дописывать что-то в исходный код. В установке sqlmap есть наборы скриптов, которые могут помочь закодировать данные, которые отправляются на сервер. Воспользуемся ими, а именно - equaltolike файлом. Так же изменим параметр, который мы уже получили из лога, а именно «Wrong username» В итоге мы получаем следующую командную строку:
sqlmap -r ./request3 -p username --risk=1 --level=3 --random-agent -b -t ./log --tamper=equaltolike --string="Wrong username»
.
И в результате:
Проведем проверку еще одного интересного задания:
Задание отличается от предыдущих тем, что для запроса теперь используется метод GET. Для нас это означает, что можно не использовать теперь файл для хранения запроса. Достаточно просто скопировать URL и Cookie:
sqlmap -u "https://ringzer0ctf.com/challenges/37?q=" --risk=3 --level=5 —cookie=«PHPSESSID=[ВАШ ИДЕНТИФИКАТОР]" --random-agent -b -t ./log
.
Всё практически идеально, за исключением одного - URL очень плохо обрабатывает пробелы в запросах. Для этого мы используем — tamper=space2morecomment
Снова неудачно, если проанализировать запросы станет ясно, что пробел слишком громоздкий для запроса. Изменим его:
В директории tamper
находим необходимый скрипт и изменяем значение пробела с «/_/»
на «/*/
»:
Перезапустив sqlmap, получаем следующий результат:
Итог — у нас есть решение еще одного задания платформы.
Таким образом, можно и нужно изменять готовые инструменты для тестирования уязвимостей. Так как все виды векторов атак предугадать невозможно. Лучшие друзья в этом деле — документация и знание структуры инструмента. Спасибо за внимание!