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

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

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

Введение: Встречая в логах или в поле ввода подобную строку: ) AND EXTRACTVALUE (7289,CONCAT (0x7e, ( (SELECT (ELT (7289=7289,1)))),0x7e))-- -, многие задаются вопросом: что это и какова её цель? Это классический пример SQL-инъекции, нацеленной на ...

Как работает эта инъекция?

Разберём по частям:

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

Когда этот фрагмент внедряется в уязвимый SQL-запрос, база данных пытается выполнить EXTRACTVALUE с некорректным XPath, что приводит к ошибке. В сообщении об ошибке MySQL отобразит переданную строку, включая результат подзапроса. Таким образом, злоумышленник может «прочитать» данные, которые в обычной ситуации не отображаются на странице.

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

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

В примере с ELT(1989=1989,1) атакующий просто проверяет работоспособность метода. В реальной атаке вместо 1 может быть подставлен, например, (SELECT password FROM users LIMIT 1), и тогда в ошибке появится пароль.

Примеры других error-based инъекций

Помимо EXTRACTVALUE, в MySQL часто используют:

  • UPDATEXML — аналогичная функция для XML, также вызывает ошибку с переданной строкой.
  • floor(rand(0)*2) в связке с GROUP BY — классический приём, вызывающий ошибку «Duplicate entry» с полезной нагрузкой.
  • GTID_SUBSET, JSON_KEYS и другие функции, которые могут выдать данные в тексте ошибки.

Вот пример из практики:

To extract next column name, change value in limit clause from 0,1 to 1,1 and so on Data extraction -> ' and (select 1 FROM (select count(*),concat((select (select concat(0x7e, (select user from data limit 1,1),0x7e))),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a) and 1<'2 In my case column name is "user" and table name is "data", replace it appropriate column and ...

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

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

  1. Не выводить сообщения об ошибках базы данных пользователю. Заменять их на общие фразы.
  2. Проводить валидацию и фильтрацию всех входных данных.
  3. Использовать ORM (например, Hibernate, Entity Framework), которые автоматически экранируют опасные символы.
  4. Регулярно обновлять СУБД и применять патчи безопасности.
  5. Проводить аудит кода и пентесты.

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

Вывод

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

Источники