Введение
Встречая в логах или в поле ввода подобную строку: ") AND EXTRACTVALUE(1777,CONCAT(0x7e,((SELECT (ELT(1777=1777,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на извлечение данных из базы данных через генерацию ошибок. В данной статье мы подробно разберём каждый элемент этой конструкции, объясним, как она работает, и почему представляет опасность для веб-приложений.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Это становится возможным, когда приложение не проверяет должным образом пользовательский ввод и передаёт его напрямую в SQL-запрос. В результате атакующий может читать, изменять или удалять данные, а в некоторых случаях — выполнять произвольные команды на сервере.
Существует несколько типов SQL-инъекций: union-based, error-based, blind (boolean и time-based). Рассматриваемая строка относится к error-based инъекциям, которые используют сообщения об ошибках СУБД для извлечения информации.
Разбор строки по частям
Давайте детально разберём каждый элемент конструкции:
- "') — закрывающая кавычка и скобка. Они используются для завершения предыдущего выражения в SQL-запросе, чтобы внедрить свой код. В зависимости от контекста могут быть и другие комбинации, например, просто
'или". - AND — логический оператор, который добавляет условие к оригинальному запросу. Если оригинальный запрос был истинным, то добавление
AND ...заставит СУБД вычислить и второе условие. - EXTRACTVALUE(1777, CONCAT(0x7e, ((SELECT (ELT(1777=1777,1)))), 0x7e)) — это функция MySQL, предназначенная для извлечения значения из XML-строки. Однако при неправильном использовании она генерирует ошибку, содержащую переданные аргументы. Это и есть основа error-based инъекции.
- -- - — комментарий, который игнорирует оставшуюся часть оригинального запроса. В MySQL для комментария достаточно
--(с пробелом), а добавленный дефис часто используется для обхода фильтров.
Функция EXTRACTVALUE
Функция EXTRACTVALUE(XML, XPath) в MySQL извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, функция возвращает ошибку, текст которой содержит переданный XPath. Именно это свойство и эксплуатируется: злоумышленник передаёт в качестве XPath строку, содержащую результат подзапроса, и получает его в сообщении об ошибке.
Пример: EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) вызовет ошибку вида XPATH syntax error: '~5.7.29~', где 5.7.29 — версия СУБД.
Функция CONCAT и шестнадцатеричные литералы
CONCAT объединяет строки. В нашем случае она соединяет символ ~ (код 0x7e), результат подзапроса и ещё один ~. Символ ~ используется как маркер, чтобы легко найти извлечённые данные в тексте ошибки. Шестнадцатеричные литералы 0x7e — это просто символ ~ в шестнадцатеричном представлении.
Подзапрос с ELT
ELT(N, str1, str2, ...) — функция, возвращающая N-ю строку из списка. В нашем случае ELT(1777=1777, 1) возвращает 1, так как условие 1777=1777 истинно (равно 1). Это простейший пример, но в реальных атаках вместо 1 может быть подзапрос, извлекающий данные, например, (SELECT table_name FROM information_schema.tables LIMIT 1).
Таким образом, конструкция (SELECT (ELT(1777=1777,1))) возвращает 1, и вся функция EXTRACTVALUE попытается обработать XPath-строку ~1~, что вызовет ошибку с текстом XPATH syntax error: '~1~'. Это демонстрирует, как можно извлечь произвольные данные, подставив вместо 1 нужный подзапрос.
Цель атаки
Основная цель подобных инъекций — получить информацию о структуре базы данных: имена таблиц, столбцов, версию СУБД, учётные данные пользователей и т.д. Error-based метод удобен тем, что результат сразу отображается в ответе сервера (если ошибки не подавляются). Злоумышленник может последовательно извлекать данные посимвольно или целыми строками, используя LIMIT и OFFSET.
В приведённой строке с 1777 и 1777=1777 скорее всего демонстрируется простой пример или тест на уязвимость. Число 1777 может быть случайным или выбранным для обхода сигнатур WAF.
Как защититься?
Для предотвращения SQL-инъекций необходимо:
- Использовать параметризованные запросы (prepared statements) — это самый надёжный способ.
- Применять хранимые процедуры с параметрами.
- Экранировать специальные символы с помощью функций СУБД, например
mysql_real_escape_string. - Ограничить права пользователя базы данных, чтобы даже при успешной инъекции ущерб был минимален.
- Регулярно обновлять СУБД и фреймворки.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Также важно отключать вывод ошибок СУБД в production-окружении, чтобы не давать атакующему лишней информации.
Заключение
Строка ") AND EXTRACTVALUE(1777,CONCAT(0x7e,((SELECT (ELT(1777=1777,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции для MySQL. Она использует функцию EXTRACTVALUE для генерации ошибки, содержащей результат подзапроса. Понимание таких конструкций помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Если вы обнаружили подобные строки в логах, это сигнал о попытке взлома, и следует немедленно проверить безопасность вашего кода.
Комментарии
—Войдите, чтобы оставить комментарий