Введение
Строка ") AND EXTRACTVALUE(8202,CONCAT(0x7e,((SELECT (ELT(8202=8202,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Такие конструкции используются пентестерами и злоумышленниками для извлечения данных из базы через сообщения об ошибках. В этой статье мы детально разберём, как она работает, какие функции задействованы и как защититься от подобных атак.
Что такое error-based SQL-инъекция?
SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в параметры запроса, которые недостаточно проверяются. Error-based инъекция — это техника, при которой атакующий заставляет базу данных вернуть данные в тексте ошибки. В MySQL для этого часто используют функции EXTRACTVALUE и UPDATEXML.
Функция EXTRACTVALUE
EXTRACTVALUE(XML_frag, XPath_expr) извлекает значение из фрагмента XML по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в которой отображается переданный аргумент. Это и позволяет вытащить произвольные данные.
Разбор строки по частям
Рассмотрим запрос ") AND EXTRACTVALUE(8202,CONCAT(0x7e,((SELECT (ELT(8202=8202,1)))),0x7e))-- - поэтапно.
- ") — закрывает ранее открытую скобку и строковый литерал в уязвимом запросе. Это необходимо, чтобы внедряемый код стал частью SQL-выражения.
- AND — логический оператор, присоединяющий наше условие к оригинальному запросу.
- EXTRACTVALUE(8202, ...) — первый аргумент 8202 — это произвольное число, которое будет использоваться как XML-фрагмент. На самом деле важен второй аргумент.
- CONCAT(0x7e, ((SELECT (ELT(8202=8202,1)))), 0x7e) — конкатенация тильды (0x7e), результата подзапроса и ещё одной тильды.
- SELECT (ELT(8202=8202,1)) — подзапрос, возвращающий 1, если условие 8202=8202 истинно. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь список состоит из одного элемента «1».
- -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса.
В результате MySQL пытается выполнить XPath-выражение ~1~, что вызывает ошибку вида: XPATH syntax error: '~1~'. Вместо «1» может быть любой другой подзапрос, например, извлечение имени пользователя или хэша пароля.
Зачем это нужно атакующему?
Основная цель — получить данные из базы. Подставляя в ELT или вместо него другие подзапросы, злоумышленник может посимвольно извлекать информацию: имена таблиц, колонок, логины, пароли. Например, конструкция SELECT table_name FROM information_schema.tables LIMIT 0,1 позволит узнать первую таблицу в базе.
Подобные инъекции часто встречаются в задачах на CTF и в отчётах о пентестах. Они опасны тем, что не требуют вывода данных на экран — достаточно, чтобы ошибка отображалась в ответе сервера.
Пример эксплуатации
Предположим, уязвимый запрос выглядит так:
$query = "SELECT * FROM articles WHERE id = '$id'";
Если передать $id = '") AND EXTRACTVALUE(8202,CONCAT(0x7e,(SELECT database()),0x7e))-- -', то итоговый SQL станет:
SELECT * FROM articles WHERE id = '") AND EXTRACTVALUE(8202,CONCAT(0x7e,(SELECT database()),0x7e))-- -'
MySQL вернёт ошибку с именем текущей базы данных. Аналогично можно извлечь версию, пользователя и другие данные.
Как защититься от error-based SQL-инъекций?
- Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода и не интерпретируются как часть инструкции.
- Экранируйте специальные символы. Если prepared statements недоступны, применяйте функции экранирования, например
mysqli_real_escape_string. - Ограничьте права пользователя БД. Веб-приложение должно работать с минимально необходимыми привилегиями — обычно только SELECT, INSERT, UPDATE, DELETE для конкретных таблиц.
- Отключите вывод ошибок MySQL в production. Сообщения об ошибках не должны попадать в ответ сервера. Логируйте их, но не показывайте пользователю.
- Используйте WAF. Веб-application firewall может блокировать подозрительные конструкции, такие как EXTRACTVALUE или UPDATEXML.
Заключение
Строка ") AND EXTRACTVALUE(8202,CONCAT(0x7e,((SELECT (ELT(8202=8202,1)))),0x7e))-- - — это компактный и эффективный инструмент для проведения error-based SQL-инъекции в MySQL. Понимание её работы помогает специалистам по безопасности выявлять уязвимости, а разработчикам — писать защищённый код. Никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий