Строка )))) AND EXTRACTVALUE(2958,CONCAT(0x7e,((SELECT (ELT(2958=2958,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы через вывод сообщения об ошибке. В этой статье мы подробно разберём, как работает данный запрос, какие функции задействованы и как защититься от подобных атак.
Что такое error-based SQL-инъекция?
SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет в пользовательский ввод специальные конструкции, которые изменяют логику SQL-запроса. Error-based инъекция — это разновидность, при которой атакующий заставляет базу данных вернуть сообщение об ошибке, содержащее полезные данные (например, версию СУБД, имена таблиц, хеши паролей).
В отличие от blind-инъекций, где информация извлекается по косвенным признакам (истина/ложь, задержки), error-based даёт мгновенный результат — текст ошибки с внедрёнными данными. Это делает её очень эффективной при наличии соответствующей уязвимости.
Разбор строки по частям
Рассмотрим каждый элемент запроса:
))))— последовательность закрывающих скобок. Она нужна, чтобы «закрыть» ранее открытые скобки в оригинальном SQL-запросе, который формируется на сервере. Это позволяет внедрить свой код без синтаксической ошибки.AND— логический оператор, присоединяющий наше условие к исходному запросу.EXTRACTVALUE(2958, CONCAT(0x7e, ((SELECT (ELT(2958=2958,1)))), 0x7e))— вызов функцииEXTRACTVALUE, которая извлекает значение из XML-фрагмента по XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку с указанием проблемного фрагмента. Именно эту ошибку и использует атакующий.0x7e— шестнадцатеричное представление символа~(тильда). Он используется как разделитель, чтобы облегчить чтение вывода в сообщении об ошибке.(SELECT (ELT(2958=2958,1)))— подзапрос, который возвращает результат функцииELT.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь2958=2958— всегда истинное условие (1), поэтомуELT(1,1)вернёт строку «1». В реальной атаке вместо этой заглушки подставляется подзапрос, извлекающий нужные данные (например,SELECT version()илиSELECT password FROM users LIMIT 1).-- -— комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы избежать синтаксических ошибок.
Как это работает на практике
Предположим, на сервере выполняется запрос вида:
SELECT * FROM articles WHERE id = '$id';
Если переменная $id не фильтруется, атакующий может передать:
1)))) AND EXTRACTVALUE(2958,CONCAT(0x7e,((SELECT (ELT(2958=2958,1)))),0x7e))-- -
В результате итоговый SQL-запрос станет:
SELECT * FROM articles WHERE id = '1)))) AND EXTRACTVALUE(2958,CONCAT(0x7e,((SELECT (ELT(2958=2958,1)))),0x7e))-- -';
MySQL попытается выполнить функцию EXTRACTVALUE с аргументом CONCAT(0x7e, (SELECT ...), 0x7e). Поскольку XPath-выражение начинается с символа ~, что недопустимо, СУБД сгенерирует ошибку:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
В сообщении об ошибке появится результат подзапроса — в данном случае «1». В реальной атаке вместо «1» будет, например, версия MySQL или хеш пароля.
Зачем нужны EXTRACTVALUE и ELT?
Функция EXTRACTVALUE появилась в MySQL 5.1. Она предназначена для работы с XML, но из-за особенности вывода ошибок стала популярным инструментом для error-based инъекций. Аналогично используются UPDATEXML и XMLTYPE (в Oracle).
Функция ELT — это сокращение от «Element». Она возвращает N-й элемент из списка строк. В контексте инъекции её применяют для того, чтобы вернуть конкретное значение (например, результат подзапроса) в виде строки, которую затем можно передать в EXTRACTVALUE.
Комбинация ELT(2958=2958,1) — это простейший тест: если выражение истинно, возвращается «1». В более сложных атаках вместо «1» подставляют подзапрос, например: ELT(1,(SELECT version())).
Последствия успешной атаки
Если злоумышленник может выполнить такую инъекцию, он получает доступ к произвольным данным в базе:
- чтение конфиденциальной информации (логины, пароли, персональные данные);
- изменение или удаление записей;
- получение полного контроля над сервером БД в некоторых конфигурациях.
Особенно опасны error-based инъекции тем, что они не требуют слепого перебора — результат приходит сразу в ответе сервера.
Как защититься от error-based SQL-инъекций
Основные меры защиты:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода, и внедрение становится невозможным.
- Экранирование специальных символов. Если prepared statements недоступны, необходимо экранировать все пользовательские данные с помощью функций типа
mysqli_real_escape_string. - Отключение вывода ошибок СУБД на продакшене. Сообщения об ошибках не должны попадать в ответ клиенту — это лишает атакующего обратной связи.
- Ограничение прав пользователя БД. Веб-приложение должно работать под учётной записью с минимально необходимыми привилегиями (только SELECT, INSERT, UPDATE, DELETE для нужных таблиц).
- Регулярное обновление СУБД и фреймворков. В новых версиях MySQL некоторые функции могут быть удалены или изменены, что снижает риск.
- Использование WAF (Web Application Firewall). Современные WAF умеют распознавать сигнатуры error-based инъекций и блокировать подозрительные запросы.
Важно понимать, что безопасность — это комплекс мер, а не одна технология. Регулярный аудит кода и пентесты помогают выявить уязвимости до того, как ими воспользуются злоумышленники.
Заключение
Строка )))) AND EXTRACTVALUE(2958,CONCAT(0x7e,((SELECT (ELT(2958=2958,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для error-based SQL-инъекции в MySQL. Он использует особенности функций EXTRACTVALUE и ELT для извлечения данных через сообщения об ошибках. Понимание механизма таких атак помогает разработчикам и администраторам правильно выстраивать защиту: применять параметризованные запросы, скрывать ошибки и ограничивать права доступа к базе данных.
Если вы обнаружили подобные строки в логах своего сервера — это признак того, что ваше приложение пытались взломать. Немедленно проверьте код на наличие уязвимостей и примите меры по устранению.
Комментарии
—Войдите, чтобы оставить комментарий