Приветствую! На этот раз посмотрим на интересную таску с уязвимостью SQLi и рассмотрим технику обхода внутренней защиты хоста.
Приятного изучения!
Способ решения №1
Начнём с того, что осмотримся на хосте. При входе на задачку мы видим вполне стандартную форму авторизации.
Я попробовал различные дефолтные креды, но не думаю, что на задании с уровнем "Сложно" такое прокатит.
В таком случае создаю новую учётку и идём ресёрчить сайт дальше.
При входе нас встречает вот такой замечательный игровой автомат.
Что-то мне подсказывает, что тут нужно выбить 777, но я не фартовый и иду к цели другим способом :)
Попробуем дёрнуть ручку и перехватить запрос в Burb Suite:
Итак, в запросе есть параметр result, где указан наш результат вращения автомата и хэш. Попробуем изменить значение result:
Угу, внутренняя защита не даёт этого сделать и сразу детектит взлом. Нужно поизучать как хэш тут обыгран. Для этого заходим во вкладку Network в Инструментарии разработчика и смотрим какие файлы прилетают к нам при обновлении страницы:
Файл slot.js показался мне интересным. Посмотрим что там такого:
Внутри есть функция, которая связана с алгоритмами хэширования, однако код обфусцирован разработчиком для более трудного анализа.
Зайдём на соответствующий ресурс для деобфускации.
Итак, теперь мы знаем как образуется тот самый хэш в result. Для более удобной эксплуатации напишу скрипт на питоне.
Попробуем вставить хэш, сформированный со значения "777".
Джекпот и верный хэш дали нам учётную запись admin. Железобетонно, что хост берёт результаты с какой-то БД. Именно поэтому нам нужно искать тут инъекцию.
Посмотрим как хост реагирует на кавычку(не забываем про новый хэш, который будет сформирован с новым значением):
Код 500 говорит нам о том, что всё отлично и хост уязвим к SQLi. Сделаем простую инъекцию:
Разбор:
SQLi: 9999' or 1=1-- -
Кавычка закрывает значение result и за этим следует оператор ИЛИ 1=1, что всегда истинно. После -- - запрос не читается бекендом т.к. всё, что ними считается закомментированным. Если одно из значений будет истинно, то нам выдадут учётку admin в best result.
Нам успешно выдало учётку admin. Значит инъекция сработала. Пробуем достать username и password:
Разбор:
SQLi: 9999' union select username from users where id=1-- -
Т.к. у нас и так бекенд при "9999" делает запрос SELECT и мы совершаем поиск по таблице, то нужно объединить эти запросы при помощи UNION. Раз уж колонка в двух таблицах одна, то ошибки не возникнет. Далее происходит обычный запрос username c таблицы USERS при условии, что в столбике id значение равно 1. После чего всё комментируется.
Разбор:
SQLi: 9999' union select password from users where id=1-- -
Аналогично предыдущему запросу, но вытаскиваем password
Примечание:
Код слота 9993 я использую т.к. на 777 есть какой-то фильтр в таких запросах. Если подставить null или любое другое число, то всё сработает. Это заставило меня долго изучать что мешало решить таск.
Итак, username и password у нас в кармане, осталось только ввести их и флаг у нас в кармане.
Способ решения №2
Хочу показать ещё один способ решения таска, но чуть проще при помощи sqlmap.
Во флаг --eval я вставил тот питоновский код, но только убрал значение result т.к. мы его подменяем в request. В request.txt указал запрос, который получали при дёргании ручки. Указываем --level и --risk максимально возможными и для выгрузки БД --dump-all.
Запускаем!
Немного через время параметр result будет найден как подверженный к инъекции.
Таким образом мы получили те же креды, но уже при помощи инструмента sqlmap.
Победа!
Выводы
Защита от подмены значений, построенная таким образом выглядит дико ненадёжно. Хорошим решением было бы поставить фильтрацию на спец. символы ('-";) или слова и операторы, принадлежащие к SQL-командам (union, select...or, and...).
Также стоило бы выключить вывод ошибок базы данных, чтобы инъекцию было сложнее нащупать. Таким рекомендаций будет достаточно для защиты хоста с ненадёжной авторизацией. На этом по части безопасности всё!
Задача заняла у меня достаточно времени, сил и нервов, но оно того стоило. В итоге, я получил два вектора решения и опыт в нахождении инъекций. Мне было дико приятно делиться своим решением данного таска.
Спасибо за внимание! Всех благ!