Введение
Строка `) AND EXTRACTVALUE(7599,CONCAT(0x7e,((SELECT (ELT(7599=7599,1)))),0x7e))-- - — это типичный пример SQL-инъекции (SQL injection). Она встречается в логах веб-серверов, в полях ввода форм или в параметрах URL, когда злоумышленник пытается атаковать базу данных. В этой статье мы детально разберём, что означает каждый элемент этой конструкции, зачем используются функции EXTRACTVALUE, CONCAT и ELT, а также как распознать и предотвратить подобные атаки.
Что такое SQL-инъекция?
SQL-инъекция — это один из самых распространённых способов взлома веб-приложений. Атакующий внедряет в запрос к базе данных произвольный SQL-код, который выполняется на сервере. Цель может быть разной: обойти аутентификацию, украсть данные, изменить или удалить информацию. Уязвимости подвержены приложения, которые не проверяют пользовательский ввод и подставляют его напрямую в SQL-запрос.
Приведённый payload относится к подвиду error-based SQL injection — инъекции, основанной на ошибках. Злоумышленник заставляет базу данных вернуть сообщение об ошибке, содержащее нужные данные (например, версию СУБД, имя пользователя или результат подзапроса).
Разбор payload по частям
Давайте последовательно разберём каждый элемент строки.
1. Закрывающая скобка и кавычка `)
Символы ) и обратная кавычка ` (в исходной строке — апостроф или кавычка) используются для «разрыва» оригинального SQL-запроса. Например, если уязвимый запрос выглядит так:
SELECT * FROM users WHERE name = 'USER_INPUT';
то подставив '), атакующий закрывает строковый литерал и условие, после чего может добавить свою конструкцию.
2. AND
Оператор AND добавляет новое условие к существующему запросу. В error-based инъекциях он часто используется для того, чтобы внедряемая функция выполнилась только при определённых условиях (например, при истинности основного запроса).
3. EXTRACTVALUE(7599, CONCAT(...))
EXTRACTVALUE — это встроенная функция MySQL (и MariaDB), предназначенная для извлечения значения из XML-документа. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Однако в руках злоумышленника она превращается в инструмент для вызова ошибки, содержащей результат подзапроса. Если второй аргумент не является корректным XPath-выражением, MySQL генерирует ошибку вида XPATH syntax error: '...', в которую попадает переданная строка.
Первый аргумент 7599 — произвольное число, которое в данном случае не играет роли, но должно быть допустимым XML-документом (число интерпретируется как текст).
4. CONCAT(0x7e, ((SELECT (ELT(7599=7599,1)))), 0x7e)
Функция CONCAT объединяет строки. Здесь она склеивает три части:
0x7e— шестнадцатеричное представление символа~(тильда). Он используется как маркер, чтобы облегчить поиск извлечённых данных в сообщении об ошибке.((SELECT (ELT(7599=7599,1))))— подзапрос, возвращающий значение.- Ещё один
0x7e— закрывающая тильда.
В результате в XPath-выражение попадает строка вида ~<результат>~, и если она содержит недопустимые символы, MySQL выдаст ошибку с этой строкой.
5. ELT(7599=7599, 1)
ELT — функция MySQL, возвращающая N-й элемент из списка. Синтаксис: ELT(N, str1, str2, ...). В нашем случае N — это результат сравнения 7599=7599, которое всегда истинно (1). Таким образом, ELT(1, 1) возвращает первый элемент списка — число 1. Это простейшая демонстрация: в реальной атаке вместо 1 мог бы стоять подзапрос, извлекающий данные (например, (SELECT version())).
6. Комментарий -- -
Последовательность -- (два дефиса) в MySQL начинает комментарий, который продолжается до конца строки. Символ - после пробела добавлен для надёжности: в некоторых СУБД требуется, чтобы после -- был пробел. Всё, что идёт после комментария в исходном запросе, игнорируется. Это позволяет атакующему «отрезать» остаток оригинального запроса, который мог бы вызвать синтаксическую ошибку.
Как работает атака целиком
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE id = '1';
После подстановки payload запрос принимает вид:
SELECT * FROM articles WHERE id = '1') AND EXTRACTVALUE(7599,CONCAT(0x7e,((SELECT (ELT(7599=7599,1)))),0x7e))-- -';
База данных выполняет:
- Закрывает строку и условие:
id = '1'. - Добавляет
AND EXTRACTVALUE(...). - Внутри
EXTRACTVALUEвычисляетсяCONCAT, который возвращает строку~1~. - MySQL пытается интерпретировать
~1~как XPath-выражение, терпит неудачу и возвращает ошибку:XPATH syntax error: '~1~'. - Остаток запроса после
-- -игнорируется.
В результате в ответе сервера (или в логах) появляется сообщение об ошибке, содержащее извлечённые данные. В нашем случае это просто 1, но заменив ELT(7599=7599,1) на подзапрос, атакующий может получить любую информацию из базы.
Зачем нужна такая сложность?
На первый взгляд конструкция кажется избыточной. Однако в реальных атаках злоумышленники используют подобные цепочки, чтобы:
- Обойти фильтры, которые блокируют простые ключевые слова (например,
UNION SELECT). - Обеспечить совместимость с разными версиями MySQL.
- Гарантировать, что ошибка будет сгенерирована только при определённых условиях (например, при истинности основного запроса).
- Использовать шестнадцатеричные литералы (
0x7e) для обхода сигнатур, ищущих кавычки.
Комбинация EXTRACTVALUE + CONCAT + 0x7e — классический пример error-based инъекции, описанный во многих руководствах по безопасности.
Как защититься от SQL-инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). В этом случае пользовательский ввод передаётся отдельно от SQL-кода и не может изменить структуру запроса. Дополнительные меры:
- Валидация и фильтрация входных данных (белые списки символов, приведение типов).
- Экранирование специальных символов с помощью функций СУБД (например,
mysql_real_escape_stringв PHP, но это менее надёжно, чем подготовленные выражения). - Использование ORM и современных фреймворков, которые по умолчанию применяют параметризацию.
- Ограничение прав пользователя базы данных: приложение должно работать с минимально необходимыми привилегиями.
- Регулярное обновление СУБД и веб-приложений.
- Внедрение WAF (Web Application Firewall) для блокировки подозрительных запросов.
Важно понимать, что EXTRACTVALUE и подобные функции не являются уязвимостью сами по себе — их опасность проявляется только при неправильной обработке пользовательского ввода.
Заключение
Строка `) AND EXTRACTVALUE(7599,CONCAT(0x7e,((SELECT (ELT(7599=7599,1)))),0x7e))-- - — это учебный пример SQL-инъекции, демонстрирующий использование error-based техники для извлечения данных. Понимание таких payload помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Если вы встретили подобную строку в логах, это сигнал о попытке взлома; необходимо проверить уязвимости и усилить защиту.
Комментарии
—Войдите, чтобы оставить комментарий