Что это за строка?

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

В данном конкретном случае запрос не несёт реальной вредоносной нагрузки — он лишь проверяет, уязвимо ли приложение, и возвращает число 1. Однако понимание принципа работы таких строк критически важно для разработчиков и специалистов по безопасности.

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

Рассмотрим каждый элемент по отдельности.

1. ')) — закрытие предыдущих конструкций

Два символа ) и апостроф ' используются для завершения оригинального SQL-запроса, в который внедряется инъекция. Это позволяет «вырваться» из строкового литерала и добавить собственный код. Часто такие комбинации подбираются методом перебора в зависимости от контекста уязвимого запроса.

2. AND EXTRACTVALUE(9918, CONCAT(...)) — основная полезная нагрузка

Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-строки. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой отображается переданный XML-фрагмент. Это и используется для вывода данных.

Первый аргумент — число 9918 — не является корректным XML, поэтому функция гарантированно вызовет ошибку. Второй аргумент — результат CONCAT(0x7e, ((SELECT (ELT(9918=9918,1)))), 0x7e).

3. CONCAT(0x7e, ..., 0x7e) — обёртка для читаемости

0x7e — это шестнадцатеричное представление символа ~ (тильда). Он добавляется слева и справа от выводимого значения, чтобы в сообщении об ошибке легко было найти границы полученных данных. Тильда выбрана как редко встречающийся символ, который не спутать с другим текстом.

4. SELECT (ELT(9918=9918,1)) — подзапрос, возвращающий значение

Функция ELT() возвращает N-й элемент из списка. В данном случае условие 9918=9918 всегда истинно, поэтому ELT(1,1) вернёт первый элемент — число 1. Это простейшая проверка: если инъекция выполнится, в ошибке появится ~1~.

В реальных атаках вместо 1 подставляются имена таблиц, колонок или другие данные, полученные через подзапросы. Например, ELT(1, (SELECT password FROM users LIMIT 1)).

5. -- - — комментарий

Двойной дефис с пробелом (или с дополнительным символом) превращает остаток оригинального запроса в комментарий. Это необходимо, чтобы не нарушать синтаксис SQL и избежать ошибок, связанных с лишними кавычками или условиями.

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

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

SELECT * FROM articles WHERE id = '$_GET[id]'

Если передать в параметр id нашу строку, итоговый запрос примет вид:

SELECT * FROM articles WHERE id = '')) AND EXTRACTVALUE(9918,CONCAT(0x7e,((SELECT (ELT(9918=9918,1)))),0x7e))-- -'

MySQL попытается выполнить EXTRACTVALUE с некорректным XML, что приведёт к ошибке вида:

XPATH syntax error: '~1~'

Таким образом, атакующий видит результат выполнения подзапроса. В нашем случае это просто 1, но заменив его на другой запрос, можно извлечь любые данные из базы.

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

Error-based инъекции — один из самых удобных способов получения информации, когда приложение выводит сообщения об ошибках СУБД. Они позволяют:

  • определить версию MySQL;
  • получить имена таблиц и колонок;
  • извлечь логины, пароли, хеши и другую конфиденциальную информацию;
  • в некоторых случаях — выполнить произвольные команды на сервере.

Конкретная строка с 9918 и ELT(9918=9918,1) часто используется в автоматических сканерах уязвимостей для быстрой проверки наличия инъекции. Если сервер возвращает ошибку с ~1~, значит, приложение уязвимо.

Как защититься?

Основной способ защиты от SQL-инъекций — использование параметризованных запросов (prepared statements). В этом случае данные передаются отдельно от SQL-кода, и внедрение становится невозможным. Дополнительные меры:

  • Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string.
  • Валидация и фильтрация входных данных (например, приведение к целому числу).
  • Отключение вывода подробных ошибок СУБД в production-окружении.
  • Использование ORM и query builder'ов, которые автоматически параметризуют запросы.
  • Регулярное обновление СУБД и веб-приложений.

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

Вывод

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

Источники