Что это за строка?
Строка %') OR EXTRACTVALUE(6404,CONCAT(0x7e,((SELECT (ELT(6404=6404,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы данных через вывод сообщения об ошибке, которое возвращается веб-приложением.
Подобные строки часто встречаются в отчётах сканеров уязвимостей, в логах веб-серверов или в учебных материалах по пентесту. Они не являются обычным пользовательским вводом — это попытка взлома, замаскированная под данные формы или параметра URL.
Разбор по частям
Давайте разберём строку на составляющие, чтобы понять, как она работает.
1. Начало: %')
Символ % — это URL-кодированный пробел (или просто часть исходного значения, например, в поисковом запросе). Далее идут закрывающая кавычка ' и закрывающая скобка ). Это попытка «закрыть» ранее открытые кавычки и скобки в оригинальном SQL-запросе, чтобы внедрить свой код. Предполагается, что уязвимый параметр вставляется в запрос внутри кавычек и скобок, например: WHERE id = ('значение').
2. OR
Логический оператор OR делает условие всегда истинным (если правая часть вернёт истину), что позволяет обойти аутентификацию или получить все записи. В данном случае он также служит для внедрения функции, которая вызовет ошибку.
3. EXTRACTVALUE(6404,CONCAT(...))
EXTRACTVALUE — это встроенная функция MySQL (до версии 8.0.17), предназначенная для извлечения значения из XML-строки. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение некорректно, функция генерирует ошибку, в тексте которой выводится переданное значение.
Первый аргумент 6404 — это произвольное число, которое не является валидным XML. Второй аргумент — результат CONCAT, который и попадёт в сообщение об ошибке.
4. CONCAT(0x7e,((SELECT (ELT(6404=6404,1)))),0x7e)
CONCAT объединяет несколько строк. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы облегчить поиск выводимых данных в тексте ошибки.
Внутри CONCAT находится подзапрос (SELECT (ELT(6404=6404,1))). ELT — функция, возвращающая N-й элемент из списка. Здесь 6404=6404 — всегда истинное условие (равно 1), поэтому ELT(1,1) вернёт 1. Это простейшая проверка работоспособности инъекции. В реальной атаке вместо 1 подставляется подзапрос, извлекающий данные, например, имя пользователя или хеш пароля.
5. Завершение: -- -
-- — это комментарий в SQL. Всё, что идёт после него, игнорируется базой данных. Пробел после -- и дефис добавлены для надёжности, чтобы комментарий точно сработал в разных СУБД и настройках.
Как это работает на практике
Предположим, есть уязвимый скрипт, который выполняет запрос:
SELECT * FROM users WHERE username = '$user' AND password = '$pass';
Если в параметр $user подставить нашу строку, запрос станет таким:
SELECT * FROM users WHERE username = '%') OR EXTRACTVALUE(6404,CONCAT(0x7e,((SELECT (ELT(6404=6404,1)))),0x7e))-- -' AND password = '...';
База данных попытается выполнить EXTRACTVALUE с некорректным XML (число 6404), что вызовет ошибку. В тексте ошибки будет что-то вроде:
XPATH syntax error: '~1~'
Таким образом, атакующий видит результат выполнения вложенного запроса. Меняя ELT(6404=6404,1) на подзапрос, например (SELECT password FROM users LIMIT 1), он может извлечь пароли.
Зачем это нужно злоумышленникам?
Error-based инъекции — мощный инструмент, когда приложение не выводит данные напрямую, но показывает сообщения об ошибках базы данных. Это позволяет поэтапно извлекать информацию: имена таблиц, столбцов, содержимое записей. В отличие от UNION-инъекций, здесь не нужно подбирать количество столбцов, но требуется, чтобы ошибки отображались пользователю.
Как защититься?
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода, и внедрение становится невозможным.
- Экранируйте специальные символы. Если параметризация недоступна, применяйте функции экранирования, например
mysqli_real_escape_string. - Отключите вывод ошибок БД на продакшене. Сообщения об ошибках не должны попадать к пользователю — это скрывает результаты инъекций.
- Регулярно обновляйте СУБД. В MySQL 8.0.17 и новее функции
EXTRACTVALUEиUPDATEXMLудалены, что затрудняет классические error-based атаки, но не отменяет необходимости общей защиты. - Используйте WAF (Web Application Firewall). Он может блокировать подозрительные строки, содержащие
EXTRACTVALUE,CONCATи другие характерные конструкции.
Распространённые вариации
Вместо EXTRACTVALUE злоумышленники могут использовать UPDATEXML, GTID_SUBSET, EXP (в MySQL 5.7) или функции других СУБД: CAST в PostgreSQL, UTL_INADDR в Oracle. Синтаксис может отличаться, но принцип один: вызвать ошибку, содержащую данные.
Строка %') OR EXTRACTVALUE(6404,CONCAT(0x7e,((SELECT (ELT(6404=6404,1)))),0x7e))-- - — это «учебный» пример, где вместо реального подзапроса стоит заглушка ELT(6404=6404,1). В реальной атаке на её месте был бы код для кражи информации.
Вывод
Если вы встретили такую строку в логах или в поле ввода — это попытка взлома. Не паникуйте, но проверьте, защищено ли ваше приложение. Для разработчиков это напоминание о важности параметризованных запросов и скрытия ошибок базы данных. Для обычных пользователей — повод убедиться, что сайт, где вы вводите данные, использует HTTPS и современные методы защиты.
Комментарии
—Войдите, чтобы оставить комментарий