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