Введение

В логах веб-серверов, в полях ввода форм или в параметрах URL часто можно встретить загадочные строки, содержащие функции баз данных. Одна из таких строк — ' AND EXTRACTVALUE(3377,CONCAT(0x7e,((SELECT (ELT(3377=3377,1)))),0x7e))-- -. Что это такое и какова её цель? Это классический пример SQL-инъекции, нацеленной на извлечение информации из базы данных MySQL. В этой статье мы подробно разберём, как работает данный запрос, какие функции используются и как защититься от подобных атак.

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

SQL-инъекция (SQL injection) — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в поля ввода или параметры запроса, чтобы заставить базу данных выполнить неожиданные действия: получить доступ к конфиденциальным данным, изменить их или удалить. Уязвимости возникают, когда приложение не проверяет и не экранирует пользовательский ввод перед подстановкой в SQL-запрос.

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

Рассмотрим каждый элемент этого запроса по порядку.

1. Символ ' (одинарная кавычка)

Одинарная кавычка используется для разрыва строкового литерала в исходном SQL-запросе. Например, если приложение выполняет запрос вида SELECT * FROM users WHERE name = '$input', то подставив ', злоумышленник закрывает строку и может добавить свой код.

2. AND

Логический оператор AND добавляет условие к запросу. В данном случае он присоединяет вызов функции EXTRACTVALUE к оригинальному запросу.

3. EXTRACTVALUE(3377, CONCAT(...))

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

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

Функция CONCAT() объединяет строки. Здесь она соединяет символ 0x7e (тильда ~), результат подзапроса и ещё одну тильду. Тильды служат маркерами, чтобы облегчить поиск данных в сообщении об ошибке.

5. (SELECT (ELT(3377=3377,1)))

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

6. -- -

Двойной дефис с пробелом — это комментарий в SQL. Всё, что идёт после него, игнорируется базой данных. Это позволяет отсечь остальную часть оригинального запроса, чтобы он оставался синтаксически корректным.

Как работает атака целиком?

Предположим, веб-приложение выполняет запрос:

SELECT * FROM articles WHERE id = '$_GET[id]'

Злоумышленник передаёт в параметре id строку:

' AND EXTRACTVALUE(3377,CONCAT(0x7e,((SELECT (ELT(3377=3377,1)))),0x7e))-- -

После подстановки запрос становится:

SELECT * FROM articles WHERE id = '' AND EXTRACTVALUE(3377,CONCAT(0x7e,((SELECT (ELT(3377=3377,1)))),0x7e))-- -'

База данных выполняет функцию EXTRACTVALUE. Поскольку второй аргумент содержит тильды и результат подзапроса, MySQL пытается интерпретировать это как XPath. XPath с тильдами некорректен, поэтому генерируется ошибка вида:

XPATH syntax error: '~1~'

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

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

  • Сбор информации: получение версии СУБД, имён таблиц, колонок, учётных данных.
  • Обход аутентификации: иногда с помощью инъекций можно войти в систему без пароля.
  • Изменение или удаление данных: выполнение UPDATE, DELETE, DROP и других опасных команд.

Конкретно этот пример с ELT(3377=3377,1) — простейший тест на наличие уязвимости. Если ошибка появляется, значит, приложение уязвимо к SQL-инъекциям.

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

Основные меры защиты:

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

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

Заключение

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

Источники