Что это за строка?
Строка %" AND EXTRACTVALUE(8635,CONCAT(0x7e,((SELECT (ELT(8635=8635,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах пентестеров и в логах веб-серверов, когда злоумышленник пытается проэксплуатировать уязвимость.
Внешне это выглядит как случайный набор символов, но на самом деле каждый элемент здесь имеет строгое назначение. Давайте разберём по частям.
Анатомия инъекции
1. Начало: %"
Символ % — это подстановочный знак в SQL-запросах (например, в LIKE). Кавычка " закрывает строковый литерал в оригинальном запросе, после чего злоумышленник добавляет AND .... Таким образом, исходный запрос, скорее всего, выглядел как SELECT ... WHERE name LIKE '%" — и инъекция ломает его структуру.
2. Функция EXTRACTVALUE(8635, CONCAT(...))
EXTRACTVALUE — это встроенная функция MySQL для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_документ, XPath_выражение).
Однако при передаче некорректного XPath-выражения MySQL генерирует ошибку, в тексте которой отображается переданное выражение. Это и есть основа error-based инъекции: злоумышленник может поместить в XPath результат подзапроса, и он окажется в сообщении об ошибке.
3. CONCAT(0x7e, ((SELECT ...)), 0x7e)
CONCAT объединяет строки. 0x7e — это шестнадцатеричный код символа ~ (тильда). Тильда используется как маркер, чтобы в выводе ошибки легко было найти границы извлечённых данных.
Внутри CONCAT находится подзапрос (SELECT (ELT(8635=8635,1))).
4. ELT(8635=8635, 1)
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 8635=8635 — это логическое выражение, которое всегда истинно (1). Таким образом, ELT(1, 1) вернёт строку '1'. В реальной атаке вместо этого подзапроса был бы запрос к базе, например, SELECT version() или SELECT password FROM users LIMIT 1. Но в данном примере используется безобидная константа, чтобы продемонстрировать работу механизма.
5. Комментарий -- -
Двойной дефис с пробелом (или -- -) — это комментарий в SQL. Он отсекает оставшуюся часть оригинального запроса, чтобы синтаксис был корректным.
Как это работает на практике?
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE title LIKE '%" AND EXTRACTVALUE(8635,CONCAT(0x7e,((SELECT (ELT(8635=8635,1)))),0x7e))-- -%'
После подстановки получается:
SELECT * FROM articles WHERE title LIKE '%" AND EXTRACTVALUE(8635,CONCAT(0x7e,((SELECT (ELT(8635=8635,1)))),0x7e))-- -%'
MySQL выполняет функцию EXTRACTVALUE, которая пытается разобрать XPath-выражение ~1~. Поскольку это невалидный XPath, возникает ошибка вида:
XPATH syntax error: '~1~'
В сообщении об ошибке мы видим ~1~ — это и есть результат подзапроса. Если бы вместо 1 стоял, например, (SELECT database()), мы бы увидели имя текущей базы данных.
Зачем это нужно злоумышленнику?
Error-based SQL-инъекция позволяет извлекать данные из базы посимвольно или целыми строками, используя вывод ошибок. Это один из самых быстрых и удобных методов, если приложение отображает ошибки СУБД на странице. С помощью EXTRACTVALUE и аналогичных функций (UPDATEXML, GTID_SUBSET и др.) можно получить:
- версию MySQL;
- имя текущего пользователя базы;
- названия таблиц и столбцов;
- логины и пароли пользователей;
- любые другие данные, доступные в рамках прав соединения.
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements). Это самый надёжный способ, так как данные не смешиваются с кодом SQL.
- Отключить вывод ошибок СУБД на продакшене. Ошибки должны логироваться, но не показываться пользователю.
- Проводить валидацию и экранирование входных данных. Но это менее надёжно, чем подготовленные выражения.
- Ограничить права пользователя базы данных. Не давайте приложению прав на чтение системных таблиц без необходимости.
- Использовать WAF (Web Application Firewall). Он может блокировать подозрительные запросы, содержащие
EXTRACTVALUEи другие опасные функции.
Вывод
Строка %" AND EXTRACTVALUE(8635,CONCAT(0x7e,((SELECT (ELT(8635=8635,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции. Она демонстрирует, как злоумышленник может использовать функцию EXTRACTVALUE для вывода данных через сообщения об ошибках. Понимание таких атак помогает разработчикам и администраторам лучше защищать свои приложения.
Комментарии
—Войдите, чтобы оставить комментарий