Введение

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

В данной статье мы разберём, как работает эта конкретная инъекция, какие цели она преследует и как защитить свой сайт от подобных атак.

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

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

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

Разбор строки EXTRACTVALUE

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

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

Таким образом, вся конструкция заставляет MySQL выполнить подзапрос и вывести его результат в сообщении об ошибке. Атакующий может прочитать это сообщение и получить конфиденциальные данные.

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

Error-based SQL-инъекция эксплуатирует особенности вывода ошибок в СУБД. В MySQL функции EXTRACTVALUE и UPDATEXML при передаче некорректного XPath-выражения вызывают ошибку, в тексте которой содержится переданная строка. Это позволяет злоумышленнику внедрить в ошибку результат выполнения подзапроса.

Например, если атакующий хочет узнать версию базы данных, он может подставить в подзапрос @@version. Тогда в ошибке появится что-то вроде:

XPATH syntax error: '~5.7.33~'

Так он узнает версию MySQL. Далее можно извлекать имена таблиц, колонок и сами данные.

Опасность для сайта

Последствия успешной SQL-инъекции могут быть катастрофическими:

  • Утечка персональных данных пользователей (логины, пароли, email, телефоны).
  • Кража финансовой информации (номера карт, счета).
  • Полное удаление или изменение содержимого базы данных.
  • Получение контроля над сервером через выполнение команд ОС.

Именно поэтому так важно защищать свои веб-приложения от подобных атак.

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

Существует несколько надёжных методов защиты:

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

Заключение

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

Источники