Что представляет собой этот запрос

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

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

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

1. Закрывающие скобки ))

В начале стоят две закрывающие круглые скобки. Они нужны, чтобы «закрыть» ранее открытые скобки в оригинальном SQL-запросе приложения. Например, если уязвимый запрос выглядит как SELECT * FROM products WHERE id = (SELECT id FROM categories WHERE name = '$input'), то злоумышленник подставляет )) OR ..., чтобы выйти из вложенного выражения и добавить своё условие.

2. Оператор OR

После скобок идёт OR — логическое «или». Оно позволяет добавить к запросу новое условие, которое будет вычислено, даже если исходное условие ложно. В error-based атаках это нужно, чтобы гарантировать выполнение внедрённой функции.

3. Функция EXTRACTVALUE

EXTRACTVALUE — встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Если XPath-выражение некорректно или возвращает не单 узел, MySQL генерирует ошибку. Злоумышленники используют это свойство: они передают в качестве XPath строку, содержащую конкатенацию запрещённых символов и извлекаемых данных, чтобы ошибка содержала эти данные.

В нашем payload первый аргумент — 5830 (произвольное число, может быть любым), второй — сложное выражение CONCAT(0x7e,((SELECT (ELT(5830=5830,1)))),0x7e).

4. Функция CONCAT и шестнадцатеричные литералы 0x7e

CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда) в кодировке ASCII. Тильда используется как разделитель, чтобы облегчить автоматическое извлечение данных из текста ошибки. Конструкция CONCAT(0x7e, ..., 0x7e) создаёт строку вида ~<данные>~.

5. Подзапрос SELECT (ELT(5830=5830,1))

ELT(N, str1, str2, ...) возвращает строку с номером N из списка. В данном случае ELT(5830=5830, 1) — первый аргумент это логическое выражение 5830=5830, которое всегда истинно (1). Значит, ELT вернёт 1. Подзапрос SELECT (ELT(...)) просто возвращает эту единицу. Зачем это нужно? Это простейшая проверка работоспособности инъекции: если сервер вернёт ошибку с символом ~1~, значит, внедрение выполнено. В реальных атаках вместо 1 подставляют подзапросы, извлекающие имена таблиц, пароли и т.д.

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

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

Как это работает целиком

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

SELECT * FROM articles WHERE id = ('$user_input')

Если подставить наш payload, запрос превратится в:

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

После закрывающих скобок и OR база данных попытается вычислить EXTRACTVALUE. Так как второй аргумент содержит символ ~, который не является допустимым XPath-выражением, MySQL сгенерирует ошибку вида:

XPATH syntax error: '~1~'

Эта ошибка будет возвращена приложению (если оно выводит ошибки БД). Злоумышленник, увидев ~1~, понимает, что инъекция работает. Далее он заменит 1 на подзапрос, например (SELECT password FROM users LIMIT 1), и получит в сообщении об ошибке ~хеш_пароля~.

Почему это опасно

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

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

  • Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: параметры передаются отдельно от текста запроса, и внедрение становится невозможным.
  • Экранируйте специальные символы. Если по каким-то причинам нельзя использовать подготовленные выражения, применяйте функции экранирования, предоставляемые драйвером БД (например, mysqli_real_escape_string в PHP).
  • Ограничивайте права пользователя БД. Веб-приложение должно подключаться к базе под учётной записью с минимально необходимыми привилегиями (обычно только SELECT, INSERT, UPDATE, DELETE для нужных таблиц).
  • Отключайте вывод ошибок БД в production. Сообщения об ошибках должны логироваться, но не показываться пользователю.
  • Используйте WAF (Web Application Firewall). Современные WAF умеют распознавать подобные payload'ы и блокировать запросы.

Заключение

Строка )) OR EXTRACTVALUE(5830,CONCAT(0x7e,((SELECT (ELT(5830=5830,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный инструмент для проверки уязвимости и извлечения данных через ошибки MySQL. Понимание механики таких атак помогает разработчикам писать безопасный код, а специалистам по безопасности — эффективнее обнаруживать и предотвращать вторжения.

Источники