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

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

Подобные строки часто встречаются в логах веб-серверов, в полях ввода форм или в параметрах URL. Они выглядят как бессмысленный набор символов, но на самом деле представляют собой тщательно сконструированный запрос, цель которого — заставить базу данных выдать скрытую информацию.

Разбор по компонентам

Давайте разберём эту строку на части, чтобы понять, как она работает.

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

В результате выполнения такого запроса MySQL выдаст ошибку вида: XPATH syntax error: '~1~'. Злоумышленник, подставляя вместо 1 другие подзапросы, может извлекать имена таблиц, логины, пароли и другие данные.

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

Error-based SQL-инъекция — это метод, при котором атакующий заставляет базу данных вернуть данные в тексте ошибки. В MySQL для этого часто используют функции EXTRACTVALUE или UPDATEXML. Они принимают XML-документ и путь XPath. Если XPath содержит недопустимые символы, MySQL генерирует ошибку, включающую эти символы.

Пример: EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) вернёт ошибку с версией MySQL. Злоумышленник может постепенно извлекать данные посимвольно или целыми строками, используя подзапросы.

В нашей строке используется ELT(7700=7700,1) — это простейший тест, который всегда возвращает 1. Он нужен, чтобы проверить, работает ли инъекция. Если в ответе появляется ошибка с '~1~', значит, уязвимость есть.

Почему это опасно?

Успешная error-based инъекция позволяет злоумышленнику:

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

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

Как защититься?

Основной способ защиты от SQL-инъекций — использование параметризованных запросов (prepared statements). Это гарантирует, что пользовательский ввод никогда не будет интерпретирован как SQL-код.

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

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

Пример безопасного кода

Вместо конкатенации строк используйте подготовленные выражения. Например, на PHP с PDO:

$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$stmt->execute(['username' => $userInput]);

Такой подход полностью исключает возможность инъекции, так как SQL-запрос и данные передаются раздельно.

Заключение

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

Источники