Введение
В логах веб-серверов, в полях ввода или в отчётах систем обнаружения вторжений часто можно встретить загадочные строки, содержащие функции и странные последовательности символов. Одна из таких строк — %"))) AND EXTRACTVALUE(9432,CONCAT(0x7e,((SELECT (ELT(9432=9432,1)))),0x7e))-- -. Что это такое и какова её цель? Это классический пример error-based SQL-инъекции (SQL-инъекция, основанная на ошибках) для СУБД MySQL. Подобные конструкции используются злоумышленниками для извлечения данных из базы данных через вывод сообщений об ошибках. В этой статье мы подробно разберём, как работает данная строка, какие функции задействованы и как защитить своё веб-приложение от таких атак.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — один из самых распространённых способов взлома веб-приложений. Суть атаки заключается во внедрении вредоносного SQL-кода в запросы, которые приложение отправляет базе данных. Если входные данные не фильтруются должным образом, злоумышленник может выполнить произвольные команды: прочитать, изменить или удалить конфиденциальную информацию, а в некоторых случаях — получить полный контроль над сервером.
SQL-инъекции делятся на несколько типов: union-based, error-based, blind (слепая), time-based и другие. Рассматриваемая строка относится к error-based типу, который relies на выводе сообщений об ошибках СУБД для получения данных.
Разбор строки %"))) AND EXTRACTVALUE(9432,CONCAT(0x7e,((SELECT (ELT(9432=9432,1)))),0x7e))-- -
Давайте разложим эту строку на составные части, чтобы понять логику атаки.
1. Начало: %")))
Символы %"))) — это попытка закрыть предыдущий SQL-запрос и внедрить свой код. Знак процента (%) часто используется в URL-кодировании, но здесь он может быть частью исходного запроса. Кавычка (") и закрывающие скобки ))) предназначены для того, чтобы «разорвать» оригинальный запрос и добавить условие AND. Например, если уязвимый запрос выглядит как SELECT * FROM users WHERE id = '$input', то подстановка %"))) AND ... может превратить его в SELECT * FROM users WHERE id = '%"))) AND ..., что приведёт к синтаксической ошибке, но с внедрённым кодом.
2. Оператор AND
Логический оператор AND используется для добавления дополнительного условия к запросу. В контексте инъекции он позволяет присоединить вызов функции EXTRACTVALUE к основному запросу.
3. Функция EXTRACTVALUE
EXTRACTVALUE(XML_document, XPath_expression) — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Однако она имеет особенность: если XPath-выражение содержит недопустимые символы, MySQL генерирует ошибку, в тексте которой отображается переданное значение. Именно это свойство и эксплуатируется злоумышленниками.
В нашем случае первый аргумент — 9432 (произвольное число, часто используемое как идентификатор), а второй — CONCAT(0x7e,((SELECT (ELT(9432=9432,1)))),0x7e).
4. Функция CONCAT и шестнадцатеричные литералы
CONCAT объединяет строки. Здесь она соединяет символ 0x7e (тильда ~) с результатом подзапроса и ещё одной тильдой. Тильда используется как разделитель, чтобы облегчить чтение вывода ошибки.
5. Подзапрос (SELECT (ELT(9432=9432,1)))
Внутри CONCAT находится подзапрос (SELECT (ELT(9432=9432,1))). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Если N=1, возвращается первая строка. Выражение 9432=9432 всегда истинно (1), поэтому ELT(1,1) вернёт 1. Однако в реальной атаке вместо 1 может быть подставлен другой запрос, например, (SELECT version()) или (SELECT password FROM users LIMIT 1). Таким образом, злоумышленник может извлечь любые данные.
В данном примере ELT(9432=9432,1) — это упрощённая демонстрация. На практике вместо 1 указывается подзапрос, возвращающий конфиденциальную информацию.
6. Комментарий -- -
Последовательность -- - (дефис, дефис, пробел, дефис) — это комментарий в SQL. В MySQL комментарий начинается с -- (два дефиса и пробел) и продолжается до конца строки. Символ - после пробела добавлен для обхода некоторых фильтров, которые могут удалять пробелы. Комментарий отсекает остаток оригинального запроса, чтобы не возникло синтаксической ошибки.
Как работает атака целиком
Предположим, уязвимый запрос выглядит так:
SELECT * FROM products WHERE category = '$cat'Злоумышленник передаёт в параметр cat строку %"))) AND EXTRACTVALUE(9432,CONCAT(0x7e,((SELECT (ELT(9432=9432,1)))),0x7e))-- -. После подстановки запрос принимает вид:
SELECT * FROM products WHERE category = '%"))) AND EXTRACTVALUE(9432,CONCAT(0x7e,((SELECT (ELT(9432=9432,1)))),0x7e))-- -'MySQL попытается выполнить этот запрос. Из-за наличия EXTRACTVALUE с некорректным XPath (в данном случае XPath — это строка, начинающаяся с тильды, что недопустимо) будет сгенерирована ошибка. Текст ошибки будет содержать переданное значение, например: XPATH syntax error: '~1~'. Если вместо 1 стоял подзапрос, в ошибке отобразится результат его выполнения. Так злоумышленник получает данные.
Важно отметить, что в реальных атаках вместо 9432 и 1 могут быть другие числа и подзапросы, адаптированные под конкретную цель.
Последствия успешной SQL-инъекции
Если злоумышленнику удаётся эксплуатировать уязвимость, последствия могут быть катастрофическими:
- Утечка конфиденциальных данных (пароли, персональная информация, платёжные реквизиты).
- Изменение или удаление данных в базе.
- Получение доступа к другим системам через базу данных.
- Отказ в обслуживании (DoS) путём выполнения ресурсоёмких запросов.
Именно поэтому важно своевременно обнаруживать и устранять такие уязвимости.
Как защититься от error-based SQL-инъекций
Существует несколько эффективных мер защиты:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ. Параметризованные запросы отделяют код от данных, и внедрённый SQL-код не будет выполнен.
- Экранирование специальных символов. Если по каким-то причинам нельзя использовать подготовленные выражения, необходимо тщательно экранировать все входные данные с помощью функций вроде
mysqli_real_escape_string. - Валидация входных данных. Проверяйте, что вводимые пользователем данные соответствуют ожидаемому формату (например, число, email и т.д.).
- Отключение вывода ошибок СУБД. Не показывайте пользователям подробные сообщения об ошибках базы данных. Это затруднит эксплуатацию error-based инъекций.
- Использование WAF (Web Application Firewall). Современные WAF могут обнаруживать и блокировать попытки SQL-инъекций.
- Регулярное обновление СУБД и фреймворков. Устаревшие версии могут содержать известные уязвимости.
Также рекомендуется проводить регулярные аудиты безопасности и тесты на проникновение.
Заключение
Строка %"))) AND EXTRACTVALUE(9432,CONCAT(0x7e,((SELECT (ELT(9432=9432,1)))),0x7e))-- - — это не случайный набор символов, а целенаправленный эксплойт для проведения error-based SQL-инъекции в MySQL. Понимание принципов работы таких атак помогает разработчикам и специалистам по безопасности создавать более защищённые приложения. Если вы обнаружили подобную строку в логах, это сигнал о том, что ваше приложение пытались взломать. Не игнорируйте такие события: проверьте код на наличие уязвимостей и примите меры по их устранению.
Помните: безопасность — это процесс, а не одноразовое действие. Регулярно обновляйте свои знания и инструменты, чтобы противостоять современным угрозам.
Комментарии
—Войдите, чтобы оставить комментарий