Введение
Встречая строку вида %'))) AND EXTRACTVALUE(1481,CONCAT(0x7e,((SELECT (ELT(1481=1481,1)))),0x7e))-- -, многие задаются вопросом: что это и зачем нужно? Это не случайный набор символов, а тщательно сконструированная error-based SQL-инъекция — атака, при которой злоумышленник заставляет базу данных выдать сообщение об ошибке, содержащее конфиденциальные данные. В данной статье мы подробно разберём, как работает эта конкретная инъекция, какие функции MySQL задействованы и как защититься от подобных угроз.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — один из самых распространённых способов взлома веб-приложений. Суть метода в том, что злоумышленник внедряет в пользовательский ввод (форму, URL-параметр, cookie) фрагмент SQL-кода, который затем выполняется на сервере базы данных. Если приложение не фильтрует входные данные и не использует параметризованные запросы, база данных воспринимает этот код как часть легитимного запроса.
Существует несколько типов SQL-инъекций:
- Union-based — объединение результатов легитимного запроса с данными из других таблиц.
- Error-based — извлечение данных через сообщения об ошибках.
- Blind — когда данные извлекаются по косвенным признакам (время отклика, логические условия).
- Stacked queries — выполнение нескольких запросов подряд.
Наш пример относится к error-based типу, который считается одним из самых эффективных при наличии вывода ошибок.
Разбор строки инъекции
Рассмотрим строку по частям:
%'))) AND EXTRACTVALUE(1481,CONCAT(0x7e,((SELECT (ELT(1481=1481,1)))),0x7e))-- -
%')))— это попытка закрыть предыдущие кавычки и скобки в исходном запросе. Знак%часто используется в LIKE-запросах, а кавычка и скобки помогают «выровнять» синтаксис, чтобы внедряемый код был корректным.AND EXTRACTVALUE(...)— добавление условия с функциейEXTRACTVALUE. Эта функция извлекает значение из XML-фрагмента по XPath-выражению. Если XPath синтаксически неверен, MySQL генерирует ошибку.- Аргументы
EXTRACTVALUE:- Первый аргумент —
1481(число, которое будет преобразовано в XML). - Второй аргумент —
CONCAT(0x7e, ((SELECT (ELT(1481=1481,1)))), 0x7e). Здесь0x7e— это шестнадцатеричное представление символа~(тильда).ELT(1481=1481,1)возвращает строку '1', если условие истинно (1481=1481 всегда истинно). Таким образом, второй аргумент превращается в строку~1~.
- Первый аргумент —
-- -— комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не возникло синтаксической ошибки.
В итоге база данных пытается выполнить XPath-выражение ~1~, которое не является допустимым. MySQL выдаёт ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении содержится результат подзапроса SELECT (ELT(1481=1481,1)) — строка '1'. В реальной атаке вместо ELT(1481=1481,1) подставляется подзапрос, извлекающий, например, имя пользователя или хеш пароля. Ошибка выведет эти данные.
Зачем нужна функция EXTRACTVALUE?
EXTRACTVALUE — встроенная функция MySQL (и MariaDB), предназначенная для работы с XML. Она принимает XML-документ и XPath-выражение, возвращая текст узла. Однако при передаче некорректного XPath она генерирует ошибку, которая включает переданное значение. Это и используют атакующие: они намеренно вызывают ошибку, чтобы «вытащить» данные через сообщение.
Аналогично работают функции UPDATEXML и GTID_SUBSET. Все они относятся к классу error-based инъекций.
Другие элементы: ELT, CONCAT, 0x7e
- ELT(N, str1, str2, ...) — возвращает N-ю строку из списка. В нашем случае
ELT(1481=1481,1)возвращает '1', так как условие истинно (1 = истина). - CONCAT — объединяет строки. Здесь он склеивает тильды и результат ELT.
- 0x7e — шестнадцатеричный литерал для символа '~'. Тильда используется как маркер, чтобы в сообщении об ошибке было легко найти начало и конец извлечённых данных.
Как эксплуатируется такая инъекция?
Предположим, есть уязвимый параметр id в URL: http://example.com/product.php?id=1. Злоумышленник подставляет:
1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -
Если приложение уязвимо, оно вернёт ошибку с именем текущей базы данных. Далее можно извлекать таблицы, столбцы и сами данные, например:
1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT password FROM users LIMIT 1),0x7e))-- -
Постепенно атакующий получает полный доступ к базе.
Последствия успешной атаки
Успешная error-based SQL-инъекция может привести к:
- Утечке конфиденциальных данных (пароли, персональная информация, платёжные реквизиты).
- Полному захвату базы данных.
- Компрометации всего сервера (в зависимости от привилегий СУБД).
- Нарушению целостности данных (изменение, удаление записей).
Именно поэтому защита от SQL-инъекций является критически важной задачей для любого веб-разработчика.
Методы защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать параметризованные запросы (prepared statements). Это самый надёжный способ, при котором SQL-код и данные передаются раздельно, и база данных никогда не интерпретирует ввод как код.
- Применять ORM (например, Hibernate, Entity Framework). Они автоматически экранируют опасные символы.
- Валидировать и фильтровать входные данные. Проверять типы, длины, допустимые символы.
- Отключать вывод ошибок СУБД в продакшене. Сообщения об ошибках не должны попадать в браузер пользователя.
- Использовать веб-application firewall (WAF). Он может блокировать известные шаблоны атак.
- Регулярно обновлять СУБД и фреймворки. Устаревшие версии могут содержать уязвимости.
Также рекомендуется проводить аудит безопасности и тестирование на проникновение.
Заключение
Строка %'))) AND EXTRACTVALUE(1481,CONCAT(0x7e,((SELECT (ELT(1481=1481,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий, как злоумышленники используют особенности СУБД для извлечения данных. Понимание таких атак помогает разработчикам создавать более защищённые приложения. Помните: безопасность — это процесс, а не разовое действие. Всегда проверяйте свой код на уязвимости и следуйте лучшим практикам.
Комментарии
—Войдите, чтобы оставить комментарий