Что это за строка?
Строка ")))) AND EXTRACTVALUE(3411,CONCAT(0x7e,((SELECT (ELT(3411=3411,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах об уязвимостях и в инструментах для пентеста, например в sqlmap.
Внешне строка выглядит как набор случайных символов, но на самом деле это тщательно сконструированный запрос, который заставляет сервер базы данных выдать конфиденциальную информацию в тексте ошибки. Давайте разберём её по частям.
Анатомия инъекции
Начало: закрывающие скобки и кавычки
Фрагмент ")))) в начале — это попытка закрыть все открытые скобки и кавычки в оригинальном SQL-запросе, чтобы внедрить свой код. Злоумышленник предполагает, как выглядит уязвимый запрос, и подбирает количество закрывающих символов, чтобы «выровнять» синтаксис.
Функция EXTRACTVALUE
EXTRACTVALUE(3411, CONCAT(0x7e, ((SELECT (ELT(3411=3411,1)))), 0x7e)) — это вызов встроенной функции MySQL для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически неверно, MySQL выдаёт ошибку, в которой отображается переданное выражение. Именно это и используется для вывода данных.
CONCAT и 0x7e
CONCAT(0x7e, ..., 0x7e) объединяет строки. 0x7e — это шестнадцатеричный код символа тильды (~). Тильды служат маркерами, чтобы в сообщении об ошибке легко было найти начало и конец выводимых данных.
SELECT и ELT
SELECT (ELT(3411=3411,1)) — это подзапрос, который возвращает результат выражения ELT(3411=3411,1). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 3411=3411 — это всегда истинное условие, которое в MySQL возвращает 1. Таким образом, ELT(1,1) вернёт строку «1». В реальной атаке вместо этого подзапроса подставляются другие выражения для извлечения имён таблиц, колонок или данных.
Комментарий -- -
В конце стоит -- -. Двойной дефис с пробелом — это комментарий в SQL, который отсекает оставшуюся часть оригинального запроса, чтобы не нарушать синтаксис.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = '")))) AND EXTRACTVALUE(3411,CONCAT(0x7e,((SELECT (ELT(3411=3411,1)))),0x7e))-- -'После подстановки пользовательского ввода запрос превращается в:
SELECT * FROM users WHERE id = '"')))) AND EXTRACTVALUE(3411,CONCAT(0x7e,((SELECT (ELT(3411=3411,1)))),0x7e))-- -'СУБД выполняет запрос. Функция EXTRACTVALUE получает неверный XPath (потому что внутри CONCAT образуется строка, не являющаяся корректным XPath), и MySQL возвращает ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении мы видим результат выполнения подзапроса — «1». Если вместо ELT(3411=3411,1) подставить, например, SELECT version(), то в ошибке отобразится версия MySQL. Так злоумышленник может пошагово извлекать любые данные.
Почему это опасно
Error-based SQL-инъекции позволяют атакующему:
- Получить версию СУБД и другую служебную информацию.
- Извлечь имена таблиц и колонок из системной схемы
information_schema. - Читать конфиденциальные данные: логины, пароли, персональные данные пользователей.
- В некоторых случаях — модифицировать или удалять данные.
Особенность error-based подхода в том, что результат виден прямо в ответе сервера, что делает атаку очень быстрой и удобной для автоматизации.
Как защититься
Основной способ защиты от SQL-инъекций — использование параметризованных запросов (prepared statements). В этом случае пользовательский ввод передаётся отдельно от SQL-кода, и внедрить произвольные конструкции не получится.
Дополнительные меры:
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string(но это менее надёжно, чем параметризация). - Использование ORM (например, Doctrine, Hibernate), которые по умолчанию применяют параметризацию.
- Ограничение прав пользователя базы данных: не давайте приложению прав на чтение
information_schemaбез необходимости. - Включение логирования ошибок на стороне сервера и отключение вывода подробных ошибок в клиентский ответ.
- Регулярное сканирование кода и пентесты.
Важно понимать, что EXTRACTVALUE — не единственная функция, используемая в error-based атаках. Аналогично применяются UPDATEXML, GTID_SUBSET и другие. Поэтому защита должна быть комплексной.
Заключение
Строка ")))) AND EXTRACTVALUE(3411,CONCAT(0x7e,((SELECT (ELT(3411=3411,1)))),0x7e))-- - — это пример эксплойта для error-based SQL-инъекции в MySQL. Она демонстрирует, как через намеренно вызванную ошибку можно вывести данные из базы. Понимание таких конструкций помогает разработчикам и специалистам по безопасности лучше защищать свои приложения.
Комментарии
—Войдите, чтобы оставить комментарий