Что это за строка?

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

В основе лежит функция EXTRACTVALUE(), которая извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, содержащую часть переданных данных. Это позволяет обойти ограничения и получить содержимое базы.

Разбор по компонентам

Рассмотрим каждый элемент запроса подробно.

  • AND — логический оператор, который добавляется к исходному запросу. Он позволяет внедрить условие, не нарушая синтаксис, если исходный запрос уже содержит WHERE.
  • EXTRACTVALUE(1032, ...) — функция MySQL для работы с XML. Первый аргумент (1032) — это XML-фрагмент (в данном случае просто число, которое не является валидным XML, но это не важно, так как ошибка возникает на втором аргументе). Второй аргумент — XPath-выражение.
  • CONCAT(0x7e, ((SELECT (ELT(1032=1032,1)))), 0x7e) — конкатенация символа тильды (0x7e — это шестнадцатеричное представление символа ~), результата подзапроса и ещё одной тильды. Тильда используется как маркер, чтобы облегчить поиск данных в сообщении об ошибке.
  • SELECT (ELT(1032=1032,1)) — подзапрос, который возвращает результат функции ELT(). ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 1032=1032 — это всегда истинное условие (равенство числа самому себе), которое даёт 1. Таким образом, ELT(1, 1) возвращает строку '1'. Это простейший пример, демонстрирующий работу инъекции. В реальной атаке вместо '1' мог бы быть, например, SELECT password FROM users LIMIT 1.
  • -- - — комментарий, который отсекает оставшуюся часть исходного SQL-запроса. В MySQL комментарий начинается с -- (два дефиса и пробел) или #. Здесь используется -- -, где третий символ — дефис, чтобы гарантировать, что комментарий будет корректно распознан даже в некоторых конфигурациях.

Как это работает

Когда уязвимый запрос, например SELECT * FROM articles WHERE id = 1 AND EXTRACTVALUE(1032,CONCAT(0x7e,((SELECT (ELT(1032=1032,1)))),0x7e))-- -, выполняется, MySQL вычисляет функцию EXTRACTVALUE. Второй аргумент — CONCAT(0x7e, (SELECT (ELT(1032=1032,1))), 0x7e) — возвращает строку ~1~. Эта строка не является корректным XPath-выражением (XPath требует, чтобы выражение начиналось с / или (), поэтому MySQL генерирует ошибку:

XPATH syntax error: '~1~'

В сообщении об ошибке отображается результат подзапроса, заключённый в тильды. Таким образом, атакующий может подставить вместо ELT(1032=1032,1) любой другой подзапрос, например (SELECT version()) или (SELECT password FROM users LIMIT 1), и получить его результат в тексте ошибки.

Это классический пример error-based SQL-инъекции, который работает в MySQL версиях до 5.7. В более новых версиях функция EXTRACTVALUE была удалена, и аналогичные атаки проводятся через UPDATEXML или другие функции.

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

Error-based инъекции позволяют извлекать данные из базы, даже если приложение не выводит результаты запроса на страницу. Вместо этого информация «утекает» через сообщения об ошибках, которые могут быть видны в ответе сервера (если включён режим отладки) или записаны в логи. Это один из самых эффективных методов при пентесте, когда другие техники (UNION, blind) не работают.

Типичные цели: получение версии СУБД, имён таблиц и колонок, логинов и паролей пользователей, другой конфиденциальной информации.

Пример практического использования

Предположим, есть уязвимый параметр id в URL: http://example.com/article.php?id=1. Злоумышленник может подставить:

1 AND EXTRACTVALUE(1032,CONCAT(0x7e,(SELECT version()),0x7e))-- -

В ответе сервера появится ошибка вида: XPATH syntax error: '~5.7.33~', что раскроет версию MySQL. Далее можно извлекать данные посимвольно или сразу целыми строками, используя CONCAT и LIMIT.

Меры защиты

Чтобы предотвратить подобные атаки, необходимо:

  • Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают в тело SQL-запроса.
  • Экранировать специальные символы при невозможности использовать подготовленные выражения. Но этот метод менее надёжен.
  • Отключить вывод ошибок СУБД на продакшене. Ошибки должны логироваться, но не отображаться пользователю.
  • Регулярно обновлять СУБД и применять патчи безопасности.
  • Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.

Важно понимать, что error-based инъекции — лишь один из многих типов SQL-инъекций. Защита должна быть комплексной.

Заключение

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

Источники