Что это за строка?

Строка вида )))) AND EXTRACTVALUE(1330,CONCAT(0x7e,((SELECT (ELT(1330=1330,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в логах веб-серверов, в полях ввода форм или в параметрах URL, когда злоумышленник пытается прощупать уязвимость сайта.

Внешне это выглядит как бессмысленный набор символов, но на самом деле каждый элемент здесь имеет строгое назначение. Давайте разберём его по частям.

Анатомия инъекции

Рассмотрим фрагменты подробнее:

  • )))) — закрывающие скобки, которые нужны, чтобы «подогнать» синтаксис под исходный SQL-запрос. Часто они завершают открытые ранее условия или функции.
  • AND EXTRACTVALUE(1330, CONCAT(...)) — вызов функции EXTRACTVALUE, которая извлекает значение из XML-документа по XPath-выражению. Если второй аргумент не является корректным XPath, MySQL генерирует ошибку, в тексте которой отображается переданная строка.
  • CONCAT(0x7e, ((SELECT (ELT(1330=1330,1)))), 0x7e) — конкатенация символа ~ (0x7e), результата подзапроса и ещё одного ~. Символ ~ используется как маркер, чтобы в сообщении об ошибке было легко найти внедрённые данные.
  • ELT(1330=1330,1) — функция ELT возвращает N-й элемент из списка. Здесь условие 1330=1330 всегда истинно, поэтому возвращается 1. Это простейшая проверка работоспособности инъекции.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы синтаксис был корректным.

Таким образом, вся конструкция заставляет MySQL выполнить подзапрос и вывести его результат в тексте ошибки, которую атакующий затем читает.

Как работает error-based SQL-инъекция

MySQL поддерживает функцию EXTRACTVALUE(XML_document, XPath_expression). Если XPath-выражение содержит недопустимые символы (например, тильду ~), СУБД возвращает ошибку вида:

XPATH syntax error: '~1~'

Именно это и нужно злоумышленнику: он может подставить в XPath любой подзапрос, и результат его выполнения окажется в тексте ошибки. Такой метод называется error-based, потому что данные извлекаются через сообщения об ошибках, а не через прямое отображение на странице.

В приведённой строке вместо 1 мог бы быть, например, (SELECT version()) или (SELECT password FROM users LIMIT 1). Тогда в ошибке отобразилась бы версия MySQL или хеш пароля.

Зачем это нужно атакующему?

Цель любой SQL-инъекции — получить доступ к данным, которые не должны быть видны пользователю. В случае error-based инъекции злоумышленник может:

  • определить версию СУБД и тип базы данных;
  • получить имена таблиц и столбцов;
  • извлечь логины, пароли, персональные данные;
  • в некоторых случаях — выполнить произвольные команды на сервере.

При этом атака может быть автоматизирована с помощью инструментов вроде SQLmap, которые подставляют подобные полезные нагрузки в уязвимые параметры.

Пример уязвимого запроса

Предположим, на сайте есть страница product.php?id=1, и в коде выполняется:

$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = $id";

Если пользователь передаст 1 AND EXTRACTVALUE(1330,CONCAT(0x7e,((SELECT (ELT(1330=1330,1)))),0x7e))-- -, то итоговый запрос станет таким:

SELECT * FROM products WHERE id = 1 AND EXTRACTVALUE(1330,CONCAT(0x7e,((SELECT (ELT(1330=1330,1)))),0x7e))-- -

MySQL выполнит подзапрос и выведет ошибку, содержащую ~1~. Если вместо 1 подставить database(), в ошибке появится имя текущей базы данных.

Как защититься от таких инъекций

Основной способ защиты — использовать параметризованные запросы (prepared statements). Они разделяют код SQL и данные, поэтому введённые пользователем символы никогда не интерпретируются как часть запроса.

Дополнительные меры:

  • валидация и фильтрация всех входных данных (особенно числовых параметров);
  • экранирование специальных символов с помощью функций вроде mysqli_real_escape_string (но это менее надёжно, чем параметризация);
  • ограничение прав пользователя базы данных: приложение должно работать с минимально необходимыми привилегиями;
  • отключение вывода подробных ошибок СУБД на продакшене — это затрудняет error-based атаки;
  • использование WAF (Web Application Firewall) для блокировки подозрительных запросов.

Важно понимать, что даже одна уязвимость может привести к полной компрометации базы данных, поэтому пренебрегать защитой нельзя.

Что делать, если вы нашли такую строку в логах?

Если вы администратор сайта и обнаружили подобную запись в логах, это может означать, что ваш ресурс пытались взломать. Действия:

  1. Проверьте, не была ли атака успешной: поищите необычные ошибки в логах MySQL, изменения в данных.
  2. Убедитесь, что все запросы к базе данных используют параметризацию.
  3. Обновите CMS и плагины до последних версий.
  4. Проведите аудит безопасности с помощью сканеров уязвимостей.
  5. Настройте мониторинг и оповещения о подозрительной активности.

Заключение

Строка )))) AND EXTRACTVALUE(1330,CONCAT(0x7e,((SELECT (ELT(1330=1330,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная полезная нагрузка для error-based SQL-инъекции в MySQL. Она эксплуатирует функцию EXTRACTVALUE для вывода данных через сообщения об ошибках. Понимание принципов работы таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости и защищать свои системы.

Помните: безопасность — это процесс, а не однократное действие. Регулярные проверки и следование лучшим практикам помогут избежать неприятных последствий.

Источники