Введение

Запрос ') AND EXTRACTVALUE(5837,CONCAT(0x7e,((SELECT (ELT(5837=5837,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) в СУБД MySQL. Подобные конструкции используются злоумышленниками для извлечения данных из базы через сообщения об ошибках. В этой статье мы детально разберём, как работает этот запрос, какие функции задействованы и как защититься от подобных атак.

Что такое error-based SQL-инъекция?

SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в поля ввода, URL-параметры или cookie, чтобы получить доступ к базе данных. Error-based инъекция — это техника, при которой хакер заставляет сервер вернуть сообщение об ошибке, содержащее полезные данные (например, имена таблиц, столбцов или конкретные значения).

В MySQL для этого часто используются функции EXTRACTVALUE и UPDATEXML. Они генерируют ошибку XML-парсинга, если переданный аргумент не является корректным XML. Злоумышленник подставляет в аргумент результат подзапроса, и этот результат «утекает» в тексте ошибки.

Разбор запроса по частям

Давайте разберём конструкцию ') AND EXTRACTVALUE(5837,CONCAT(0x7e,((SELECT (ELT(5837=5837,1)))),0x7e))-- - поэтапно.

1. Закрывающая кавычка и скобка: ')

Символы ') используются для завершения оригинального SQL-запроса, который, вероятно, выглядел как SELECT ... WHERE id = ('...'). Злоумышленник закрывает строку и скобку, чтобы внедрить свой код.

2. AND — логическое условие

Оператор AND позволяет присоединить дополнительное условие к исходному запросу. Если исходный запрос возвращал true, то и внедрённое условие должно быть true, чтобы ошибка не возникла раньше времени. Но в данном случае цель — вызвать ошибку, поэтому результат не важен.

3. Функция EXTRACTVALUE(5837, ...)

EXTRACTVALUE(XML_frag, XPath_expr) — встроенная функция MySQL, которая извлекает значение из XML-фрагмента по XPath-выражению. Если второй аргумент не является корректным XPath, функция возвращает ошибку XPATH syntax error. Именно это и нужно злоумышленнику: в тексте ошибки будет отображён переданный XPath.

Первый аргумент 5837 — произвольное число, которое не влияет на результат, так как оно не является валидным XML.

4. CONCAT(0x7e, ..., 0x7e)

Функция CONCAT объединяет строки. Здесь она склеивает символ ~ (hex 0x7e), результат подзапроса и снова ~. Тильда используется как маркер, чтобы в сообщении об ошибке легко было найти начало и конец извлечённых данных.

5. Подзапрос (SELECT (ELT(5837=5837,1)))

Внутри CONCAT выполняется подзапрос. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь условие 5837=5837 всегда истинно (1), поэтому ELT(1,1) вернёт строку '1'. В реальной атаке вместо 1 подставляется подзапрос, извлекающий данные, например: (SELECT version()) или (SELECT table_name FROM information_schema.tables LIMIT 0,1).

Таким образом, злоумышленник может получить любое значение из базы, если оно поместится в сообщение об ошибке.

6. Комментарий -- -

Двойной дефис с пробелом или другим символом — это комментарий в SQL. Он «отрезает» оставшуюся часть оригинального запроса, чтобы избежать синтаксических ошибок.

Пример работы

Предположим, уязвимый запрос выглядит так:

SELECT * FROM users WHERE id = ('$id')

Если передать $id = ') AND EXTRACTVALUE(5837,CONCAT(0x7e,(SELECT version()),0x7e))-- -, итоговый запрос станет:

SELECT * FROM users WHERE id = ('') AND EXTRACTVALUE(5837,CONCAT(0x7e,(SELECT version()),0x7e))-- -')

MySQL выполнит подзапрос, получит версию сервера, например 5.7.23, и попытается интерпретировать строку ~5.7.23~ как XPath. Возникнет ошибка:

XPATH syntax error: '~5.7.23~'

Злоумышленник увидит версию СУБД в ответе сервера.

Зачем это нужно злоумышленнику?

  • Получение информации о структуре базы данных (имена таблиц, столбцов).
  • Извлечение конфиденциальных данных (пароли, логины, персональные данные).
  • Обход аутентификации и повышение привилегий.
  • Подготовка к дальнейшим атакам, например, к SQL-инъекциям второго порядка.

Как защититься?

Основной способ защиты — использование параметризованных запросов (prepared statements). Они разделяют код и данные, поэтому внедрённый SQL-код не будет интерпретироваться как часть запроса.

Дополнительные меры:

  1. Валидация и фильтрация всех входных данных.
  2. Использование хранимых процедур с параметрами.
  3. Ограничение прав пользователя базы данных (принцип наименьших привилегий).
  4. Регулярное обновление СУБД и веб-приложений.
  5. Применение WAF (Web Application Firewall) для блокировки подозрительных запросов.
  6. Отключение вывода подробных ошибок на продакшене.

Заключение

Конструкция ') AND EXTRACTVALUE(5837,CONCAT(0x7e,((SELECT (ELT(5837=5837,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои системы. Помните: безопасность — это процесс, а не разовое действие.

Источники