May 5

UNION-Атаки

Приветствую! На связи админ канала Falcon Bytes! Мы продолжаем разбираться с базовыми понятиями в SQL-инъекциях, и сегодня я затрону тему UNION-Атак.

Если приложение уязвимо для SQL-инъекции и результаты запроса возвращаются в ответах приложения, вы можете использовать метод UNION для получения данных из других таблиц в базе данных. Это широко известно как UNION атака.

Теория

Оператор UNION позволяет вам выполнить одно или несколько дополнительных запросов в базу данных к исходному запросу, грубо говоря: склеить два SQL запроса в один. Например:

SELECT a, b FROM table1 UNION SELECT c, d FROM table2

Этот запрос возвращает один набор результатов с двумя столбцами, содержащими значения из столбцов a, b в таблице table1 и столбцы c, d в таблице table2 .

Для того, чтобы UNION запрос работал, должны быть выполнены два ключевых требования:

  • Отдельные запросы должны возвращать одинаковое количество столбцов.
  • Типы данных в каждом столбце должны быть совместимы между отдельными запросами.

Чтобы выполнить UNION атаку с помощью SQL-инъекции, убедитесь, что ваша атака соответствует этим двум требованиям. Обычно это предполагает выяснение:

  • Сколько столбцов возвращается из исходного запроса.
  • Какие столбцы, возвращенные из исходного запроса, имеют подходящий тип данных для хранения результатов внедренного запроса.

Определение количества необходимых столбцов

Когда вы выполняете UNION атаку с помощью SQL-инъекции, нужно определить, сколько вообще столбцов в базе данных приложения. Для этого есть эффективный способ внедрения запроса ORDER BY в инъекцию. Этот оператор нужен для сортировки значений в базе данных по возврастанию или убыванию.

Например:

SELECT * FROM Products ORDER BY ProductID;

Этот запрос сортирует знаения в базе данных по возрастанию основываясь на ProductID


Если добавить в конце запроса параметр DESC, то сортировка будет происходить уже по убыванию.

Пример:

Однако помимо конкретного названия столбца, по которому идет сортировка можно еще указать его порядковый номер (начиная с 1, 2, 3, ...)

Таким образом делая запрос:

SELECT * FROM Products ORDER BY 1 DESC;

У нас будет такой же результат, как у запроса:

SELECT * FROM Products ORDER BY ProductID DESC;

Зачем нам нужно делать сортировку по индексам?

А для того, чтобы понять, сколько конкретно столбцов есть в целевой базе данных. Если ввести порядковый номер столбца, которого не существует (например в базе есть всего три столбца, а мы указали в запросе номер 4), то из-за ошибки в запросе приложение может вернуть нам ошибку.

Например:

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

Приложение может фактически вернуть ошибку базы данных в своем HTTP-ответе, но оно также может выдать общий ответ об ошибке. В других случаях он может просто не вернуть никаких результатов. В любом случае, если вы обнаружите некоторую разницу в ответе, вы сможете сделать вывод, сколько столбцов возвращается по запросу.

Второй метод предполагает отправку серии UNION SELECTполезные данные, указывающие разное количество нулевых значений:

' UNION SELECT NULL-- ' UNION SELECT NULL,NULL-- ' UNION SELECT NULL,NULL,NULL-- etc.

Если количество нулей не соответствует количеству столбцов, база данных возвращает ошибку, например:

All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

Мы используем NULLкак значения, возвращаемые из введенного SELECTзапрос, поскольку типы данных в каждом столбце должны быть совместимы между исходным и внедренным запросами. NULLконвертируется в любой общий тип данных, поэтому максимизирует вероятность того, что полезная нагрузка будет успешной, если количество столбцов правильное.

Как и в случае ORDER BYПри использовании этого метода приложение может фактически вернуть ошибку базы данных в своем ответе HTTP, но может вернуть общую ошибку или просто не вернуть никаких результатов. Когда количество значений NULL соответствует количеству столбцов, база данных возвращает дополнительную строку в наборе результатов, содержащую значения NULL в каждом столбце. Влияние на ответ HTTP зависит от кода приложения. Если вам повезет, вы увидите в ответе дополнительный контент, например дополнительную строку в таблице HTML. В противном случае нулевые значения могут вызвать другую ошибку, например NullPointerException. В худшем случае ответ может выглядеть так же, как ответ, вызванный неправильным количеством нулей. Это сделает этот метод неэффективным.

Используя такой метод мы можем понять только сколько столбцов выбирается в запросе, но это не будет гарантом того, что именно столько столбцов в самой таблице, вместо этого советую использовать ORDER BY, однако оба этих метода стоит знать, для более точного анализа.

Практика

Перейдем по ссылке и запустим лабораторию для проверки работы SQL-инъекции.

Нажимаем "ACCESS THE LAB"

Это тестовое приложение содержит уязвимость внедрения SQL в фильтре категорий продуктов. Результаты запроса возвращаются в ответе приложения, поэтому вы можете использовать атаку UNION для получения данных из других таблиц. Первым шагом такой атаки является определение количества столбцов, возвращаемых запросом. Затем вы будете использовать эту технику в последующих лабораторных работах для построения полной атаки.

Для решения этого квеста определите количество столбцов, возвращаемых запросом, выполнив атаку UNION с помощью SQL-инъекции, которая возвращает дополнительную строку, содержащую нулевые значения.

Анализ

Приступим к анализу! Для начала посмотрим на страницу и просто потыкаем разные кнопки и посмотрим, какие параметры строки запроса есть появляются при нажатии на кнопки.

