Что это за строка?
Строка %' OR EXTRACTVALUE(2016,CONCAT(0x7e,((SELECT (ELT(2016=2016,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер базы данных.
Подобные строки часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) и в учебных материалах по информационной безопасности. Они не являются обычным пользовательским вводом, а представляют собой попытку атаки на веб-приложение, которое небезопасно обрабатывает параметры запроса.
Разбор конструкции по частям
Чтобы понять, как работает этот эксплойт, разберём его на составляющие.
1. Начало: %'
Символ % часто используется как подстановочный знак в SQL-запросах с LIKE. Апостроф ' закрывает строковый литерал в исходном запросе. Вместе %' — это попытка «сломать» синтаксис запроса, чтобы внедрить собственный код. Например, если приложение выполняет запрос вида:
SELECT * FROM users WHERE name LIKE '%[ввод]%'то при подстановке %' запрос становится синтаксически незавершённым, и злоумышленник может добавить свою логику.
2. Оператор OR
Логическое «ИЛИ» позволяет обойти условия фильтрации. Если хотя бы одна часть выражения истинна, запрос вернёт данные. В error-based инъекциях OR часто используется для вызова функции, которая гарантированно выполнится и вызовет ошибку с полезной нагрузкой.
3. Функция EXTRACTVALUE(2016, CONCAT(...))
EXTRACTVALUE() — это функция MySQL для работы с XML. Она извлекает значение из XML-строки по указанному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression).
В нашем случае первый аргумент — 2016 (число, которое не является корректным XML), второй — результат CONCAT(0x7e, ((SELECT (ELT(2016=2016,1)))), 0x7e).
Когда EXTRACTVALUE получает некорректный XML, MySQL генерирует ошибку и включает в сообщение часть переданного XPath-выражения. Это позволяет злоумышленнику «вытащить» данные через текст ошибки.
4. CONCAT(0x7e, ..., 0x7e)
CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда используется как маркер-разделитель, чтобы в сообщении об ошибке было легко найти внедрённые данные. Конструкция 0x7e ... 0x7e обрамляет полезную нагрузку.
5. Подзапрос (SELECT (ELT(2016=2016,1)))
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Если N=1, возвращается первая строка. Здесь 2016=2016 — всегда истинное условие, которое возвращает 1 (в MySQL TRUE = 1). Таким образом, ELT(1, 1) вернёт 1.
В реальной атаке вместо 1 подставляется подзапрос, извлекающий данные, например: (SELECT password FROM users LIMIT 1). Но в данном примере показан «безопасный» шаблон, который просто возвращает число 1 — вероятно, для тестирования уязвимости.
6. Комментарий -- -
Двойной дефис с пробелом (или -- -) в MySQL означает начало комментария до конца строки. Это позволяет «отрезать» оставшуюся часть оригинального запроса, чтобы синтаксис стал корректным.
Как работает error-based SQL-инъекция
Error-based инъекция — это метод, при котором злоумышленник заставляет базу данных вернуть данные в тексте ошибки. MySQL при неправильном использовании функций, таких как EXTRACTVALUE или UPDATEXML, включает в сообщение об ошибке фрагмент переданного XPath. Это позволяет посимвольно извлекать содержимое базы.
Пример реальной атаки: вместо ELT(2016=2016,1) подставляется (SELECT table_name FROM information_schema.tables LIMIT 1). Тогда в ошибке появится имя первой таблицы. Меняя LIMIT, можно перебрать все таблицы, столбцы и данные.
Пример уязвимого запроса
Рассмотрим гипотетический уязвимый код на PHP:
$name = $_GET['name'];
$query = "SELECT * FROM products WHERE name LIKE '%$name%'";
$result = mysqli_query($conn, $query);Если пользователь передаст %' OR EXTRACTVALUE(2016,CONCAT(0x7e,((SELECT (ELT(2016=2016,1)))),0x7e))-- -, итоговый запрос станет:
SELECT * FROM products WHERE name LIKE '%%' OR EXTRACTVALUE(2016,CONCAT(0x7e,((SELECT (ELT(2016=2016,1)))),0x7e))-- -%'MySQL выполнит EXTRACTVALUE и вернёт ошибку, например: XPATH syntax error: '~1~'. В реальной атаке вместо 1 было бы значение из базы.
Последствия успешной инъекции
- Утечка конфиденциальных данных (пароли, персональные данные, номера карт).
- Полное чтение структуры базы данных через
information_schema. - В некоторых случаях — модификация или удаление данных.
- Компрометация всего веб-приложения и сервера.
Как защититься от error-based SQL-инъекций
Основной метод защиты — использование подготовленных выражений (prepared statements) с параметризацией запросов. Это исключает возможность внедрения SQL-кода, так как данные передаются отдельно от запроса.
Дополнительные меры:
- Экранирование специальных символов с помощью
mysqli_real_escape_string(устаревший, но всё ещё используемый метод). - Валидация и фильтрация входных данных (белые списки, ограничение длины, типов).
- Использование ORM и Query Builder, которые автоматически параметризуют запросы.
- Отключение вывода ошибок MySQL в production-окружении (display_errors = Off).
- Применение WAF (Web Application Firewall) для блокировки подозрительных запросов.
- Регулярное обновление СУБД и библиотек.
Заключение
Строка %' OR EXTRACTVALUE(2016,CONCAT(0x7e,((SELECT (ELT(2016=2016,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции для MySQL. Она демонстрирует, как злоумышленники могут использовать функции EXTRACTVALUE, CONCAT и ELT для извлечения данных через сообщения об ошибках. Понимание механизма таких атак помогает разработчикам и администраторам правильно защищать веб-приложения: использовать подготовленные выражения, фильтровать ввод и скрывать детали ошибок от пользователей.
Комментарии
—Войдите, чтобы оставить комментарий