Что это за строка?
Перед нами типичный пример error-based SQL-инъекции (инъекции, основанной на ошибках) для СУБД MySQL. Конструкция AND EXTRACTVALUE(9430,CONCAT(0x7e,((SELECT (ELT(9430=9430,1)))),0x7e))-- - может встретиться в логах веб-сервера, в поле ввода формы или в параметрах URL. Её цель — заставить базу данных вернуть данные через сообщение об ошибке.
Подобные строки часто используются злоумышленниками для проверки уязвимости сайта или для извлечения информации из базы данных. В данной статье мы разберём, как именно работает этот эксплойт, какие функции MySQL задействованы и как от него защититься.
Разбор по частям
Давайте разложим запрос на составляющие, чтобы понять логику атакующего.
1. AND
Логический оператор, который добавляется к исходному SQL-запросу. Если исходный запрос возвращает истину, то AND с любым выражением не изменит результат, но позволит внедрить свою конструкцию.
2. EXTRACTVALUE(9430, CONCAT(...))
EXTRACTVALUE — встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_фрагмент, XPath_выражение). В нашем случае первым аргументом передаётся число 9430 (произвольное число, может быть любым), а вторым — результат CONCAT.
Особенность EXTRACTVALUE в том, что если XPath-выражение некорректно, MySQL выдаёт ошибку, в тексте которой содержится переданное выражение. Это и используется для внедрения.
3. CONCAT(0x7e, ((SELECT (ELT(9430=9430,1)))), 0x7e)
CONCAT объединяет строки. Здесь он склеивает:
0x7e— шестнадцатеричное представление символа~(тильда). Используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке.((SELECT (ELT(9430=9430,1))))— подзапрос, возвращающий результат функцииELT.- Ещё один
0x7e— закрывающая тильда.
Таким образом, CONCAT формирует строку вида ~<результат>~, которая затем передаётся в EXTRACTVALUE в качестве XPath-выражения.
4. ELT(9430=9430, 1)
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Если N=1, возвращается первая строка. В данном случае 9430=9430 — это логическое выражение, которое всегда истинно (1). Поэтому ELT(1, 1) вернёт 1. Это простейший случай: атакующий мог бы заменить 1 на вызов другой функции, например VERSION() или DATABASE(), чтобы извлечь полезные данные.
Однако в приведённой строке подзапрос возвращает просто число 1. Это тестовый пример, чтобы проверить, выполняется ли инъекция. Если сервер вернёт ошибку с текстом, содержащим ~1~, значит, уязвимость есть.
5. -- -
Это комментарий в MySQL. -- начинает комментарий, а пробел и дефис добавлены для надёжности (некоторые парсеры требуют пробела после --). Всё, что идёт после, игнорируется. Это нужно, чтобы обрезать остаток исходного запроса, который мог бы помешать выполнению инъекции.
Как это работает вместе
Представим, что исходный запрос был таким:
SELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(9430,CONCAT(0x7e,((SELECT (ELT(9430=9430,1)))),0x7e))-- -MySQL выполнит EXTRACTVALUE с XPath-выражением ~1~. Это выражение синтаксически некорректно, поэтому СУБД сгенерирует ошибку:
XPATH syntax error: '~1~'
В тексте ошибки появятся данные, которые злоумышленник внедрил в запрос. В данном случае это просто «1», но если заменить ELT(9430=9430,1) на VERSION(), то в ошибке отобразится версия MySQL. Если на DATABASE() — имя текущей базы данных. Если на подзапрос SELECT password FROM users LIMIT 1 — хеш пароля и т.д.
Таким образом, error-based инъекция позволяет извлекать произвольные данные из базы, если приложение выводит сообщения об ошибках MySQL пользователю.
Почему это опасно?
Успешная эксплуатация такой инъекции может привести к:
- чтению конфиденциальных данных (пароли, персональные данные, номера кредитных карт);
- обходу аутентификации;
- изменению или удалению информации в базе;
- полному захвату сервера в некоторых случаях.
Даже если приложение не показывает ошибки, злоумышленник может использовать слепые методы (blind SQL injection), но error-based считается более простой и быстрой.
Как защититься?
Основная причина уязвимости — недостаточная фильтрация пользовательского ввода и конкатенация его в SQL-запрос. Вот ключевые меры:
- Используйте подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ.
- Экранируйте специальные символы с помощью функций вроде
mysqli_real_escape_string, но помните, что это не панацея. - Отключите вывод ошибок MySQL в production-окружении. Пользователь не должен видеть текст ошибок СУБД.
- Применяйте принцип наименьших привилегий для учётной записи базы данных: не давайте ей прав на чтение системных таблиц и т.д.
- Регулярно обновляйте СУБД и фреймворки, используйте WAF (веб-application firewall) для фильтрации подозрительных запросов.
В случае с EXTRACTVALUE можно также отключить эту функцию, если она не используется, но обычно проще исправить код.
Вывод
Строка AND EXTRACTVALUE(9430,CONCAT(0x7e,((SELECT (ELT(9430=9430,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проверки и эксплуатации error-based SQL-инъекции в MySQL. Понимание его работы помогает разработчикам и специалистам по безопасности эффективнее защищать веб-приложения.
Если вы встретили такую строку в логах, это повод проверить свой сайт на уязвимости и усилить меры безопасности.
Комментарии
—Войдите, чтобы оставить комментарий