Введение
Строка %'))) AND EXTRACTVALUE(7491,CONCAT(0x7e,((SELECT (ELT(7491=7491,1)))),0x7e))-- - — это не случайный набор символов, а типичный пример error-based SQL-инъекции для СУБД MySQL. Такие конструкции используются злоумышленниками для проверки уязвимости веб-приложений и извлечения данных из базы через сообщения об ошибках. В этой статье мы разберём каждый элемент запроса, объясним его назначение и последствия.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — один из самых распространённых способов атаки на веб-приложения, работающие с базами данных. Суть метода: злоумышленник внедряет в пользовательский ввод специально сконструированные фрагменты SQL-кода, которые затем выполняются на сервере. Если приложение не фильтрует входные данные, это может привести к утечке конфиденциальной информации, изменению или удалению данных, а в некоторых случаях — к полному захвату сервера.
Error-based инъекция — разновидность, при которой атакующий заставляет базу данных вернуть сообщение об ошибке, содержащее результат выполнения встроенного подзапроса. Это позволяет извлекать данные посимвольно или целыми строками, если приложение отображает ошибки СУБД.
Разбор строки по частям
Рассмотрим каждый компонент запроса %'))) AND EXTRACTVALUE(7491,CONCAT(0x7e,((SELECT (ELT(7491=7491,1)))),0x7e))-- -.
1. Начальные символы %')))
Эта последовательность, скорее всего, является частью исходного запроса, в который внедряется инъекция. Символ % может быть остатком от LIKE-шаблона, а ' — закрывающей кавычкой для строкового литерала. Скобки ))) закрывают ранее открытые конструкции. Всё вместе это подготавливает почву для внедрения произвольного SQL-кода.
2. Оператор AND
Логический оператор AND присоединяет наше условие к существующему выражению WHERE. Если исходный запрос был истинным, то добавление AND ... с ложным условием сделает весь запрос ложным, что можно заметить по изменению поведения приложения. В error-based инъекциях AND часто используется для активации функции, вызывающей ошибку.
3. Функция EXTRACTVALUE(7491, CONCAT(...))
EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Однако в контексте SQL-инъекции она используется иначе: если вторым аргументом передать строку, не являющуюся корректным XPath, MySQL выдаст ошибку, в тексте которой будет содержаться переданная строка. Это и есть основной механизм error-based инъекции.
Первый аргумент 7491 — произвольное число. Оно не имеет значения, так как всё равно вызовет ошибку, но может использоваться для уникализации или обхода простых фильтров.
4. CONCAT(0x7e, ..., 0x7e)
CONCAT объединяет строки. 0x7e — шестнадцатеричное представление символа тильды (~). Тильды служат маркерами, обрамляющими извлекаемые данные, чтобы атакующий мог легко найти их в сообщении об ошибке. Внутри CONCAT находится подзапрос (SELECT (ELT(7491=7491,1))).
5. ELT(7491=7491, 1)
ELT — функция MySQL, возвращающая N-й элемент из списка строк. Синтаксис: ELT(N, str1, str2, ...). Если N=1, возвращается первая строка. В нашем случае выражение 7491=7491 всегда истинно и в числовом контексте даёт 1. Таким образом, ELT(1, 1) возвращает строку '1'. Это простейший случай — фактически проверка, что инъекция выполняется. В реальных атаках вместо 1 мог бы стоять подзапрос, возвращающий имя пользователя, хэш пароля или другую конфиденциальную информацию.
6. Комментарий -- -
Двойной дефис с пробелом (в MySQL требуется пробел после --) превращает всё, что идёт дальше, в комментарий. Это позволяет отсечь остаток оригинального SQL-запроса, который мог бы помешать выполнению инъекции. Символ - в конце — просто дополнительный дефис для надёжности.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE name = '$input';
Если в $input передать нашу строку, запрос станет:
SELECT * FROM users WHERE name = '%'))) AND EXTRACTVALUE(7491,CONCAT(0x7e,((SELECT (ELT(7491=7491,1)))),0x7e))-- -';
MySQL попытается выполнить EXTRACTVALUE с некорректным XPath, и вернёт ошибку вида:
XPATH syntax error: '~1~'
В сообщении об ошибке мы видим ~1~ — это результат выполнения подзапроса, обёрнутый тильдами. Если бы вместо 1 был, например, (SELECT password FROM users LIMIT 1), в ошибке отобразился бы пароль. Так злоумышленник может извлекать данные по частям.
Зачем это нужно злоумышленнику?
Основные цели error-based SQL-инъекций:
- Проверка уязвимости: простые конструкции вроде
ELT(7491=7491,1)позволяют убедиться, что приложение уязвимо и ошибки СУБД отображаются. - Извлечение данных: подставляя в подзапрос имена таблиц, колонок, логины, пароли, можно постепенно выкачать всю базу.
- Обход фильтров: использование функций
EXTRACTVALUE,UPDATEXML,ELTи hex-кодирования помогает обойти наивные системы защиты.
Как защититься?
Лучший способ предотвратить подобные атаки — использовать параметризованные запросы (prepared statements). Они разделяют код и данные, поэтому внедрённый SQL-код никогда не будет выполнен. Дополнительные меры:
- Валидация и фильтрация всех пользовательских вводов.
- Отключение вывода подробных ошибок СУБД в продакшене.
- Применение ORM и современных фреймворков, которые по умолчанию используют параметризацию.
- Регулярное обновление СУБД и веб-приложений.
Заключение
Строка %'))) AND EXTRACTVALUE(7491,CONCAT(0x7e,((SELECT (ELT(7491=7491,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции. Она демонстрирует, как с помощью встроенных функций MySQL можно заставить базу данных выдать данные через сообщение об ошибке. Понимание таких конструкций необходимо разработчикам и специалистам по информационной безопасности для защиты веб-приложений.
Комментарии
—Войдите, чтобы оставить комментарий