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

Перед нами фрагмент, который часто встречается в логах веб-сервера или в поле ввода на сайте:

` AND EXTRACTVALUE(7907,CONCAT(0x7e,((SELECT (ELT(7907=7907,1)))),0x7e))-- -

Это пример SQL-инъекции (SQL injection), а именно — error-based SQL-инъекции (инъекции, основанной на ошибках). Такие конструкции используют для извлечения данных из базы данных MySQL через сообщения об ошибках, которые возвращаются приложением.

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

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

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

1. Обратная кавычка (`)

Символ обратной кавычки в MySQL используется для экранирования идентификаторов (например, имён таблиц или столбцов). В данном случае он, вероятно, служит для того, чтобы «разорвать» исходный SQL-запрос и внедрить свой код. Злоумышленник предполагает, что приложение подставляет пользовательский ввод в запрос без должной обработки, и пытается закрыть строку или идентификатор, чтобы добавить свою конструкцию.

2. AND

Логический оператор AND используется для объединения условий в SQL-запросе. Здесь он нужен, чтобы внедряемое выражение выполнилось только при истинности предыдущего условия (или чтобы не нарушить синтаксис исходного запроса).

3. EXTRACTVALUE(7907, CONCAT(...))

EXTRACTVALUE() — это встроенная функция MySQL, которая извлекает значение из XML-фрагмента. Она принимает два аргумента: XML-строку и XPath-выражение. Если XPath-выражение некорректно или возвращает несколько узлов, функция генерирует ошибку, в тексте которой может содержаться результат вычисления переданного выражения.

В нашем случае первым аргументом передаётся число 7907 (произвольное число, может быть любым), а вторым — результат CONCAT. Именно ошибка, возникающая при обработке EXTRACTVALUE, и станет каналом утечки данных.

4. CONCAT(0x7e, ((SELECT (ELT(7907=7907,1)))), 0x7e)

CONCAT() объединяет строки. Здесь она склеивает:

  • 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как маркер, чтобы облегчить поиск внедрённых данных в сообщении об ошибке.
  • Результат подзапроса SELECT (ELT(7907=7907,1)).
  • Ещё одну тильду 0x7e.

Таким образом, в ошибку попадёт строка вида ~<результат>~.

5. ELT(7907=7907, 1)

ELT() — функция MySQL, которая возвращает N-й элемент из списка строк. Первый аргумент — это число (позиция), второй и последующие — строки. В данном случае ELT(7907=7907, 1) вычисляет выражение 7907=7907, которое всегда истинно (1), и возвращает первый элемент из списка, то есть 1. Это простейшая проверка, которая всегда вернёт 1. В реальных атаках вместо 1 может быть подзапрос, извлекающий данные (например, имя пользователя или пароль).

Фактически, данная конструкция — это «тестовая» инъекция, чтобы проверить, уязвим ли сайт. Если приложение вернёт ошибку с текстом, содержащим тильды и число, значит, инъекция работает.

6. -- - (комментарий)

Два дефиса и пробел (или дефис) в MySQL означают начало комментария. Всё, что идёт после них, игнорируется базой данных. Это нужно, чтобы «отрезать» оставшуюся часть исходного запроса, которая могла бы помешать выполнению внедрённого кода или вызвать синтаксическую ошибку. Символ - после пробела — это дополнительная мера для обхода некоторых фильтров, но в стандартном MySQL достаточно -- (с пробелом).

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

Метод основан на том, что СУБД при возникновении ошибки возвращает её текст клиенту (или приложение выводит его на страницу). Злоумышленник конструирует запрос так, чтобы в тексте ошибки оказались данные, которые он хочет получить. В MySQL для этого часто используют функции EXTRACTVALUE() или UPDATEXML(). Они генерируют ошибку формата «XPATH syntax error: '...'», где вместо многоточия подставляется результат вычисления внедрённого выражения.

В нашем примере после выполнения запроса можно ожидать ошибку вроде:

XPATH syntax error: '~1~'

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

Чем опасна такая инъекция?

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

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

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

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

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

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

Заключение

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

Источники