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

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

При обычной SQL-инъекции злоумышленник пытается получить данные, изменяя логику запроса. В error-based варианте он заставляет базу данных выдать ошибку, в тексте которой содержатся нужные сведения. MySQL-функция EXTRACTVALUE() как раз предназначена для работы с XML и при некорректном XPath-выражении возвращает сообщение с переданной строкой. Это позволяет «вытащить» результат подзапроса прямо в текст ошибки.

Разбор запроса по частям

  • )) — закрывающие скобки, которые «обрывают» оригинальный запрос приложения, чтобы вставить свой код.
  • AND EXTRACTVALUE(1808, ...) — вызов функции. Первый аргумент (1808) — произвольное число, второй — XPath-выражение.
  • CONCAT(0x7e, ((SELECT (ELT(1808=1808,1)))), 0x7e) — формирует строку, начиная и заканчивая символом ~ (0x7e). Внутри — подзапрос с ELT().
  • ELT(1808=1808,1) — возвращает 1, так как условие 1808=1808 истинно. Это простейшая проверка, которая в реальной атаке заменяется на извлечение данных (например, имени таблицы или пароля).
  • -- - — комментарий, обрезающий остаток оригинального SQL-запроса.

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

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

Цель — получить информацию о структуре базы данных или конкретные значения (логины, хеши паролей, номера карт). Поскольку ошибка возвращается в ответе сервера, атакующий может автоматизировать процесс: подставлять разные подзапросы и читать данные по частям. Например, вместо ELT(1808=1808,1) можно использовать (SELECT table_name FROM information_schema.tables LIMIT 1), чтобы узнать имя первой таблицы.

Пример реальной эксплуатации

Предположим, уязвимый параметр передаётся в URL: ?id=1. Злоумышленник подставляет:

1)) AND EXTRACTVALUE(1808,CONCAT(0x7e,(SELECT database()),0x7e))-- -

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

Как защититься от таких атак

  1. Использовать подготовленные выражения (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода, и внедрить функцию не получится.
  2. Экранировать специальные символы. Если подготовленные выражения недоступны, применяйте функции экранирования, например mysqli_real_escape_string() в PHP.
  3. Ограничить права пользователя БД. Учётная запись веб-приложения не должна иметь прав на чтение information_schema или доступ к лишним таблицам.
  4. Отключить вывод ошибок MySQL на продакшене. Сообщения об ошибках не должны попадать в ответ клиенту — это лишает атакующего обратной связи.
  5. Использовать WAF (Web Application Firewall). Современные WAF умеют распознавать сигнатуры error-based инъекций, включая EXTRACTVALUE и UPDATEXML.
  6. Регулярно проводить аудит кода и пентесты. Это помогает выявить уязвимости до того, как их найдут злоумышленники.

Связанные функции и альтернативы

Помимо EXTRACTVALUE(), в MySQL существуют другие функции, которые могут быть использованы для error-based инъекций:

  • UPDATEXML() — также генерирует ошибку XPath при неправильном выражении.
  • GTID_SUBSET() — в некоторых версиях MySQL вызывает ошибку с переданной строкой.
  • EXP() — переполнение при больших значениях, но менее информативно.

Важно понимать, что подобные техники работают не только в MySQL. В других СУБД (PostgreSQL, MS SQL) есть свои функции и приёмы для извлечения данных через ошибки.

Заключение

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

Источники