Введение

В запросе пользователя фигурирует строка OR EXTRACTVALUE(6326,CONCAT(0x7e,((SELECT (ELT(6326=6326,1)))),0x7e))-- -. Это не случайный набор символов, а типичный пример SQL-инъекции — атаки, при которой злоумышленник внедряет вредоносный код в SQL-запрос через пользовательский ввод. В данном случае используется функция EXTRACTVALUE для извлечения данных из базы через генерацию ошибок. Разберём, как это работает, зачем нужно и как защититься.

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

SQL-инъекция (SQLi) — один из самых распространённых способов взлома веб-приложений. Если сайт не фильтрует входные данные, злоумышленник может передать в поле ввода (например, в форму логина) специально сконструированную строку, которая изменит логику SQL-запроса. Это позволяет обойти аутентификацию, украсть данные, изменить или удалить информацию.

Существует несколько типов SQL-инъекций:

  • Union-based — объединение результатов легитимного запроса с данными из других таблиц.
  • Error-based — извлечение данных через сообщения об ошибках.
  • Blind — когда данные получают по косвенным признакам (время ответа, true/false).
  • Stacked queries — выполнение нескольких запросов подряд.

Рассматриваемая конструкция относится к error-based инъекциям.

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

Давайте пошагово разберём, что делает каждый элемент.

1. OR

Логический оператор OR используется для изменения условия WHERE. Например, если исходный запрос был SELECT * FROM users WHERE id = '$input', то при подстановке ' OR 1=1 -- - он превратится в SELECT * FROM users WHERE id = '' OR 1=1 -- -', что вернёт все строки таблицы. В нашем случае OR присоединяет вызов функции EXTRACTVALUE.

2. EXTRACTVALUE(6326, CONCAT(...))

EXTRACTVALUE — функция MySQL (и MariaDB), предназначенная для извлечения значения из XML-документа по XPath-выражению. Синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Она возвращает текст узла, соответствующего XPath. Если XPath некорректен или возвращает несколько узлов, функция генерирует ошибку. Эту особенность и эксплуатируют злоумышленники.

В нашем случае первый аргумент — 6326 (произвольное число, не являющееся валидным XML), второй — результат CONCAT.

3. CONCAT(0x7e, ((SELECT (ELT(6326=6326,1)))), 0x7e)

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

Внутри CONCAT стоит подзапрос (SELECT (ELT(6326=6326,1))). ELT — функция, возвращающая N-й элемент из списка. Здесь ELT(6326=6326,1) вернёт 1, так как условие 6326=6326 истинно. Это простейший пример; на практике вместо ELT может быть подзапрос, извлекающий имя пользователя, пароль или другую конфиденциальную информацию.

4. -- -

Это комментарий. В MySQL -- начинает комментарий до конца строки, но требует пробела после себя. Символ - добавлен для надёжности (иногда пробел может быть удалён). Всё, что идёт после -- -, игнорируется, что позволяет отсечь остаток оригинального запроса.

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

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

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

Злоумышленник передаёт в параметр id нашу строку. Запрос становится:

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

При выполнении MySQL попытается вычислить EXTRACTVALUE. Поскольку первый аргумент 6326 не является корректным XML, функция выдаст ошибку. В сообщении об ошибке будет указано значение второго аргумента — строка, полученная в результате CONCAT. Если вместо ELT(6326=6326,1) подставить подзапрос, возвращающий, например, версию базы данных, то она отобразится в ошибке. Так злоумышленник может пошагово извлекать данные.

Пример ошибки:

XPATH syntax error: '~1~'

Тильды помогают легко выделить полезную нагрузку.

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

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

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

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

  • Экранирование специальных символов.
  • Валидация и фильтрация входных данных.
  • Ограничение прав пользователя базы данных (принцип наименьших привилегий).
  • Использование ORM и современных фреймворков.
  • Регулярное обновление СУБД и приложений.
  • Внедрение WAF (Web Application Firewall).

Также рекомендуется отключить вывод подробных ошибок SQL в продакшене, чтобы не давать атакующему лишней информации.

Заключение

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

Источники