Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Одной из разновидностей является error-based SQL-инъекция, основанная на намеренном вызове ошибок СУБД, которые возвращают полезную информацию в тексте сообщения об ошибке.
Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-документа с помощью выражения XPath. Однако при передаче некорректного XPath-выражения MySQL генерирует ошибку, содержащую переданную строку. Это позволяет атакующему «вытащить» данные через сообщение об ошибке.
Разбор запроса AND EXTRACTVALUE(1694,CONCAT(0x7e,((SELECT (ELT(1694=1694,1)))),0x7e))-- -
Рассмотрим детально, что делает каждый элемент этого запроса.
1. Префикс AND
Конструкция AND добавляется к исходному SQL-запросу, чтобы внедрить дополнительное условие. Если исходный запрос был, например, SELECT * FROM users WHERE id = 1, то после инъекции он превращается в SELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(...). Это позволяет выполнить вредоносную функцию только при истинности предыдущего условия.
2. Функция EXTRACTVALUE(1694, CONCAT(...))
Первый аргумент — 1694 — произвольное число (может быть любым). Второй аргумент — результат CONCAT(), который формирует строку, интерпретируемую как XPath-выражение. Поскольку эта строка не является корректным XPath, MySQL выдаст ошибку вида: XPATH syntax error: '~...~', где ~ — разделитель, добавленный через 0x7e (шестнадцатеричное представление тильды).
3. CONCAT(0x7e, ((SELECT (ELT(1694=1694,1)))), 0x7e)
Функция CONCAT объединяет три части:
0x7e— символ~(тильда), служит маркером начала и конца выводимых данных.((SELECT (ELT(1694=1694,1))))— подзапрос, возвращающий результат функцииELT().- Ещё один
0x7e— закрывающая тильда.
4. ELT(1694=1694, 1)
Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь первый аргумент — выражение 1694=1694, которое всегда истинно (равно 1). Второй аргумент — строка 1. Таким образом, ELT(1, 1) возвращает '1'. Это простейший случай, демонстрирующий работу инъекции: в реальной атаке вместо 1 мог бы быть подзапрос, извлекающий данные (например, имя пользователя, хеш пароля).
5. Комментарий -- -
Символы -- начинают комментарий в SQL, а следующий за ними пробел (или дефис) гарантирует, что остальная часть исходного запроса будет проигнорирована. Это позволяет обрезать запрос и избежать синтаксических ошибок.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE id = 1 AND EXTRACTVALUE(1694,CONCAT(0x7e,((SELECT (ELT(1694=1694,1)))),0x7e))-- -
При выполнении MySQL попытается вычислить EXTRACTVALUE и выдаст ошибку:
XPATH syntax error: '~1~'
Таким образом, атакующий получает подтверждение, что инъекция работает, и может заменить 1 на любой другой подзапрос, например, (SELECT version()), чтобы узнать версию СУБД, или (SELECT password FROM users LIMIT 1) для кражи паролей.
Зачем используется ELT и 1694=1694?
Конструкция ELT(1694=1694,1) — это классический приём в error-based инъекциях. Выражение 1694=1694 всегда истинно, что даёт ELT(1,1). Это позволяет обойти фильтры, которые могут блокировать прямые подзапросы, и продемонстрировать работоспособность инъекции без реального извлечения данных. В реальных атаках вместо 1 подставляется сложный подзапрос, а вместо 1694=1694 может быть условие, зависящее от данных (например, ASCII(SUBSTRING(...))>100).
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это делает невозможным внедрение SQL-кода.
- Экранировать специальные символы во всех пользовательских данных, попадающих в SQL-запросы.
- Ограничить права пользователя БД, чтобы даже при успешной инъекции злоумышленник не мог получить доступ к критичным данным.
- Отключить вывод подробных ошибок в production-окружении, чтобы сообщения об ошибках не попадали к пользователю.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Заключение
Запрос AND EXTRACTVALUE(1694,CONCAT(0x7e,((SELECT (ELT(1694=1694,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, эксплуатирующей функцию EXTRACTVALUE в MySQL. Понимание механики таких атак помогает разработчикам и специалистам по безопасности своевременно выявлять и устранять уязвимости.
Комментарии
—Войдите, чтобы оставить комментарий