Error-Based SQL injection в MySQL

3 комментария

SQL injectionЧто такое SQL инъекцию сегодня наверное знает каждый второй ребенок. Error-Based — уже менее знакомый термин, но все же так же прост для понимания.

На всякий случай попробую объяснить. В некоторых ситуациях инъекция происходит в запросе который непосредственно не выводит никаких данных на страницу, либо же вообще никак не влияет на вывод. И если в первом случае данные из базы можно извлечь относительно просто, используя IF, косвенно влияя на вывод страницы, и тем самым прибегнув к бинарному поиску. То вот во втором случае — все очень грустно, бинарный поиск, как правило, основывался на конструкции SLEEP и замере времени ответа, что давало огромные задержки на вывод данных через эту инъекцию.

Следующей вехой в развитии этой атаки стал вектор Error-Based. Он основывается на выводе информации в тексте ошибки выполнения запроса. Как вы понимаете, для этого нужен прямой вывод текста ошибки на саму страницу. Да я согласен, это бывает не часто, и вообще за вывод ошибок на продакшене нужно жестоко карать. Но если вам повезло, то это поможет существенно сократить время атаки.

Duplicate entry

Наверное это один из самых популярных векторов атаки. Его предложил некто Qwazar еще в лохматые года. Выглядит он вот так:

Потом этот способ дорабатывали все кому не лень (забегу немного вперед, в т.ч. и я), в итоге самый оптимальный и короткий запрос на сегодняшний день выглядит вот так:

Так например, такой запрос:

Выведет вот такую вот ошибку:
Duplicate entry '5.5.25-log' for key 'group_key'
Как видно — мы смогли передать в текст ошибки нужные нам данные, что существенно ускорит нашу атаку в дальнейшем. Ограничение — за один запрос выведется не более 64 символов.

Почему это работает

Ошибка переполнения типа данных

Подробнее здесь. Буду краток, вектор выглядит вот так:

Пример ошибки:
BIGINT value is out of range in '(('5.5.25-log' is not null) - -(9223372036854775808))'
Данный способ покруче предыдущего так как позволяет вывести аж 475 символов вместо 64, но говорят что работает не на всех версиях MySQL. Проверить это у меня возможности нет, поэтому оставлю это на совести авторов. По крайней мере на версии 5.5 это работает точно.

Еще похожая вариация:

Это выдаст вот такую ошибку:
'((not((select 'root@localhost' from dual))) - ~(0))'

Гео-функции

Появились только в MySQL >= 5.7.5

Удобно, но 5.7.5 — это большая редкость на сегодняшний день. Тут я это наверное привел только ради того чтобы предложить альтернативу, предыдущим техникам и разбавить статью. Вряд ли это кто то применит на практике.

Заключение

Основной акцент в статье был сделан на то почему работает «Duplicate key»-метод (ради того чтобы не потерять мой пост отсюда), т.к. этот метод порой вызывает огромное недоумение. Ну а в целом буду собирать здесь все известные мне методы данной атаки.

Благодарю за внимание.

Добавить комментарий

Прочли запись? Понравилась? Не стесняйтесь, оставьте, пожалуйста, свой комментарий. Мне очень интересно, что вы думаете об этом. Кстати в комментарии вы можете задать мне любой вопрос. Я обязательно отвечу.

Вы можете оставить коментарий анонимно, для этого можно не указывать Имя и email. Все комментарии проходят модерацию, поэтому ваш комментарий появится не сразу.