Что это за строка?
Строка ') AND EXTRACTVALUE(4035,CONCAT(0x7e,((SELECT (ELT(4035=4035,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах сканеров уязвимостей, в логах веб-серверов или в материалах по пентесту.
Внешне это выглядит как бессмысленный набор символов, но на самом деле каждый элемент здесь имеет строгое назначение. Давайте разберём его по частям.
Разбор структуры инъекции
Начнём с начала строки:
')— закрывающая кавычка и скобка. Они нужны, чтобы разорвать оригинальный SQL-запрос, который, вероятно, выглядел какSELECT ... WHERE id = ('...'). Закрывая кавычку и скобку, злоумышленник получает возможность внедрить свой код.AND EXTRACTVALUE(4035,CONCAT(...))— вызов функцииEXTRACTVALUE. Эта функция извлекает значение из XML-строки по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданная строка.CONCAT(0x7e,((SELECT (ELT(4035=4035,1)))),0x7e)— конкатенация символа~(0x7e в шестнадцатеричном виде), результата подзапроса и снова~. Символ~используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке.SELECT (ELT(4035=4035,1))— подзапрос, возвращающий результат выраженияELT(4035=4035,1). ФункцияELTвозвращает N-й элемент из списка. Здесь4035=4035всегда истинно (1), поэтомуELT(1,1)вернёт1. Это простейший случай, демонстрирующий работу инъекции. В реальной атаке вместо этой конструкции подставляется подзапрос, извлекающий нужные данные, например, имя базы данных или хеши паролей.-- -— комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы не возникло синтаксической ошибки.
Как работает error-based инъекция через EXTRACTVALUE
Функция EXTRACTVALUE(XML_document, XPath_expression) в MySQL анализирует XML-документ и возвращает значение узла, соответствующего XPath. Если XPath-выражение содержит недопустимые символы, например, тильду ~, MySQL выдаёт ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении отображается фрагмент переданного XPath, включая результат подзапроса. Таким образом, атакующий может «вытащить» произвольные данные, подставляя их в XPath через CONCAT.
В нашем примере подзапрос возвращает 1, поэтому ошибка будет содержать ~1~. В реальной атаке вместо ELT(4035=4035,1) может быть, например, (SELECT DATABASE()) или (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE()). Тогда в ошибке появятся имена базы данных или таблиц.
Зачем нужна функция ELT?
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В контексте инъекции она используется как «заглушка» или для обхода фильтров. Выражение 4035=4035 всегда истинно и даёт 1, поэтому ELT(1,1) возвращает 1. Это простейший случай, который часто используется в сканерах для проверки наличия уязвимости. Если сервер возвращает ошибку с ~1~, значит, инъекция возможна.
Какие данные можно извлечь?
С помощью этой техники атакующий может получить:
- Имя текущей базы данных (
SELECT DATABASE()) - Версию MySQL (
SELECT VERSION()) - Список таблиц и столбцов из
information_schema - Логины и пароли пользователей, если они хранятся в базе
- Любые другие данные, доступные в рамках прав текущего пользователя БД
Ограничение — длина сообщения об ошибке. Обычно MySQL обрезает его до 64 символов, поэтому для извлечения больших объёмов данных используют посимвольное чтение или функции вроде SUBSTRING.
Пример реального использования
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE username = ('$user')
Если подставить вместо $user нашу строку, запрос станет:
SELECT * FROM users WHERE username = ('') AND EXTRACTVALUE(4035,CONCAT(0x7e,((SELECT (ELT(4035=4035,1)))),0x7e))-- -')
MySQL выполнит подзапрос, получит 1, сформирует XPath ~1~, вызовет ошибку и вернёт её клиенту. В результате в ответе сервера появится сообщение с ~1~.
Как защититься от таких инъекций?
Основной метод — использование параметризованных запросов (prepared statements). В этом случае данные передаются отдельно от SQL-кода, и внедрить что-либо в структуру запроса невозможно.
Дополнительные меры:
- Экранирование специальных символов с помощью
mysqli_real_escape_stringили аналогичных функций. - Валидация и фильтрация входных данных: если поле ожидает число, приводите его к числу.
- Ограничение прав пользователя БД: не давайте приложению доступ к
information_schemaбез необходимости. - Отключение вывода подробных ошибок на продакшене: ошибки должны логироваться, а не показываться пользователю.
- Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.
Важно понимать, что error-based инъекции — лишь один из многих типов SQL-инъекций. Union-based, blind, time-based — все они опасны и требуют комплексной защиты.
Заключение
Строка ') AND EXTRACTVALUE(4035,CONCAT(0x7e,((SELECT (ELT(4035=4035,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проверки и эксплуатации error-based SQL-инъекции в MySQL. Понимание принципов его работы помогает разработчикам и специалистам по безопасности лучше защищать свои приложения.
Комментарии
—Войдите, чтобы оставить комментарий