Что такое error-based SQL-инъекция?
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения. Злоумышленник встраивает в пользовательский ввод специальные конструкции, которые меняют логику SQL-запроса. Существует несколько разновидностей: union-based, blind, time-based и error-based. Последняя, о которой пойдёт речь, основана на принудительном вызове ошибки базы данных, в тексте которой «протаскиваются» нужные хакеру данные.
Запрос из вашего вопроса — AND EXTRACTVALUE(8792,CONCAT(0x7e,((SELECT (ELT(8792=8792,1)))),0x7e))-- - — это классический пример error-based инъекции для СУБД MySQL. Такие конструкции используются для извлечения информации из базы, когда прямой вывод данных невозможен.
Разбор конструкции по частям
EXTRACTVALUE
Функция EXTRACTVALUE(XML_document, XPath_expression) появилась в MySQL 5.1. Она извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически некорректно, MySQL возвращает ошибку XPATH syntax error, в тексте которой отображается переданный фрагмент. Именно это свойство и эксплуатируют злоумышленники.
CONCAT и 0x7e
CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа «~» (тильда). Тильда используется как маркер-разделитель: она недопустима в XPath-выражении, поэтому гарантированно вызывает ошибку, а её обрамление позволяет легко найти внедрённые данные в сообщении об ошибке.
SELECT и ELT
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(8792=8792,1) вернёт «1», так как условие 8792=8792 истинно. На практике вместо этого подзапроса подставляют реальный запрос к таблицам information_schema или пользовательским данным, например: SELECT table_name FROM information_schema.tables LIMIT 1.
Комментарий -- -
Двойной дефис с пробелом — это комментарий в MySQL. Он «отрезает» остаток оригинального запроса, чтобы синтаксис оставался корректным.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = '$id';
Если передать в параметр $id строку 1 AND EXTRACTVALUE(8792,CONCAT(0x7e,(SELECT version()),0x7e))-- -, то база выполнит:
SELECT * FROM users WHERE id = '1' AND EXTRACTVALUE(8792,CONCAT(0x7e,(SELECT version()),0x7e))-- -';
В ответе сервер вернёт ошибку вида: XPATH syntax error: '~5.7.34~'. Таким образом, атакующий узнаёт версию СУБД. Аналогично можно извлекать имена таблиц, колонок и даже хеши паролей.
Чем опасна такая инъекция?
- Позволяет получить полный доступ к структуре базы данных.
- Даёт возможность читать конфиденциальную информацию: логины, пароли, персональные данные.
- В некоторых конфигурациях (при наличии прав FILE) может привести к записи файлов на сервер и выполнению кода.
- Ошибки, возвращаемые СУБД, помогают обойти «слепые» сценарии и ускорить эксплуатацию.
Как защититься от error-based SQL-инъекций
1. Подготовленные выражения (prepared statements)
Самый надёжный способ — использовать параметризованные запросы. Данные передаются отдельно от SQL-кода и не могут изменить его структуру. Это работает в PDO (PHP), JDBC (Java), psycopg2 (Python) и других библиотеках.
2. Экранирование и валидация
Если по каким-то причинам prepared statements недоступны, необходимо строго валидировать входные данные: приводить к ожидаемому типу, проверять по белому списку, использовать функции экранирования (например, mysqli_real_escape_string).
3. Отключение подробных сообщений об ошибках
В production-окружении никогда не показывайте пользователю текст ошибок СУБД. Это лишает атакующего обратной связи и делает error-based инъекции бесполезными.
4. Принцип наименьших привилегий
Учётная запись, от имени которой работает приложение, должна иметь только необходимые права. Запретите доступ к information_schema и mysql, если он не нужен.
5. Регулярные обновления и WAF
Своевременно обновляйте СУБД и фреймворки. Веб-приложения-экраны (WAF) могут блокировать известные сигнатуры атак, но не заменяют правильного кодирования.
Заключение
Конструкция AND EXTRACTVALUE(8792,CONCAT(0x7e,((SELECT (ELT(8792=8792,1)))),0x7e))-- - — это не безобидный набор символов, а рабочий инструмент хакера. Понимание механики таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости. Главный вывод: используйте параметризованные запросы, скрывайте ошибки и не доверяйте пользовательскому вводу.
Комментарии
—Войдите, чтобы оставить комментарий