Что такое SQL-инъекция и как она работает
SQL-инъекция (SQL injection) — один из самых распространённых способов атаки на веб-приложения. Злоумышленник внедряет в пользовательский ввод специальные конструкции, которые меняют логику выполняемого SQL-запроса. В результате можно получить доступ к данным, которые не должны отображаться, или даже выполнить произвольные команды на сервере.
Запрос, который мы разбираем: ')) AND EXTRACTVALUE(5896,CONCAT(0x7e,((SELECT (ELT(5896=5896,1)))),0x7e))-- - — типичный пример инъекции, использующей ошибки СУБД MySQL для извлечения информации. Такая техника называется error-based SQL injection.
Расшифровка отдельных частей запроса
1. Закрывающие скобки и кавычки
Начинается строка с ')). Это попытка «закрыть» существующий запрос, чтобы внедрить свой код. Обычно в уязвимом приложении запрос формируется примерно так: SELECT * FROM users WHERE name = ('$input'). Подставляя ')), атакующий завершает исходную конструкцию и добавляет свою.
2. Оператор AND и функция EXTRACTVALUE
Далее идёт AND EXTRACTVALUE(5896,CONCAT(...)). EXTRACTVALUE — встроенная функция MySQL, которая извлекает значение из XML-строки. Синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может оказаться переданная строка. Это и используется для вывода данных.
Первый аргумент — 5896 — просто число, которое не влияет на результат, но должно быть допустимым XML-фрагментом (число интерпретируется как текст). Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(5896=5896,1)))), 0x7e) — конкатенация тильды (0x7e — шестнадцатеричный код символа ~), результата подзапроса и ещё одной тильды.
3. Подзапрос с ELT
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(5896=5896, 1). Выражение 5896=5896 всегда истинно, то есть равно 1. Значит, ELT возвращает первый элемент — 1. Это простейшая проверка, которая может быть заменена на любую другую логику, например, на извлечение имени пользователя или хеша пароля.
В реальной атаке вместо 1 могло бы стоять что-то вроде (SELECT password FROM users LIMIT 1). Тогда ошибка EXTRACTVALUE содержала бы этот пароль.
4. Комментарий в конце
Символы -- - — это комментарий в MySQL (пробел после двух дефисов обязателен). Он «отрезает» оставшуюся часть исходного запроса, чтобы синтаксис стал корректным.
Зачем злоумышленник использует такую конструкцию
Основная цель — заставить сервер вернуть сообщение об ошибке, содержащее конфиденциальные данные. Например, если заменить ELT(5896=5896,1) на подзапрос, возвращающий версию базы данных или имя текущего пользователя, эти сведения появятся в тексте ошибки. Затем атакующий может извлекать данные посимвольно или целыми строками, в зависимости от настроек.
Подобные инъекции часто встречаются в старых приложениях, где пользовательский ввод напрямую конкатенируется с SQL-запросом без экранирования.
Как защититься от SQL-инъекций
- Использовать подготовленные выражения (prepared statements). Это самый надёжный способ: параметры передаются отдельно от текста запроса, и внедрить код невозможно.
- Применять ORM или библиотеки для работы с БД, которые автоматически экранируют данные.
- Ограничить права пользователя базы данных. Приложение должно работать под учётной записью с минимально необходимыми привилегиями.
- Включить логирование ошибок, но не выводить их пользователю. Сообщения об ошибках должны попадать в лог, а не на страницу.
- Регулярно проводить аудит кода и сканирование уязвимостей.
Важно понимать, что даже такая «безобидная» инъекция, как в примере, может быть первым шагом к полному захвату базы данных.
Вывод
Разобранный запрос — классическая error-based SQL-инъекция, эксплуатирующая функцию EXTRACTVALUE для вывода данных через сообщение об ошибке. Понимание механики таких атак помогает разработчикам правильно выстраивать защиту. Никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий