Gray Hat C#, SQL-Injection

#13 Gray Hat C#. Руководство для хакера по созданию и автоматизации инструментов безопасности. Использование SQL-инъекций. Выполнение эксплойта на основе UNION вручную.

Здравствуйте, дорогие друзья.

Обнаружение возможных SQL-инъекций — это только половина работы тестера на проникновение; их эксплуатация — более важная и трудная половина. Ранее в этом разделе мы использовали URL-адрес из BadStore для фаззинга параметров строки запроса HTTP, одним из которых, был уязвимый параметр строки запроса, называемый searchquery. Параметр строки запроса URL-адреса searchquery уязвим для двух типов методов внедрения SQL. Оба типа внедрения (логический и UNION) невероятно полезны для понимания, поэтому я опишу написание эксплойтов для обоих типов с использованием одного и того же уязвимого URL-адреса BadStore.
Метод UNION проще всего эксплуатировать при использовании SQL-инъекций. Можно использовать UNION во внедрении запроса SELECT, когда Вы можете контролировать конец запроса SQL. Злоумышленник, который может добавить оператор UNION в конец оператора SELECT, может вернуть веб-приложению больше строк данных, чем первоначально предполагалось программистом.
Одна из самых сложных частей в реализации инъекции UNION заключается в балансировке столбцов. По сути, Вы должны сбалансировать то же количество столбцов с помощью предложения UNION, которое исходный оператор SELECT возвращает из базы данных. Другая проблема заключается в возможности программно определить, где в ответе веб-сервера появляются введенные Вами результаты.


Выполнение эксплойта на основе UNION вручную

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

Давайте возьмем уязвимую строку кода в веб-приложении BadStore (badstore.cgi, строка 203) и посмотрим, сколько столбцов она выбирает (см. листинг ниже).


Балансировка операторов SELECT требует некоторого тестирования, но из исходного кода BadStore я знаю, что этот конкретный запрос SELECT возвращает четыре столбца. При передаче полезных данных с пробелами, URL-кодированными как знаки плюса, как показано в листинге ниже, мы обнаруживаем, что слово hacked возвращается в виде строки в результатах поиска.

Когда значение searchquery в этой полезной нагрузке передается приложению, переменная searchquery используется непосредственно в SQL-запросе, отправленном в базу данных, и мы превращаем исходный SQL-запрос (листинг ниже) в новый SQL-запрос, не предназначенный для использования исходным программистом, как показано в листинге ниже.

Мы используем хеш, чтобы обрезать исходный запрос SQL, превращая любой код SQL, следующий за нашей полезной нагрузкой, в комментарий, который не будет выполняться MySQL. Теперь любые дополнительные данные (в данном случае слово «взломанный»), которые мы хотим вернуть в ответе веб-сервера, должны находиться в третьем столбце UNION.
Люди могут довольно легко определить, где данные, возвращаемые полезной нагрузкой, появляются на веб-странице после эксплуатации. Однако компьютеру необходимо указать, где искать данные, полученные в результате SQL-инъекции. Программно определить, где в ответе сервера находятся данные, контролируемые злоумышленником, может быть сложно. Чтобы упростить эту задачу, мы можем использовать функцию SQL CONCAT, чтобы окружить данные, которые нам действительно нужны, известными маркерами, как в листинге ниже.

Полезная нагрузка в листинге ниже использует шестнадцатеричные значения для добавления данных в слева и справа от дополнительного значения, которое мы выбираем с помощью нашей полезной нагрузки. Если полезные данные отображаются обратно в HTML-коде веб-приложения, регулярное выражение не будет случайно совпадать с исходными полезными данными. В этом примере 0x71766a7a71 — это qvjzq, а 0x716b626b71qkbkq. Если внедрение сработало, ответ должен содержать qvjzqhackedqkbkq. Если внедрение не работает и результаты поиска возвращаются как есть, регулярное выражение будет такое как: , и оно не будет соответствовать шестнадцатеричным значениям в исходной полезной нагрузке. Функция MySQL CONCAT() — это удобный способ гарантировать, что наш эксплойт получит правильные данные из ответа веб-сервера. В листинге ниже показан более полезный пример. Здесь мы можем заменить функцию CONCAT() из предыдущей полезной нагрузки, чтобы вернуть текущую базу данных, окруженную известными левым и правым маркерами.

Результатом внедрения в функцию поиска BadStore должен быть qvbzqbadstoredbqvkvq. Регулярное выражение, такое как qvbzq(.)qvkvq, должно возвращать значение badstoredb, имя текущей базы данных.
Теперь, когда мы знаем, как эффективно получать значения из базы данных, мы можем начать перекачивать данные из текущей базы данных с помощью инъекции UNION. Одной особенно полезной таблицей в большинстве веб-приложений является таблица пользователей. Как вы можете видеть в листинге ниже, мы можем легко использовать описанную ранее технику внедрения UNION, для перечисления пользователей и хэшей; их паролей из таблицы пользователей (называемой userdb) с помощью одного запроса и полезной нагрузки.

Результаты должны появиться на веб-странице в таблице элементов, если внедрение прошло успешно.

На этом все. Всем хорошего дня!

Цикл статей по Gray Hat C#. Руководство для хакера по созданию и автоматизации инструментов безопасности.