Введение

SQL-инъекции остаются одной из самых опасных уязвимостей веб-приложений. Среди них особое место занимают error-based инъекции, когда злоумышленник извлекает данные через сообщения об ошибках базы данных. Запрос, который вы видите в заголовке, — классический пример такой атаки на MySQL с использованием функций EXTRACTVALUE и ELT. В этой статье мы детально разберём, как он работает, что означают его части и как защититься от подобных атак.

Что такое error-based SQL-инъекция

Error-based SQL-инъекция — это метод эксплуатации, при котором атакующий заставляет базу данных выдать полезную информацию прямо в тексте ошибки. В отличие от UNION-инъекций, где данные возвращаются в теле ответа, здесь используется механизм генерации ошибок с подстановкой результата подзапроса. MySQL, в частности, имеет несколько функций, которые при некорректных аргументах возвращают сообщение об ошибке, содержащее переданное значение. К таким функциям относятся EXTRACTVALUE и UPDATEXML.

Разбор запроса

Рассмотрим запрос: " AND EXTRACTVALUE(7725,CONCAT(0x7e,((SELECT (ELT(7725=7725,1)))),0x7e))-- -

Он состоит из нескольких частей:

  • " — закрывающая кавычка, которая завершает строковый литерал в уязвимом параметре.
  • AND — логический оператор, присоединяющий наше условие к оригинальному запросу.
  • EXTRACTVALUE(7725, CONCAT(...)) — вызов функции, которая извлекает значение из XML-фрагмента. Первый аргумент (7725) — это XML-документ, который на самом деле не является валидным XML (просто число). Второй аргумент — XPath-выражение, сформированное через CONCAT.
  • CONCAT(0x7e, ((SELECT (ELT(7725=7725,1)))), 0x7e) — конкатенация символа '~' (0x7e), результата подзапроса и снова '~'.
  • SELECT (ELT(7725=7725,1)) — подзапрос, который возвращает 1, если условие 7725=7725 истинно (а оно всегда истинно). Функция ELT возвращает N-й элемент из списка; здесь список состоит из одного элемента 1.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса.

В результате EXTRACTVALUE получает невалидный XPath (начинающийся с '~'), что вызывает ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и выводится результат подзапроса — в данном случае '1'.

Зачем нужны 0x7e и ELT

Символ 0x7e ('~') используется как маркер, чтобы отделить полезные данные от остального текста ошибки. Это облегчает автоматизированный парсинг результата. Функция ELT(7725=7725,1) — это простейший способ вернуть константу 1. В реальных атаках вместо неё подставляют подзапросы, извлекающие имена таблиц, колонок или данные пользователей. Например: ELT(1=1, (SELECT table_name FROM information_schema.tables LIMIT 1)).

Как это работает на практике

Предположим, уязвимый параметр — это id в URL: example.com/product.php?id=1". Если приложение не фильтрует кавычки, база данных выполнит наш инъекционный запрос. В результате мы увидим ошибку MySQL, содержащую результат подзапроса. Постепенно перебирая условия и подзапросы, атакующий может извлечь всю структуру базы данных и её содержимое.

Для автоматизации часто используют sqlmap — инструмент, который сам подбирает нужные функции и извлекает данные. Однако понимание ручного эксплойта важно для пентестеров и разработчиков.

Меры защиты

Чтобы предотвратить error-based SQL-инъекции, необходимо:

  • Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ.
  • Применять хранимые процедуры с параметрами.
  • Экранировать все пользовательские данные, попадающие в SQL-запросы, с помощью функций экранирования (например, mysqli_real_escape_string).
  • Включить вывод ошибок в лог, а не на экран, чтобы злоумышленник не видел сообщения СУБД.
  • Ограничить права пользователя базы данных, от имени которого работает приложение: запретить доступ к information_schema, если он не нужен.
  • Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.

Важно понимать, что никакая отдельная мера не даёт 100% гарантии, поэтому нужен комплексный подход.

Заключение

Запрос " AND EXTRACTVALUE(7725,CONCAT(0x7e,((SELECT (ELT(7725=7725,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции через функции EXTRACTVALUE и ELT. Он демонстрирует, как можно заставить MySQL выдать результат подзапроса в сообщении об ошибке. Понимание таких техник помогает разработчикам лучше защищать свои приложения, а пентестерам — эффективно искать уязвимости.

Источники