Введение

Строка " AND EXTRACTVALUE(4793,CONCAT(0x7e,((SELECT (ELT(4793=4793,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. В данной статье мы подробно разберём, как работает этот payload, какие функции задействованы и как защититься от подобных атак.

Что такое error-based SQL-инъекция?

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет в запрос к базе данных произвольный SQL-код. Error-based инъекция — это техника, при которой атакующий заставляет сервер вернуть сообщение об ошибке, содержащее полезные данные (например, имена таблиц, логины, пароли). В MySQL для этого часто используются функции EXTRACTVALUE и UPDATEXML, которые при некорректных аргументах генерируют ошибку с текстом, включающим переданное значение.

Разбор payload по частям

Рассмотрим строку по частям:

  • " AND ... -- - — типичное начало для внедрения в строковый параметр. Двойная кавычка закрывает строку, AND добавляет логическое условие, а -- - комментирует остаток исходного запроса.
  • EXTRACTVALUE(4793, CONCAT(...)) — функция EXTRACTVALUE извлекает значение из XML-фрагмента. Первый аргумент (4793) — это XML-документ (число, не являющееся корректным XML), второй — XPath-выражение. При некорректном XPath MySQL выдаёт ошибку, содержащую результат вычисления второго аргумента.
  • CONCAT(0x7e, ((SELECT (ELT(4793=4793,1)))), 0x7e) — объединяет символ тильды (0x7e — шестнадцатеричный код символа ~), результат подзапроса и ещё одну тильду. Тильды служат маркерами, чтобы облегчить извлечение данных из сообщения об ошибке.
  • (SELECT (ELT(4793=4793,1))) — подзапрос, возвращающий результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(4793=4793, 1) — условие 4793=4793 всегда истинно (1), поэтому ELT(1, 1) возвращает 1. Это простейший пример; в реальных атаках вместо 1 подставляется подзапрос, извлекающий данные (например, (SELECT password FROM users LIMIT 1)).

Таким образом, при выполнении запроса MySQL попытается вычислить EXTRACTVALUE(4793, CONCAT('~', (SELECT ...), '~')). Поскольку первый аргумент не является корректным XML, будет сгенерирована ошибка вида: XPATH syntax error: '~1~'. В реальной атаке вместо 1 окажется, например, хеш пароля или имя пользователя.

Зачем нужны ELT и CONCAT?

Функция ELT в данном контексте используется для управления возвращаемым значением. В простейшем случае она возвращает константу, но в более сложных payload'ах ELT позволяет реализовать условную логику: если условие истинно, вернуть один результат, иначе — другой. Это даёт возможность проводить слепые инъекции или извлекать данные посимвольно.

CONCAT с тильдами нужен для того, чтобы отделить полезную нагрузку от служебного текста ошибки. Тильда (~) — удобный маркер, так как редко встречается в данных и легко находится в сообщении об ошибке.

Ограничения EXTRACTVALUE

Следует отметить, что длина результата EXTRACTVALUE ограничена 32 символами. Если необходимо извлечь более длинную строку (например, GROUP_CONCAT), используют SUBSTR или LIMIT для посимвольного вывода. Это важно учитывать при анализе подобных payload'ов.

Как защититься от error-based SQL-инъекций?

Основная мера защиты — использование параметризованных запросов (prepared statements) и хранимых процедур. Никогда не конкатенируйте пользовательский ввод в SQL-запрос напрямую. Дополнительно рекомендуется:

  • Экранировать специальные символы с помощью функций типа mysqli_real_escape_string (но это не панацея).
  • Использовать ORM или query builder, которые автоматически применяют параметризацию.
  • Ограничить права пользователя базы данных, чтобы даже при успешной инъекции злоумышленник не получил доступ к критичным данным.
  • Включить логирование ошибок на сервере, но не выводить их пользователю (чтобы не помогать атакующему).
  • Регулярно обновлять СУБД и применять патчи безопасности.

Заключение

Строка " AND EXTRACTVALUE(4793,CONCAT(0x7e,((SELECT (ELT(4793=4793,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции для MySQL. Понимание механики таких атак помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Помните: безопасность должна быть заложена на этапе проектирования, а не добавляться после обнаружения уязвимости.

Источники