Типы SQLi
Существует 5 основных типов SQL инъекций:
- Классическая (In-Band или Union-based). Самая опасная и редко встречающаяся сегодня атака. Позволяет сразу получать любые данные из базы.
- Error-based. Позволяет получать информацию о базе, таблицах и данных на основе выводимого текста ошибки СУБД.
- Boolean-based. Вместо получения всех данных, атакующий может поштучно их перебирать, ориентируясь на простой ответ типа true/false.
- Time-based. Похожа на предыдущую атаку принципом перебора, манипулируя временем отклика базы.
- Out-of-Band. Очень редкие и специфические типы атак, основанные на индивидуальных особенностях баз данных.
Далее мы разберем их детальней.
Уязвимые точки
Уязвимые точки для атаки находятся в местах, где формируется запрос к базе: форма аутентификации, поисковая строка, каталог, REST-запросы и непосредственно URL.
Защита от SQLi
Для каждого сервера и фреймворка есть свои тонкости и лучшие практики, но суть всегда одинакова.
Нельзя вставлять данные в запрос напрямую. Всегда обрабатывайте ввод отдельно и формируйте запрос исключительно из безопасных значений.
Создавайте белые списки: их значительно труднее обойти, чем черные. Все названия таблиц, полей и баз должны быть заданы конкретными значениями в вашей программе. Это касается и операторов.
Естественно, не забывайте про ограничение прав доступа к базе.
Тем не менее, кибербезопасность – это тот случай, когда понимание принципов нападения – лучший способ защиты.
Классические атаки
Самый простой пример критически уязвимого для SQLi кода выглядит следующим образом:
Представляя такой антипример, можно понять принцип действия атак, которые мы рассмотрим ниже.
Комментирование
Использование однострочных комментариев позволяет игнорировать часть запроса, идущую после вашей инъекции. Например, ввод в уязвимое поле Username запроса admin'-- позволит зайти на ресурс под администратором, потому что поверка пароля будет закомментирована. Конечно, сейчас такой тип уязвимости встречается очень редко, но помнить о ней стоит.
Многострочные комментарии могут справится с проверкой или определить тип базы данных. Например, подобные запросы обойдут примитивный текстовый анализ:
А некоторые особые комментарии позволят определить тип базы данных в целях дальнейшей эксплуатации уязвимостей:
Манипуляции со строками
Существует ряд более продвинутых способов обходить черные списки. Например, против фильтра кавычек можно использовать конкатенацию строк:
В MySQL для обхода сложных паттернов можно представлять строки в шеснадцатиричном виде, с помощью функции HEX()
или вводить их посимвольно:
Обход аутентификации
Есть стандартный словарь, содержащий в себе основные запросы, для обхода уязвимой формы аутентификации. Впервые его опубликовали лет 10 назад и регулярно дополняют. Не забудьте прогнать через него формы регистрации на своем сайте:
Union injection
UNION это SQL-команда, позволяющая вертикально комбинировать данные из разных таблиц в одну. Это одна из самых популярных и опасных классических инъекций.
Допустим, на сайте есть список товаров с уязвимой строкой поиска. Тогда, подобрав правильное количество колонок и определив их название, через UNION можно вывести практически любые данные.
Последовательные запросы
Если целевой сервис работает на SQL Server и ASP/PHP, либо на PostgreSQL и PHP, можно использовать простой знак ';' для последовательного вызова вредоносных запросов:
Возможный урон
Конкретных примеров и нюансов довольно много, не будем перечислять все. Главное, помните, что комбинируя эти приёмы и различные специфические функции, атакующий может получить полный доступ к базе и даже командной строке.
Error-Based
Чтобы побороть этот тип атак, достаточно запретить вывод ошибок на проде. Тем не менее, давайте на примере разберем, чем вам может грозить игнорирование этой меры.
Последовательное выполнение следующих запросов к SQL Server, позволит определить в тексте ошибки названия столбцов:
Слепые инъекции
В более-менее хорошо сделанном приложении атакующий не увидите ни ошибок, ни результата UNION-атаки. Тут приходит очередь действовать вслепую.
Условные выражения
Атаки с использованием IF и WHERE – основа слепого метода. Они являются одной из причин, почему используемые вами операторы должны быть закодированы в программе, а не генерироваться абы как. Синтаксис для разных баз будет отличаться:
Boolean-based
Если атакующий все же может получить информацию о наличии или отсутствии ошибки из HTTP-статуса, в сервисе имеется уязвимость к обычной слепой атаке. Рассмотрим запрос, который позволит нам при помощи алгоритма бинарного поиска посимвольно определить название первой таблицы и в дальнейшем всех данных:
Time-Based
Если атакующий не наблюдает никаких отличий в ответах сервера, остается полностью слепая атака. Примером будет использование функций SLEEP или WAIT FOR DALAY:
Конечно, реальные примеры будут выглядеть примерно как boolean-based, только true
и false
атакующий будет отличать по времени отклика. Недостатки такого метода очевидны. Если выбрать слишком маленькую задержку, будет сильное влияние сторонних факторов типа пинга. Если слишком большую – атака займет очень много времени и её, скорее всего, остановят.
Конечно, по SQLi можно писать целые книги, но мы постарались объяснить ключевые принципы с примерами.
Комментарии