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

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

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

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

Чтобы понять смысл строки, разберём её на составные части.

1. Начало: %'))

Символы % и ' часто используются для «закрытия» исходного значения в запросе. Знак % может быть частью строки LIKE, а ' — закрывающая кавычка. Далее идут две закрывающие скобки )), которые завершают вложенные функции или условия в оригинальном запросе. Всё вместе это позволяет «вырваться» из контекста и добавить собственный код.

2. AND EXTRACTVALUE(...)

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

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

Функция CONCAT() объединяет несколько строк в одну. Здесь она собирает строку из трёх частей:

  • 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить поиск нужных данных в тексте ошибки.
  • ((SELECT (ELT(8169=8169,1)))) — подзапрос, который возвращает результат функции ELT().
  • Ещё один 0x7e — закрывающая тильда.

В результате CONCAT формирует строку вида ~<результат>~, которая затем передаётся в EXTRACTVALUE в качестве первого аргумента (XML-документа).

4. ELT(8169=8169,1)

Функция ELT() возвращает N-й элемент из списка строк. В данном случае первый аргумент — это логическое выражение 8169=8169, которое всегда истинно (1). Второй аргумент — 1. Когда условие истинно, ELT возвращает строку с индексом 1, то есть '1'. Если бы условие было ложным, ELT вернул бы NULL. Таким образом, конструкция ELT(8169=8169,1) — это простой способ получить константу '1', которая затем попадёт в CONCAT. В реальных эксплойтах вместо 1 может быть подставлен подзапрос, возвращающий интересующие злоумышленника данные, например, имя пользователя или хеш пароля.

5. Завершение: -- -

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

Как это работает вместе

Когда строка внедряется в уязвимый запрос, сервер MySQL выполняет примерно следующее:

  1. Закрываются исходные кавычки и скобки, чтобы синтаксис остался корректным.
  2. Вычисляется ELT(8169=8169,1), что даёт строку '1'.
  3. CONCAT создаёт строку '~1~'.
  4. EXTRACTVALUE(8169, '~1~') вызывается с первым аргументом 8169 (число, которое преобразуется в строку '8169') и вторым аргументом '~1~'. Поскольку '~1~' не является корректным XPath-выражением, MySQL генерирует ошибку. В тексте ошибки может появиться значение, переданное в CONCAT, то есть ~1~.
  5. Символы -- - комментируют остаток запроса.

В результате атакующий получает сообщение об ошибке, из которого может извлечь внедрённые данные. В данном примере это просто 1, но если вместо 1 подставить подзапрос, например (SELECT password FROM users LIMIT 1), то в ошибке отобразится хеш пароля.

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

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

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

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

  • Экранировать все пользовательские данные, попадающие в SQL-запросы.
  • Отключить вывод подробных сообщений об ошибках базы данных в production-окружении.
  • Регулярно обновлять СУБД и использовать средства обнаружения вторжений (WAF).
  • Проводить аудит кода и тестирование на проникновение.

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

Заключение

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

Источники