Что это за строка?
Строка OR EXTRACTVALUE(9800,CONCAT(0x7e,((SELECT (ELT(9800=9800,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, использующая ошибки функций MySQL для извлечения данных. Подобные конструкции применяются злоумышленниками для атак на веб-приложения, которые небезопасно обрабатывают пользовательский ввод при формировании SQL-запросов.
В основе лежит функция EXTRACTVALUE, предназначенная для работы с XML. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение синтаксически некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданная строка. Именно это свойство используется для error-based SQL-инъекции — метода, при котором данные извлекаются через сообщения об ошибках базы данных.
Разбор по частям
Рассмотрим структуру запроса детально:
- OR — логический оператор, который добавляется к исходному условию
WHERE. Если исходное условие ложно,ORс истинным выражением сделает всё условие истинным, что может привести к возврату всех строк таблицы. - EXTRACTVALUE(9800, ...) — вызов функции. Первый аргумент
9800— это произвольное число, которое интерпретируется как XML-фрагмент (в данном случае не является валидным XML, но это не мешает вызову). - CONCAT(0x7e, ..., 0x7e) — функция конкатенации.
0x7e— это шестнадцатеричное представление символа тильды (~). Тильда используется как разделитель, чтобы облегчить поиск внедрённых данных в тексте ошибки. - ((SELECT (ELT(9800=9800,1)))) — подзапрос, который возвращает результат функции
ELT.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь9800=9800— всегда истинное условие, поэтомуELTвозвращает1(первый элемент). В реальной атаке вместо1мог бы быть, например,version()илиdatabase(). - -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не нарушать его синтаксис.
Как это работает
Предположим, что веб-приложение формирует запрос вида:
SELECT * FROM users WHERE id = '$input';
Если злоумышленник передаст в $input строку 1 OR EXTRACTVALUE(9800,CONCAT(0x7e,((SELECT (ELT(9800=9800,1)))),0x7e))-- -, то итоговый запрос станет таким:
SELECT * FROM users WHERE id = '1' OR EXTRACTVALUE(9800,CONCAT(0x7e,((SELECT (ELT(9800=9800,1)))),0x7e))-- -';
База данных выполнит функцию EXTRACTVALUE. Поскольку второй аргумент содержит символ ~ и не является корректным XPath-выражением, MySQL сгенерирует ошибку. В тексте ошибки будет отображено переданное значение — в данном случае ~1~. Если бы вместо 1 стояла функция version(), в ошибке появилась бы версия СУБД. Таким образом, атакующий может пошагово извлекать произвольные данные: имена таблиц, столбцов, логины, пароли и т.д.
Стоит отметить, что EXTRACTVALUE была удалена в MySQL 8.0. В более старых версиях (5.7 и ниже) она доступна и активно использовалась в эксплойтах. Аналогичный принцип применяется с функциями UPDATEXML и GTID_SUBSET.
Цели и последствия
Основная цель такой инъекции — получить несанкционированный доступ к данным. В зависимости от привилегий пользователя базы данных злоумышленник может:
- Читать содержимое таблиц (персональные данные, хеши паролей, платёжная информация).
- Изменять или удалять данные.
- Выполнять административные операции, если уязвимость позволяет обойти аутентификацию.
Error-based инъекции особенно опасны, потому что они не требуют слепого перебора и дают немедленный результат в виде сообщения об ошибке. Однако они возможны только тогда, когда приложение выводит ошибки СУБД пользователю.
Как защититься
Чтобы предотвратить подобные атаки, разработчикам следует придерживаться следующих правил:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ, так как данные не попадают напрямую в SQL-код.
- Применять хранимые процедуры с параметрами, если это возможно.
- Экранировать специальные символы с помощью функций вроде
mysqli_real_escape_string, но это менее надёжно, чем подготовленные выражения. - Отключать вывод ошибок СУБД в продакшене. Ошибки должны логироваться, а пользователю показываться общее сообщение.
- Ограничивать привилегии пользователя базы данных, от имени которого работает приложение. Не давайте ему прав на чтение системных таблиц без необходимости.
- Регулярно обновлять СУБД и использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Важно понимать, что EXTRACTVALUE — не единственная функция, эксплуатируемая в error-based атаках. Злоумышленники также используют UPDATEXML, XMLType, GTID_SUBSET и другие. Поэтому защита должна быть комплексной.
Заключение
Строка OR EXTRACTVALUE(9800,CONCAT(0x7e,((SELECT (ELT(9800=9800,1)))),0x7e))-- - — это учебный пример SQL-инъекции, демонстрирующий уязвимость веб-приложений перед атаками на основе ошибок. Понимание механики таких атак помогает разработчикам и специалистам по безопасности создавать более защищённые системы. Если вы обнаружили подобную строку в логах или входных данных, это признак попытки взлома, и следует немедленно проверить безопасность вашего приложения.
Комментарии
—Войдите, чтобы оставить комментарий