Что это за строка?
Строка AND EXTRACTVALUE(9987,CONCAT(0x7e,((SELECT (ELT(9987=9987,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер.
Подобные выражения часто встречаются в отчётах об уязвимостях, в базах данных эксплойтов и в практических заданиях по информационной безопасности (например, на платформах DVWA, SQLZoo). Они позволяют атакующему получить информацию о структуре базы или содержимом таблиц, даже если прямой вывод данных заблокирован.
Разбор по частям
1. AND
Логический оператор, который добавляется к исходному SQL-запросу. Если исходный запрос уже содержит условие WHERE, то инъекция через AND позволяет внедрить дополнительное выражение. Оно должно быть истинным, чтобы запрос вернул результаты, но в error-based инъекциях важнее сама ошибка.
2. EXTRACTVALUE(9987, ...)
Функция MySQL EXTRACTVALUE(XML_frag, XPath_expr) извлекает значение из фрагмента XML по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку XPATH syntax error, в тексте которой отображается переданный фрагмент. Именно это и используется для вывода данных.
Первый аргумент 9987 — произвольное число, оно не играет роли, так как ошибка возникает из-за второго аргумента. В реальных эксплойтах на месте 9987 может быть любое число или даже строка.
3. CONCAT(0x7e, ..., 0x7e)
Функция CONCAT объединяет строки. Здесь 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда используется как разделитель, чтобы в сообщении об ошибке было легко найти выводимые данные. Между двумя тильдами вставляется результат подзапроса.
4. (SELECT (ELT(9987=9987,1)))
Внутренний подзапрос. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае 9987=9987 — это истинное выражение, которое в MySQL преобразуется в 1. Таким образом, ELT(1, 1) вернёт 1. Это простейший случай, демонстрирующий работу механизма. В реальных атаках вместо 1 подставляются имена таблиц, колонок или данные, которые нужно извлечь.
5. -- -
Комментарий. Двойной дефис с пробелом (или -- -) заставляет MySQL игнорировать остаток исходного запроса. Это нужно, чтобы не нарушать синтаксис и обойти возможные проверки.
Как это работает на практике
Предположим, есть уязвимый параметр id в URL: ?id=1. Исходный запрос: SELECT * FROM users WHERE id = 1. Атакующий подставляет:
?id=1 AND EXTRACTVALUE(9987,CONCAT(0x7e,((SELECT (ELT(9987=9987,1)))),0x7e))-- -
Итоговый запрос:
SELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(9987,CONCAT(0x7e,((SELECT (ELT(9987=9987,1)))),0x7e))-- -
MySQL выполнит EXTRACTVALUE с аргументом ~1~. Поскольку ~1~ не является корректным XPath, сервер вернёт ошибку:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
В тексте ошибки мы видим ~1~ — это результат выполнения подзапроса. Если вместо 1 подставить, например, SELECT database(), то в ошибке отобразится имя текущей базы данных.
Зачем это нужно?
Error-based SQL-инъекции — один из способов обхода защиты, когда приложение не выводит данные напрямую, но возвращает сообщения об ошибках СУБД. Это позволяет:
- определить версию MySQL;
- получить имя текущей базы данных;
- извлечь имена таблиц и колонок;
- читать содержимое таблиц (логины, пароли, персональные данные).
В современных веб-приложениях такие ошибки часто скрываются, но в устаревших системах или при неверной конфигурации они всё ещё могут быть видны.
Меры защиты
Чтобы предотвратить подобные атаки, разработчики должны:
- использовать подготовленные выражения (prepared statements) с параметризацией запросов;
- экранировать все пользовательские данные, попадающие в SQL;
- отключить вывод подробных ошибок СУБД в продакшене;
- применять принцип наименьших привилегий для учётной записи базы данных;
- регулярно обновлять СУБД и использовать WAF.
Важно понимать, что EXTRACTVALUE — не единственная функция для error-based инъекций. Аналогично используются UPDATEXML, GTID_SUBSET, EXP и другие. Однако EXTRACTVALUE остаётся популярной из-за простоты и наглядности.
Заключение
Строка AND EXTRACTVALUE(9987,CONCAT(0x7e,((SELECT (ELT(9987=9987,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции в MySQL. Она демонстрирует, как через намеренно вызванную ошибку XPath можно вывести результат подзапроса. Понимание таких конструкций помогает специалистам по безопасности выявлять уязвимости, а разработчикам — писать защищённый код.
Комментарии
—Войдите, чтобы оставить комментарий