Встретили в логах или в запросе подозрительную строку ') AND EXTRACTVALUE(9728,CONCAT(0x7e,((SELECT (ELT(9728=9728,1)))),0x7e))-- -? Это не случайный набор символов, а тщательно сконструированная SQL-инъекция типа error-based, нацеленная на СУБД MySQL. В этой статье мы разберём её по частям, объясним, зачем она нужна, и расскажем, как защитить свой сайт от подобных атак.

Что такое error-based SQL-инъекция?

SQL-инъекция — это один из самых распространённых способов взлома веб-приложений. Злоумышленник передаёт в поле ввода (например, в форму авторизации или в параметр URL) специально сформированную строку, которая встраивается в SQL-запрос и заставляет базу данных выполнить нежелательные действия. Существует несколько разновидностей: union-based, blind, time-based и error-based.

Error-based инъекция основана на том, что база данных при определённых условиях возвращает сообщение об ошибке, содержащее результат выполнения подзапроса. Атакующий может извлечь данные (имена таблиц, логины, пароли) прямо из текста ошибки, не имея прямого доступа к выводу страницы.

Разбор строки ') AND EXTRACTVALUE(9728,CONCAT(0x7e,((SELECT (ELT(9728=9728,1)))),0x7e))-- -

Давайте разберём её на составляющие:

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

Когда MySQL выполняет EXTRACTVALUE с некорректным XPath-выражением (а CONCAT с тильдой делает его таковым), он выбрасывает ошибку вида XPATH syntax error: '~1~'. В этом сообщении и оказывается результат подзапроса — в данном примере это просто «1», но в реальной атаке вместо ELT(9728=9728,1) подставляется, например, (SELECT password FROM users LIMIT 1), и пароль утекает в лог ошибок.

Зачем это нужно злоумышленнику?

Цель — получить доступ к данным, которые не отображаются на странице. Например, узнать версию СУБД, имена таблиц и колонок, логины и хеши паролей администраторов. Error-based инъекция удобна тем, что не требует слепого перебора: результат сразу виден в тексте ошибки.

Подобные конструкции часто встречаются в автоматизированных сканерах уязвимостей (sqlmap, Havij) и в логах веб-серверов. Если вы видите такую строку в логах, значит, ваш сайт пытались просканировать на уязвимость.

Как защититься от error-based SQL-инъекций?

Главное правило — никогда не доверять пользовательскому вводу. Вот ключевые меры:

  1. Используйте подготовленные выражения (prepared statements). Это самый надёжный способ. Параметры передаются отдельно от SQL-кода, и внедрить что-либо в запрос невозможно.
  2. Экранируйте специальные символы. Если prepared statements недоступны, применяйте функции экранирования (mysqli_real_escape_string, pg_escape_string и т.п.).
  3. Ограничьте права пользователя БД. Не давайте веб-приложению прав на чтение системных таблиц и выполнение опасных функций.
  4. Отключите вывод ошибок на продакшене. Сообщения об ошибках не должны попадать в браузер пользователя — только в защищённый лог.
  5. Используйте WAF (Web Application Firewall). Он может блокировать подозрительные запросы на лету.
  6. Регулярно обновляйте СУБД и фреймворки. Многие уязвимости закрываются в новых версиях.

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

Не паникуйте. Сначала проверьте, удалось ли атаке достичь цели: просмотрите логи ошибок MySQL, логи веб-сервера. Если в ответах нет признаков утечки (например, необычных ошибок с данными), вероятно, атака была отбита. В любом случае стоит провести аудит кода на предмет SQL-инъекций и убедиться, что все запросы используют параметризацию.

Помните: error-based инъекции — это не магия, а следствие небрежного программирования. Правильная валидация и параметризация сводят риск к нулю.

Строка ') AND EXTRACTVALUE(9728,CONCAT(0x7e,((SELECT (ELT(9728=9728,1)))),0x7e))-- - — это учебный пример эксплуатации уязвимости. В реальной атаке вместо ELT(9728=9728,1) будет стоять подзапрос, извлекающий конфиденциальные данные.

Таким образом, перед вами классический образец error-based SQL-инъекции для MySQL. Знание того, как она устроена, помогает вовремя распознать угрозу и принять меры. Безопасность веб-приложений — это непрерывный процесс, и понимание основ SQL-инъекций — первый шаг к защите.

Источники