Введение
Встречая в логах веб-сервера или в поле ввода подобную строку: AND EXTRACTVALUE(6050,CONCAT(0x7e,((SELECT (ELT(6050=6050,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на извлечение данных из базы данных MySQL через механизм ошибок. В данной статье мы детально разберём каждую часть этого запроса, объясним, как он работает, какую информацию позволяет получить злоумышленнику и, главное, как защититься от подобных атак.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — это один из самых распространённых способов взлома веб-приложений, при котором злоумышленник внедряет произвольный SQL-код в запрос к базе данных. Это становится возможным, когда приложение небезопасно обрабатывает пользовательский ввод, например, подставляет его напрямую в SQL-запрос без экранирования или параметризации. Цель инъекции — обойти аутентификацию, украсть, изменить или удалить данные, а иногда и получить полный контроль над сервером.
Существует несколько типов SQL-инъекций: UNION-based, error-based, blind (слепая), time-based и другие. Рассматриваемая строка относится к error-based инъекциям, когда злоумышленник намеренно вызывает ошибку базы данных, чтобы в её тексте получить полезную информацию.
Разбор строки AND EXTRACTVALUE(6050,CONCAT(0x7e,((SELECT (ELT(6050=6050,1)))),0x7e))-- -
Давайте разберём этот запрос по частям.
1. AND
Оператор AND используется для добавления условия к существующему SQL-запросу. Например, если исходный запрос был SELECT * FROM users WHERE id = 1, то после внедрения он может стать SELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(...). Это позволяет выполнить внедрённую функцию только в том случае, если исходное условие истинно, что не нарушает логику запроса, но добавляет выполнение вредоносного кода.
2. EXTRACTVALUE(6050, CONCAT(...))
EXTRACTVALUE() — это встроенная функция MySQL (до версии 8.0.17), предназначенная для извлечения значения из XML-документа по указанному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Если XPath-выражение некорректно, функция генерирует ошибку, текст которой содержит переданное выражение. Именно это свойство и эксплуатируется злоумышленниками: они передают в качестве XPath строку, содержащую результат подзапроса, и ошибка возвращает эти данные в ответе сервера.
В нашем случае первым аргументом идёт число 6050 — это просто произвольное число, которое не несёт смысловой нагрузки (может быть любым). Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(6050=6050,1)))), 0x7e).
3. CONCAT(0x7e, ..., 0x7e)
Функция CONCAT() объединяет строки. Здесь она склеивает символ 0x7e (это шестнадцатеричное представление символа ~ — тильда), затем результат подзапроса и снова тильду. Тильда используется как маркер, чтобы в сообщении об ошибке легко было найти извлечённые данные: они будут заключены между двумя тильдами. Например, ошибка может выглядеть так: XPATH syntax error: '~1~'.
4. (SELECT (ELT(6050=6050,1)))
Это подзапрос, который возвращает значение. ELT() — функция MySQL, возвращающая N-й элемент из списка строк: ELT(N, str1, str2, ...). В данном случае N — это результат сравнения 6050=6050, которое всегда истинно (1), а список состоит из одного элемента 1. Таким образом, ELT(1, 1) вернёт строку '1'. Фактически это простейший тестовый подзапрос, который всегда возвращает 1. В реальной атаке вместо него был бы подзапрос, извлекающий, например, имя пользователя или хеш пароля из таблицы users.
5. -- -
Двойной дефис -- в SQL обозначает начало комментария. Всё, что идёт после него, игнорируется базой данных. Это нужно, чтобы «отрезать» оставшуюся часть оригинального запроса, которая могла бы помешать выполнению инъекции. Пробел после -- и дефис в конце — это стандартное оформление комментария в MySQL, где требуется пробел после двух дефисов.
Как работает атака целиком
Предположим, веб-приложение выполняет запрос:SELECT * FROM products WHERE id = 1 AND EXTRACTVALUE(6050,CONCAT(0x7e,((SELECT (ELT(6050=6050,1)))),0x7e))-- -
База данных выполняет:
- Вычисляет
6050=6050→ истина (1). - Вычисляет
ELT(1,1)→ строка '1'. - Формирует строку
CONCAT('~', '1', '~')→ '~1~'. - Передаёт '~1~' в
EXTRACTVALUE(6050, '~1~'). - Поскольку '~1~' не является корректным XPath, MySQL генерирует ошибку:
XPATH syntax error: '~1~'. - Эта ошибка возвращается в ответе приложения (если вывод ошибок не отключён).
Злоумышленник видит в ответе '~1~' и понимает, что инъекция работает. Далее он может заменить ELT(6050=6050,1) на подзапрос, извлекающий нужные данные, например: (SELECT password FROM users LIMIT 1). Тогда в ошибке отобразится хеш пароля.
Чем опасна такая инъекция?
Error-based SQL-инъекции позволяют злоумышленнику:
- Получить доступ к содержимому базы данных (логины, пароли, персональные данные).
- Обойти аутентификацию и войти в систему под администратором.
- Изменить или удалить данные.
- В некоторых случаях — выполнить произвольные команды на сервере (при наличии соответствующих привилегий).
Особенность error-based метода в том, что он не требует слепого перебора и даёт быстрый результат, если приложение выводит ошибки базы данных пользователю.
Как защититься от SQL-инъекций?
Основные меры защиты:
- Параметризованные запросы (prepared statements) — самый надёжный способ. При использовании параметров пользовательский ввод никогда не интерпретируется как SQL-код.
- Экранирование специальных символов — если параметризация невозможна, применяйте функции экранирования, предоставляемые драйвером БД.
- Отключение вывода ошибок БД — не показывайте пользователям сообщения об ошибках базы данных. Логируйте их на сервере.
- Ограничение привилегий пользователя БД — учётная запись, от имени которой работает приложение, должна иметь минимально необходимые права.
- Использование WAF (Web Application Firewall) — помогает блокировать известные шаблоны атак, но не является панацеей.
- Регулярное обновление СУБД — в MySQL 8.0.17 и выше функция
EXTRACTVALUE()удалена, что снижает риск подобных атак на новых версиях.
Заключение
Строка AND EXTRACTVALUE(6050,CONCAT(0x7e,((SELECT (ELT(6050=6050,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проведения error-based SQL-инъекции в MySQL. Понимание принципов его работы помогает разработчикам и администраторам лучше защищать свои приложения. Если вы обнаружили подобные строки в логах, это сигнал о попытке взлома, и следует немедленно проверить безопасность кода и базы данных.
Комментарии
—Войдите, чтобы оставить комментарий