Строка ))) AND EXTRACTVALUE(9135,CONCAT(0x7e,((SELECT (ELT(9135=9135,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. В этой статье мы разберём, как именно работает такой запрос, что такое функции EXTRACTVALUE и ELT, и почему подобные конструкции считаются опасными.
Что такое SQL-инъекция?
SQL-инъекция (SQLi) — один из самых распространённых способов атаки на веб-приложения. Злоумышленник внедряет в пользовательский ввод специальные символы или целые SQL-конструкции, которые меняют логику выполняемого запроса. Это позволяет читать, изменять или удалять данные, а иногда и полностью захватывать контроль над сервером.
По данным OWASP, SQL-инъекции стабильно входят в топ-10 критических уязвимостей. Ошибки возникают, когда разработчики конкатенируют пользовательский ввод с SQL-запросом без должной обработки.
Разбор строки инъекции
Рассмотрим фрагмент ))) AND EXTRACTVALUE(9135,CONCAT(0x7e,((SELECT (ELT(9135=9135,1)))),0x7e))-- - по частям.
)))— закрывающие скобки. Они нужны, чтобы «закрыть» ранее открытые скобки в оригинальном запросе и сделать синтаксис корректным.AND— логический оператор, присоединяющий наше условие к исходному запросу.EXTRACTVALUE(9135, CONCAT(...))— функция MySQL для работы с XML. Она извлекает значение из XML-строки по XPath-выражению. Если XPath некорректен, MySQL выдаёт ошибку, в тексте которой отображается переданное выражение.9135— произвольное число (идентификатор XML-документа).CONCAT(0x7e, ((SELECT (ELT(9135=9135,1)))), 0x7e)— конкатенация символа~(0x7e), результата подзапроса и снова~.SELECT (ELT(9135=9135,1))— подзапрос, возвращающий1, если условие9135=9135истинно. ФункцияELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь N — результат сравнения (1), поэтому возвращается первый элемент —1.-- -— комментарий, который «отрезает» остаток оригинального запроса, чтобы не возникло синтаксической ошибки.
В реальной атаке вместо 9135=9135 подставляется условие, проверяющее данные (например, SUBSTRING(version(),1,1)='5'). Если условие истинно, ELT вернёт 1, и в ошибке EXTRACTVALUE появится строка ~1~. Если ложно — ELT вернёт NULL или 0, и ошибка будет другой. По этим сообщениям атакующий побайтово извлекает информацию.
Почему EXTRACTVALUE вызывает ошибку?
Функция EXTRACTVALUE(XML_document, XPath_expression) требует, чтобы XPath был синтаксически правильным. Если передать строку, не являющуюся корректным XPath (например, содержащую символ ~), MySQL сгенерирует ошибку вида:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
Именно этот текст ошибки и служит каналом утечки данных. Атакующий видит результат выполнения подзапроса прямо в сообщении об ошибке.
Зачем нужен ELT?
ELT(N, str1, str2, ...) возвращает N-й элемент из списка строк. В нашем случае используется один элемент — 1. Конструкция ELT(9135=9135,1) — это трюк: сравнение 9135=9135 всегда истинно (1), поэтому ELT вернёт 1. В реальной инъекции на месте 9135=9135 стоит проверяемое условие, а вместо 1 может быть, например, version() или database().
Пошаговый пример атаки
- Злоумышленник находит точку входа — параметр, который попадает в SQL-запрос без экранирования.
- Подставляет конструкцию с
EXTRACTVALUE, чтобы вызвать ошибку и увидеть её текст. - Меняет условие в
ELT, чтобы извлечь имя базы, версию, имена таблиц и т.д. - Автоматизирует процесс с помощью sqlmap или ручного перебора.
Важно: подобные методы работают только на MySQL и MariaDB. В других СУБД (PostgreSQL, MS SQL) используются иные приёмы.
Как защититься от error-based SQL-инъекций
Основная причина успеха таких атак — отсутствие параметризации запросов. Вот ключевые меры защиты:
- Используйте подготовленные выражения (prepared statements). Это самый надёжный способ. Параметры передаются отдельно от SQL-кода, и внедрить что-либо в структуру запроса невозможно.
- Экранируйте специальные символы. Если по каким-то причинам параметризация недоступна, применяйте функции экранирования, предоставляемые драйвером БД.
- Отключите вывод подробных ошибок в production. Сообщения об ошибках не должны попадать к пользователю — это лишает атакующего обратной связи.
- Ограничьте права пользователя БД. Приложение должно работать под учётной записью с минимально необходимыми привилегиями.
- Используйте WAF. Веб-прикладной брандмауэр может блокировать типовые сигнатуры SQLi, но не является панацеей.
Вывод
Строка ))) AND EXTRACTVALUE(9135,CONCAT(0x7e,((SELECT (ELT(9135=9135,1)))),0x7e))-- - — наглядный пример эксплуатации ошибок СУБД для извлечения данных. Понимание механики таких атак помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Главное правило: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий