Введение

Запрос ` OR EXTRACTVALUE(3464,CONCAT(0x7e,((SELECT (ELT(3464=3464,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции. Такие конструкции используются злоумышленниками для извлечения данных из базы данных через намеренно вызываемые ошибки СУБД. В данной статье мы подробно разберём, как работает этот запрос, какие функции MySQL задействованы и как защититься от подобных атак.

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

SQL-инъекция — это один из самых распространённых способов взлома веб-приложений, при котором вредоносный код внедряется в SQL-запрос через пользовательский ввод. Error-based (основанная на ошибках) разновидность характеризуется тем, что атакующий заставляет базу данных выдать сообщение об ошибке, содержащее конфиденциальную информацию. Это возможно, когда приложение выводит ошибки СУБД прямо на страницу.

В отличие от union-based инъекций, где результаты внедряются в обычный вывод, error-based полагается на функции, генерирующие ошибки с полезной нагрузкой. MySQL предоставляет несколько таких функций, в частности EXTRACTVALUE и UPDATEXML.

Разбор синтаксиса запроса

Рассмотрим запрос по частям:

  • ` — обратный апостроф, который может закрывать идентификатор в исходном запросе, чтобы затем внедрить свой код.
  • OR — логический оператор, позволяющий добавить условие, которое всегда истинно или ложно, но главное — выполнить внедрённую функцию.
  • EXTRACTVALUE(3464,CONCAT(0x7e,((SELECT (ELT(3464=3464,1)))),0x7e)) — вызов функции EXTRACTVALUE, которая извлекает значение из XML-фрагмента по XPath-выражению. Если XPath-выражение синтаксически неверно, MySQL выдаёт ошибку, содержащую переданные данные.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса.

Функция EXTRACTVALUE

EXTRACTVALUE(XML_frag, XPath_expr) принимает два аргумента: фрагмент XML и выражение XPath. Она возвращает текст первого узла, соответствующего выражению. Если XPath-выражение содержит ошибку, MySQL генерирует сообщение вида: XPATH syntax error: '...'. Злоумышленник может поместить в XPath конкатенацию своего запроса, чтобы увидеть результат в тексте ошибки.

Функция CONCAT

CONCAT(str1, str2, ...) объединяет строки. В нашем случае она склеивает символ ~ (код 0x7e), результат подзапроса и ещё один ~. Эти тильды служат маркерами, по которым легко найти внедрённые данные в сообщении об ошибке.

Подзапрос с ELT

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В примере используется ELT(3464=3464,1). Выражение 3464=3464 всегда истинно, что в числовом контексте даёт 1. Таким образом, ELT(1,1) возвращает строку '1'. Это простейшая демонстрация: в реальной атаке вместо 1 мог бы стоять подзапрос, извлекающий, например, имя пользователя или хеш пароля.

Комментарий -- -

Два дефиса и пробел (или другой символ) обозначают начало комментария в MySQL. Всё, что идёт после, игнорируется. Это позволяет обойти проверки и завершить запрос корректно.

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

Предположим, уязвимый запрос выглядит так:

SELECT * FROM users WHERE id = '$input';

Если передать в $input строку ` OR EXTRACTVALUE(3464,CONCAT(0x7e,((SELECT (ELT(3464=3464,1)))),0x7e))-- -, итоговый запрос станет:

SELECT * FROM users WHERE id = '` OR EXTRACTVALUE(3464,CONCAT(0x7e,((SELECT (ELT(3464=3464,1)))),0x7e))-- -';

MySQL выполнит функцию EXTRACTVALUE, которая попытается интерпретировать строку ~1~ как XPath. Поскольку это невалидный XPath, возникнет ошибка: XPATH syntax error: '~1~'. В результате на странице отобразится сообщение с внедрёнными данными. В нашем случае это просто 1, но при замене ELT(3464=3464,1) на подзапрос, например (SELECT password FROM users LIMIT 1), злоумышленник получит пароль.

Зачем это нужно злоумышленнику?

Error-based инъекции позволяют:

  • Получить имена таблиц и столбцов из системной схемы information_schema.
  • Извлечь логины, пароли, персональные данные пользователей.
  • Обойти аутентификацию, если запрос связан с проверкой учётных данных.

Особенность метода в том, что он работает даже тогда, когда приложение не выводит результаты запроса напрямую, но отображает ошибки. Если вывод ошибок отключён, атакующий может использовать blind-техники, но error-based проще и быстрее.

Методы защиты

Чтобы предотвратить подобные атаки, необходимо применять комплекс мер:

  1. Параметризованные запросы (prepared statements). Это самый надёжный способ: данные пользователя передаются отдельно от SQL-кода и не могут изменить его структуру.
  2. Экранирование специальных символов. Если параметризация невозможна, следует использовать функции экранирования, например mysqli_real_escape_string.
  3. Отключение вывода ошибок СУБД. Сообщения об ошибках должны логироваться, а не отображаться пользователю.
  4. Ограничение прав пользователя БД. Учётная запись веб-приложения не должна иметь прав на чтение системных таблиц и выполнение опасных функций.
  5. Использование WAF. Веб-application firewall может блокировать запросы, содержащие характерные сигнатуры SQL-инъекций.
  6. Регулярное обновление СУБД и фреймворков. Новые версии часто закрывают известные уязвимости.

Заключение

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

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

Источники