Введение
Встречая в логах веб-сервера или в поле ввода подобную строку: %' OR EXTRACTVALUE(4462,CONCAT(0x7e,((SELECT (ELT(4462=4462,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Перед вами классический пример SQL-инъекции (SQL injection), нацеленной на извлечение данных из базы данных через ошибки. Подобные запросы часто появляются при сканировании уязвимостей или попытках взлома сайтов. В этой статье мы подробно разберём, что означает каждый элемент этой конструкции, зачем злоумышленники используют EXTRACTVALUE, и как защитить свой сайт от таких атак.
Что такое SQL-инъекция?
SQL-инъекция — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет произвольный SQL-код в запрос к базе данных. Это становится возможным, если приложение не проверяет должным образом пользовательский ввод и передаёт его напрямую в SQL-запрос. Успешная инъекция может привести к утечке конфиденциальных данных, модификации или удалению информации, а в некоторых случаях — к полному контролю над сервером.
Существует несколько типов SQL-инъекций: основанные на ошибках (error-based), на времени (time-based), на логических выражениях (boolean-based) и другие. Рассматриваемый запрос относится к error-based инъекциям, так как использует функцию EXTRACTVALUE, которая при некорректном XPath-выражении генерирует ошибку, содержащую полезные для атакующего данные.
Разбор строки инъекции
Давайте детально разберём каждый элемент запроса %' OR EXTRACTVALUE(4462,CONCAT(0x7e,((SELECT (ELT(4462=4462,1)))),0x7e))-- -.
1. Начало: %' OR
Символ % часто используется в SQL LIKE-запросах как подстановочный знак. Злоумышленник добавляет ' OR, чтобы разорвать исходный запрос и добавить своё условие. Если исходный запрос был, например, SELECT * FROM users WHERE name LIKE '%...%', то после подстановки получается SELECT * FROM users WHERE name LIKE '%%' OR EXTRACTVALUE(...) -- -'. Это позволяет обойти проверку и выполнить внедрённую функцию.
2. Функция EXTRACTVALUE
EXTRACTVALUE — это функция в MySQL (и MariaDB), предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_fragment, XPath_expression). Если XPath-выражение синтаксически неверно, функция возвращает ошибку, в тексте которой содержится переданное выражение. Именно это свойство и эксплуатируют злоумышленники: они передают в XPath специально сформированную строку, чтобы в сообщении об ошибке увидеть результат выполнения вложенного SQL-запроса.
3. CONCAT и 0x7e
CONCAT(0x7e, ..., 0x7e) объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда добавляется в начало и конец, чтобы отделить полезные данные от служебного текста ошибки. XPath не допускает использования символа ~ в именах, поэтому при попытке разбора выражения с тильдой возникает ошибка, и MySQL выводит сообщение вида: XPATH syntax error: '~<данные>~'.
4. Вложенный SELECT и ELT
(SELECT (ELT(4462=4462,1))) — это подзапрос, который возвращает результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(4462=4462,1): условие 4462=4462 всегда истинно (равно 1), поэтому ELT возвращает первую строку — 1. Это простейший пример. В реальных атаках вместо 1 может быть вызов DATABASE(), USER(), VERSION() или подзапрос, извлекающий имена таблиц и столбцов. Например, чтобы узнать имя текущей базы данных, используют: EXTRACTVALUE(1, CONCAT(0x7e, (SELECT DATABASE()), 0x7e)).
5. Комментарий -- -
Двойной дефис -- в SQL означает начало комментария. Всё, что идёт после него, игнорируется базой данных. Пробел после -- и ещё один дефис (-- -) используются для обхода некоторых парсеров, которые требуют наличия пробела после --. Это позволяет «отрезать» остаток оригинального запроса, чтобы синтаксис оставался корректным.
Зачем злоумышленники используют EXTRACTVALUE?
Основная цель — получить информацию из базы данных, когда другие методы (например, UNION-инъекции) не работают. Error-based инъекции через EXTRACTVALUE (или аналогичную функцию UPDATEXML) позволяют извлекать данные посимвольно или целыми строками, если приложение выводит сообщения об ошибках базы данных на экран. Даже если вывод ошибок отключён, атакующий может использовать слепые методы, но EXTRACTVALUE чаще применяется именно для быстрого получения данных через ошибки.
Типичные сценарии:
- Получение имени базы данных, пользователя, версии СУБД.
- Извлечение имён таблиц и столбцов из
information_schema. - Кража логинов, паролей, персональных данных пользователей.
- Получение хешей паролей администраторов для дальнейшего взлома.
Как распознать попытку инъекции
Признаки атаки можно заметить в логах веб-сервера (access.log) или в логах приложений. Ищите строки, содержащие:
EXTRACTVALUE,UPDATEXML,CONCAT,0x7e.- Комбинации
' OR,-- -,#в параметрах URL или формах. - Необычные XPath-выражения с тильдой.
- Множественные запросы с разными числами в EXTRACTVALUE (перебор).
Если вы обнаружили такие строки, это сигнал о том, что ваш сайт пытаются взломать. Важно немедленно проверить уязвимости и принять меры.
Как защититься от SQL-инъекций
Лучший способ защиты — использовать параметризованные запросы (prepared statements) и хранимые процедуры. Это исключает возможность внедрения SQL-кода, так как данные передаются отдельно от самого запроса. Дополнительные меры:
- Экранирование специальных символов с помощью функций драйвера БД (например,
mysqli_real_escape_string). - Валидация и фильтрация входных данных на стороне сервера: проверка типов, длины, допустимых символов.
- Ограничение прав пользователя БД: не давайте приложению прав на удаление таблиц или доступ к системным таблицам без необходимости.
- Отключение вывода ошибок БД на продакшене: ошибки должны логироваться, но не показываться пользователю.
- Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.
- Регулярное обновление CMS, фреймворков и библиотек.
Также рекомендуется проводить аудит безопасности и тестирование на проникновение.
Пример безопасного кода на PHP
Вместо уязвимого кода:
$query = "SELECT * FROM users WHERE name LIKE '%" . $_GET['name'] . "%'";
Используйте подготовленные выражения:
$stmt = $pdo->prepare("SELECT * FROM users WHERE name LIKE :name");
$stmt->execute(['name' => '%' . $_GET['name'] . '%']);
Это полностью исключает возможность SQL-инъекции.
Заключение
Строка %' OR EXTRACTVALUE(4462,CONCAT(0x7e,((SELECT (ELT(4462=4462,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, использующая функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. Понимание механизмов таких атак помогает разработчикам и администраторам своевременно обнаруживать и предотвращать угрозы. Помните: безопасность веб-приложений — это непрерывный процесс, и использование современных методов защиты обязательно.
Комментарии
—Войдите, чтобы оставить комментарий