Нажмем например кнопку "Gifts":

Видим в строке параметр Gifts. Пробуем вставить вместо этого стандартные символы для поиска SQL уязвимостей:

'--

Видим, что сервер ответил нормально, а значит, что этот параматер уязвим к SQL-инъекциям. Теперь нам нужно найти способ получить количество столбцов, которые получаются в запросе.

Теперь попробуем провести UNION атаку и вставить параметр NULL в запрос:

' UNION SELECT NULL--

Приложение возвращает нам ошибку - это значит, что столбцов в запросе больше. Оно в принципе и неудивительно, поскольку перейдя на разные категории у нас есть значение с названием товара и его ценой - это значит, что у нас есть минимум два столбца, которые получает запрос.

Попробуем вставить еще один NULL

' UNION SELECT NULL, NULL--

Получаем ту же ошибку. Но что если ввести три?

Получаем положительный результат и поздравление о том, что мы прошли квест.

Но как же самый первый способ, который я описал?

Давайте попробуем и его:

' ORDER BY 1--

В этом запросе помимо категории еще добавляется условие, что оно должно быть отсортировано по первому столбцу. Что же возвращает нам сервер?

Как видим, сервер отвечает нам списком товаров, это значит, что один столбец точно есть в базе данных. Также можно добавить параметр DESC тогда товары будут отсортированы еще и в порядке убывания.

Попробуем теперь ввести номер столбца 2:

Приложение тоже нам возвращает список товаров. Хочу отметить, что порядок товаров изменился, таким образом перебирая порядковые номера можно еще и понять, какой номер столбца чем является.

Введя номер 3 можно понять, что третий столбец хранит в себе цену товара, так как все цены отсортировались в порядке возрастания.

Теперь введем 4 номер и посмотрим что произойдет теперь

Получаем ошибку сервера. Это значит, что запрашивается всего три столбца. Метод с ORDER BY является более качественным, так как можно более точно предположить, какой столбец за что отвечает.

А что же с BurpSuite?

Если вы читали самую первую статью, вы помните, что я упоминал об этой программе, но до этого момента мы ее ни разу не использовали. Давайте исправим эту несправедливость.

Для чего он нужен?

Burp Suite — это набор инструментов для тестирования безопасности веб-приложений. Он предоставляет различные функции, включая сканирование уязвимостей, перехват и изменение трафика между браузером и сервером, анализ защищенности и тестирование на проникновение. Burp Suite используется для обнаружения и эксплуатации уязвимостей веб-приложений, а также для проверки и обеспечения их безопасности.

Нам нужно повторить запросы, которые мы делаем с браузера при помощи BurpSuite, но чтобы не переписывать все значение куки и юзер-агентов, используем встроенную функцию.

Для начала скачаем расширение ProxyFoxy:

Запускаем BurpSuite

Теперь нажимаем на пункт Proxy

Обязательно отметьте галочки как показано на скриншоте:

Теперь скопируйте айпи и порт прокси сервера

Вставьте его в proxyfoxy:

Мы сохранили прокси бурп сьюта. Теперь активируем прокси нажав по нему в расширении.

Но теперь есть важный нюанс. Соединение будет по умолчанию незащищенным, поэтому в поле ввода URL пишем ссылку:

http://burp

И переходим на страницу.

Нажимаем на кнопку в правом верхнем углу: "CA Certificate"

У нас скачался сертификат.

Переходим в настройки браузера и ищем пункт "сертификаты":

И выбираем переименованный нами ранее сертификат, не забываем указать параметр расширения сертификата.

Отмечаем галочки и нажимаем "ОК"

Теперь мы полностью готовы к использованию!

Использование BurpSuite

Теперь вернемся к нашей лаборатории. Для начала в графе proxy включаем "Intercept"

Теперь включив прокси вернемся к странице лаборатории и перезагрузим страницу. Теперь в графе Intercept у нас должна была появиться копия нашего запроса, который мы сделали.

Если у вас что-то другое, не похожее на пример из скриншота, то нажмите пару раз на кнопку Forward. Поскольку Burp Suite отлавливает абсолютно все запросы, то нужно их пропустить.

Теперь нажимаем кнопку Action и выбираем пункт "Send to repeater"

Нажав на пункт Repeater вверху переходим в меню повторителя

Здесь можно отправлять запросы как будто это наш браузер и получать ответы. Проведем нашу атаку еще раз, только с использованием BurpSuite.

На первой строчке четко видно параметры категорий, в них мы и введем нашу инъекцию.

Такой формат нечитаемый программой, поэтому все, что мы хотим, чтобы было указано в параметрах и воспринималось софтом как параметр выделяем и используем комбинацию CTRL+U.

После данной манипуляции наш запрос будет выглядеть так:

Теперь можно отправить запрос на сервер и посмотреть, что из этого получится.

Выбрав меню Render можно посмотреть, как выглядит реально страница если смотреть ее с браузера. Тоже очень удобно.

Как и в прошлый раз, сервер вернул нам ошибку, так как у нас ошибка в запросе в базе данных, теперь давайте сразу же напишем вариант, который был верный.

category=Gifts' UNION SELECT NULL, NULL, NULL--

Вуаля! Сервер ответил нам кодом 200.

Можно еще посмотреть рендер страницы, которую нам вернул сервер и убедиться, что все получилось.

В качестве домашнего задания, вы можете попробовать использовать ORDER BY функцию чтобы провести эту атаку.

На связи был админ канала Falcon Bytes, успехов!