Введение
В логах веб-сервера или в поле ввода иногда можно встретить странные последовательности символов, например: ')))) AND EXTRACTVALUE(1428,CONCAT(0x7e,((SELECT (ELT(1428=1428,1)))),0x7e))-- -. Для неподготовленного пользователя это выглядит как случайный набор знаков. На самом деле перед нами классический пример SQL-инъекции — атаки на базы данных, при которой злоумышленник внедряет свой код в запрос, выполняемый приложением. В данном случае используется метод error-based SQL injection (инъекция на основе ошибок), характерный для СУБД MySQL. В статье мы детально разберём каждую часть этой строки, объясним, зачем нужны функции EXTRACTVALUE, CONCAT, ELT, и покажем, как злоумышленники извлекают информацию через сообщения об ошибках.
Что такое error-based SQL-инъекция
SQL-инъекция — это способ вмешательства в работу приложения путём внедрения вредоносного SQL-кода в поля ввода, параметры URL или заголовки. Если приложение недостаточно защищено, внедрённый код выполняется на стороне базы данных. Error-based инъекция — частный случай, при котором хакер заставляет СУБД вернуть в ответе сообщение об ошибке, содержащее полезные данные (например, версию сервера, имя базы, содержимое таблиц). Для этого используются функции, которые при некорректных аргументах генерируют ошибку с подставленным значением.
В MySQL одной из таких функций является EXTRACTVALUE(). Она предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в текст которой попадает часть переданных данных. Это и позволяет атакующему «прочитать» результат выполнения подзапроса.
Разбор строки по частям
Рассмотрим анализируемую конструкцию по элементам:
- ')))) — последовательность закрывающих скобок и кавычек. Она нужна, чтобы «закрыть» оригинальный запрос приложения и выйти за его пределы. Количество скобок подбирается экспериментально в зависимости от структуры уязвимого запроса.
- AND — логический оператор, добавляющий условие к запросу. Внедряемая часть выполняется только если предыдущее выражение истинно.
- EXTRACTVALUE(1428, CONCAT(0x7e, ((SELECT (ELT(1428=1428,1)))), 0x7e)) — вызов функции извлечения значения из XML. Первый аргумент — произвольное число (1428), второй — XPath-выражение, сформированное динамически.
- CONCAT(0x7e, ..., 0x7e) — объединение строк.
0x7e— шестнадцатеричный код символа «~» (тильда). Тильда добавляется в начало и конец, чтобы XPath-выражение стало синтаксически некорректным и гарантированно вызвало ошибку. - ((SELECT (ELT(1428=1428,1))) — подзапрос, возвращающий результат функции
ELT().ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь1428=1428— всегда истинное условие, поэтомуELT(1,1)вернёт «1». В реальной атаке вместо «1» мог бы быть, например, номер версии MySQL или имя пользователя, полученные через другой подзапрос. - -- - — комментарий в SQL. Всё, что идёт после него, игнорируется. Это нужно, чтобы «отрезать» оставшуюся часть оригинального запроса и избежать синтаксической ошибки.
В результате выполнения такого запроса MySQL попытается вычислить XPath-выражение, начинающееся с символа «~», что недопустимо. Возникнет ошибка вида: XPATH syntax error: '~1~'. В сообщении об ошибке отобразится результат подзапроса — в нашем случае «1». Если бы подзапрос возвращал, например, @@version, в ошибке появилась бы версия СУБД.
Зачем нужна функция ELT
ELT() в MySQL возвращает строку по её номеру из списка аргументов. В контексте инъекции она используется для преобразования результата логического сравнения в число. Конструкция ELT(1428=1428,1) возвращает «1», потому что условие истинно. Если бы условие было ложным, ELT(0,1) вернул бы NULL. Это позволяет строить запросы, зависящие от условий, и извлекать данные побитно или посимвольно. В более сложных атаках вместо простого сравнения подставляются подзапросы, возвращающие символы из интересующих таблиц.
Как злоумышленники используют такие строки
Подобные конструкции встречаются при автоматизированном сканировании уязвимостей (например, с помощью sqlmap) или при ручном тестировании на проникновение. Цель — получить доступ к данным, которые не должны быть видны: логины и пароли пользователей, номера банковских карт, персональная информация. Error-based инъекция удобна тем, что не требует вывода данных напрямую на страницу — достаточно, чтобы приложение отображало сообщения об ошибках БД. Если же ошибки скрыты, атакующий может использовать blind-инъекции, но это уже другой класс атак.
Важно понимать: рассматриваемая строка сама по себе не является вирусом или вредоносной программой. Это лишь попытка эксплуатации уязвимости. Если ваше приложение вернуло такую ошибку или в логах появилась подобная запись, значит, кто-то пытался проверить систему на наличие SQL-инъекции. Необходимо срочно проверить безопасность кода и настроек сервера.
Как защититься от SQL-инъекций
Основная рекомендация — использовать параметризованные запросы (prepared statements) и хранимые процедуры. Они разделяют код SQL и данные, поэтому внедрённые символы не могут изменить структуру запроса. Дополнительные меры:
- Экранирование специальных символов с помощью функций драйвера БД (например,
mysqli_real_escape_stringв PHP). - Валидация и фильтрация всех входных данных на стороне сервера.
- Ограничение прав пользователя базы данных: приложение должно работать с минимально необходимыми привилегиями.
- Отключение вывода подробных сообщений об ошибках БД в production-окружении.
- Регулярное обновление СУБД и использование WAF (Web Application Firewall).
Соблюдение этих правил сводит риск успешной SQL-инъекции к минимуму.
Заключение
Строка ')))) AND EXTRACTVALUE(1428,CONCAT(0x7e,((SELECT (ELT(1428=1428,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции для MySQL. Она демонстрирует, как злоумышленники используют особенности функций EXTRACTVALUE, CONCAT и ELT, чтобы через сообщения об ошибках получить доступ к данным. Понимание механизма таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости и защищать информацию.
Комментарии
—Войдите, чтобы оставить комментарий