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

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

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

Разбор по компонентам

1. Начальные символы )))

Три закрывающие скобки нужны, чтобы «закрыть» ранее открытые скобки в оригинальном SQL-запросе, который формирует уязвимое приложение. Например, если сервер выполняет запрос вида SELECT * FROM users WHERE id = (((...))), то инъекция должна сначала уравновесить синтаксис, иначе запрос не выполнится.

2. AND

Логический оператор AND присоединяет вредоносное условие к исходному запросу. Если исходное условие истинно, то результат будет зависеть от второго операнда. В error-based инъекции это не так важно — главное, чтобы функция EXTRACTVALUE выполнилась и вызвала ошибку.

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

EXTRACTVALUE — это встроенная функция MySQL (и MariaDB), предназначенная для работы с XML. Она принимает два аргумента: XML-документ и XPath-выражение. Если первый аргумент не является корректным XML, функция генерирует ошибку XPATH syntax error, в тексте которой отображается переданное XPath-выражение.

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

4. ELT(8300=8300,1)

ELT() — функция MySQL, возвращающая N-й элемент из списка строк. Синтаксис: ELT(N, строка1, строка2, ...). В данном случае 8300=8300 — это логическое выражение, которое всегда истинно (равно 1). То есть ELT(1, 1) вернёт строку '1'. Это простейший тест: если инъекция сработает, в ошибке появится ~1~.

В реальной атаке вместо 1 подставляется подзапрос, извлекающий данные, например: ELT(1, (SELECT password FROM users LIMIT 1)). Тогда в тексте ошибки отобразится пароль.

5. -- -

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

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

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

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

СУБД сначала вычислит EXTRACTVALUE. Поскольку первый аргумент не является XML, возникнет ошибка. В сообщении об ошибке будет что-то вроде:

XPATH syntax error: '~1~'

Атакующий видит, что инъекция работает, и может заменить 1 на подзапрос для извлечения имён таблиц, колонок или данных.

Аналогичные error-based техники используют функции UPDATEXML, GTID_SUBSET, EXP и другие. Они позволяют обходить фильтры, если приложение выводит ошибки БД на страницу.

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

  • Получение содержимого базы данных без прямого вывода результатов запроса.
  • Обход ограничений, когда UNION-инъекции невозможны (например, из-за разного числа колонок).
  • Автоматизация через инструменты вроде sqlmap, которые генерируют подобные строки.

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

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

Что означает конкретно эта строка?

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

Важно понимать: сам по себе этот запрос не крадёт данные, он лишь проверяет возможность атаки. Но если приложение уязвимо, злоумышленник может заменить ELT(8300=8300,1) на ELT(1,(SELECT ...)) и извлечь конфиденциальную информацию.

Вывод

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

Источники