Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых и опасных видов атак на веб-приложения. Согласно OWASP Top 10, она стабильно входит в список критических угроз. Один из методов эксплуатации — error-based SQL-инъекция, при которой злоумышленник заставляет базу данных выдать сообщение об ошибке, содержащее конфиденциальные данные. Функция EXTRACTVALUE() в MySQL часто используется для таких атак.
В запросе пользователя: " OR EXTRACTVALUE(7520,CONCAT(0x7e,((SELECT (ELT(7520=7520,1)))),0x7e))-- - — виден классический пример внедрения. Давайте разберём его по частям.
Как работает EXTRACTVALUE в MySQL
EXTRACTVALUE(XML_frag, XPath_expr) — это встроенная функция MySQL, которая извлекает значение из фрагмента XML по заданному XPath-выражению. Если XPath-выражение синтаксически неверно, MySQL возвращает ошибку вида: XPATH syntax error: '...'. Именно эта особенность позволяет злоумышленникам внедрять произвольные данные в текст ошибки.
Например, запрос:
SELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e));
вернёт ошибку: XPATH syntax error: '~5.7.23~'. Таким образом, версия СУБД будет выведена в сообщении об ошибке.
Разбор инъекции из запроса
Рассмотрим внедрение: " OR EXTRACTVALUE(7520,CONCAT(0x7e,((SELECT (ELT(7520=7520,1)))),0x7e))-- -.
"— закрывает строковый литерал в уязвимом запросе.OR— логический оператор, который делает условие всегда истинным (если правая часть вернёт истину или ошибку).EXTRACTVALUE(7520, ...)— вызов функции. Первый аргумент (7520) — произвольное число, не влияет на результат.CONCAT(0x7e, ..., 0x7e)— объединяет символ~(0x7e) с полезной нагрузкой, чтобы отделить данные в сообщении об ошибке.(SELECT (ELT(7520=7520,1)))— подзапрос, возвращающий 1, так как условие7520=7520истинно.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь возвращается 1.-- -— комментарий, обрезающий остаток оригинального запроса.
В результате MySQL попытается вычислить XPath-выражение ~1~, что вызовет ошибку XPATH syntax error: '~1~'. Это простейший пример. На практике вместо 1 подставляют подзапросы, извлекающие имена таблиц, колонок, пароли пользователей.
Примеры извлечения данных
Допустим, есть таблица users с колонками username, password. Злоумышленник может выполнить:
" OR EXTRACTVALUE(1, CONCAT(0x7e, (SELECT CONCAT(username, 0x3a, password) FROM users LIMIT 1), 0x7e))-- -
В ответе придёт ошибка с логином и паролем первого пользователя. Если в таблице несколько строк, можно перебирать их через LIMIT с смещением.
Однако есть ограничение: функция EXTRACTVALUE возвращает не более 32 символов. Для обхода используют SUBSTRING или MID.
Другие функции для error-based инъекций
Помимо EXTRACTVALUE, в MySQL есть UPDATEXML(), которая работает аналогично. Также существуют методы, основанные на делении на ноль, неверных типах данных и т.п. Но EXTRACTVALUE и UPDATEXML наиболее популярны из-за простоты и наглядности.
Важно: в MySQL 5.7+ и в MariaDB эти функции всё ещё доступны, но в новых версиях (MySQL 8.0) они помечены как устаревшие и могут быть удалены в будущем. Тем не менее, на многих серверах они работают.
Как защититься от SQL-инъекций через EXTRACTVALUE
Основной способ защиты — использование параметризованных запросов (prepared statements). Это исключает возможность внедрения SQL-кода, так как данные передаются отдельно от структуры запроса.
- Параметризация: Всегда используйте подготовленные выражения в PDO, mysqli или ORM.
- Экранирование: Если параметризация невозможна, применяйте функции экранирования (mysqli_real_escape_string), но это менее надёжно.
- Валидация ввода: Проверяйте типы данных, ограничивайте длину, используйте белые списки.
- Минимизация привилегий: Учётная запись БД для веб-приложения не должна иметь прав на чтение системных таблиц или выполнение опасных функций.
- Отключение вывода ошибок: Не показывайте пользователям сообщения об ошибках СУБД — это лишает атакующего обратной связи.
- WAF: Веб-приложения могут быть защищены с помощью Web Application Firewall, который блокирует подозрительные запросы.
Также рекомендуется регулярно обновлять СУБД и фреймворки, проводить аудит кода и пентесты.
Заключение
SQL-инъекция через EXTRACTVALUE — это мощный инструмент в руках злоумышленника, позволяющий извлекать данные из базы через сообщения об ошибках. Понимание механизма работы помогает разработчикам осознать важность защиты. Используйте параметризованные запросы, ограничивайте права БД и не выводите ошибки пользователю — это сведёт риск к минимуму.
Комментарии
—Войдите, чтобы оставить комментарий