В этом посте хотел бы рассмотреть необычное решение, которое я нашел в процессе выполнения CTF таска "Соленый огурец" из веба на платформе Codeby Games.
1. Открываем указанный iport в браузере и перед нами открывается простое веб приложение для создания заметок.
2. В самом начале на странице с заданием можно было скачать исходники к этому приложению. После того как архив скачался, заглянем в app.py: видно что это приложение на фласке; стоит обратить внимание на маршрут "/add_none" - интересным моментом является то, что введенная заметка сериализируется (метод dumps) с помощью модуля pickle, затем кодировка base64 и потом сохраняется в куки с названием "notes". Для вывода заметки производятся обратные действия: из куки декодировка base64 и затем десериализация (метод loads).
3. Таким образом можно предположить, что если "завернуть" нужные нам команды с помощью pickles, закодировав полученный результат с помощью base64, и передать их в кукис, то можно добиться удаленного выполенния кода. Далее пришлось полазить по Интернету в поисках каких-либо подсказок насчет данной ситуации. Во всех случаях, которые мне попались, люди переопределяли метод __reduce__() внутри какого-либо класса, вызывая выполнение системных команд. Справедливо было бы спросить почему именно этот метод. Почитав докуметацию к pickles, надеюсь, я правильно понял, что метод __reduce__() является частью протокола сериализации Python, который позволяет объектам определить специальную логику для их сериализации и десериализации; когда объект передается функции pickle.dump() или pickle.dumps(), модуль pickle проверяет, есть ли у объекта метод __reduce__(). Если такой метод определен, то вызывается __reduce__(), который должен вернуть кортеж из функции, класса или строки и аргументов, которые будут использоваться для создания объекта при его десериализации. В нашем случае, когда переопределяется метод __reduce__(), вызывается команда из терминала.
Для проверки я сделал тестовую программу которая сериализует класс Inject c методом __reduce__() (внутри c помощью subprocess.check_output, которая сохраняет stdout, попробуем вывести текущего пользователя):
Запустим данный скрипт и получим закодированный в base64 сериализованный объект: "gASVLwAAAAAAAACMCnN1YnB......"
Скопируем вывод и всавим его прямо в кукис notes и обновим страницу:
Получим такой вывод - похоже на посимаолный вывод ascii кодов в десятеричной с.к. Воспользовавшись таблицой ascii, можно легко сопоставить 114 - 'r', 111 - 'o', 116 - 't', 10 - это управляющий символ. То есть мы под root'ом. Таким образом мы достигли PoC. Можно двигаться дальше. Для удобства сделаем программу на python котороая будет переводить ascii коды в привычные нам символы:
4. Теперь попробуем вывести все доступные файлы в текущей директории:
Получаем наш новый кукис и вставляем его в Cookie Editor:
Скопируем эти коды и декодируем их с помощью написанной ранее программы:
Отлично, теперь аналогичным образом прочитаем файл с флагом:
Результат:
Декодируем:
Готово, флаг найден.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Я сказал вначале, что решение необычное, потому что насколько я знаю это задание нужно было решать через реверс шелл (в интернете все передавли как пейлоад именно netcat reverse shell):
Но если я правильно понимаю, для реверс шелла нужен белый ip (если мы не в одной локальной сети, конечно): ведь по сути это машина жертвы должна инициировать соединение, а атакующий - открыть определенный порт и слушать.
То есть самое главное, что я хотел спросить, что обычно делается если нужно начать реверс шелл: покупается в vps, проброс портов на роутере или может есть какие-то сервисы, чтобы разово принять такое соединение?
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Благодарю за внимание. Надеюсь получить ответ на вопрос выше. В ctf играх я недавно поэтому, если где что не так сказал - не судите строго.
1. Открываем указанный iport в браузере и перед нами открывается простое веб приложение для создания заметок.
2. В самом начале на странице с заданием можно было скачать исходники к этому приложению. После того как архив скачался, заглянем в app.py: видно что это приложение на фласке; стоит обратить внимание на маршрут "/add_none" - интересным моментом является то, что введенная заметка сериализируется (метод dumps) с помощью модуля pickle, затем кодировка base64 и потом сохраняется в куки с названием "notes". Для вывода заметки производятся обратные действия: из куки декодировка base64 и затем десериализация (метод loads).
3. Таким образом можно предположить, что если "завернуть" нужные нам команды с помощью pickles, закодировав полученный результат с помощью base64, и передать их в кукис, то можно добиться удаленного выполенния кода. Далее пришлось полазить по Интернету в поисках каких-либо подсказок насчет данной ситуации. Во всех случаях, которые мне попались, люди переопределяли метод __reduce__() внутри какого-либо класса, вызывая выполнение системных команд. Справедливо было бы спросить почему именно этот метод. Почитав докуметацию к pickles, надеюсь, я правильно понял, что метод __reduce__() является частью протокола сериализации Python, который позволяет объектам определить специальную логику для их сериализации и десериализации; когда объект передается функции pickle.dump() или pickle.dumps(), модуль pickle проверяет, есть ли у объекта метод __reduce__(). Если такой метод определен, то вызывается __reduce__(), который должен вернуть кортеж из функции, класса или строки и аргументов, которые будут использоваться для создания объекта при его десериализации. В нашем случае, когда переопределяется метод __reduce__(), вызывается команда из терминала.
Для проверки я сделал тестовую программу которая сериализует класс Inject c методом __reduce__() (внутри c помощью subprocess.check_output, которая сохраняет stdout, попробуем вывести текущего пользователя):
Запустим данный скрипт и получим закодированный в base64 сериализованный объект: "gASVLwAAAAAAAACMCnN1YnB......"
Скопируем вывод и всавим его прямо в кукис notes и обновим страницу:
Получим такой вывод - похоже на посимаолный вывод ascii кодов в десятеричной с.к. Воспользовавшись таблицой ascii, можно легко сопоставить 114 - 'r', 111 - 'o', 116 - 't', 10 - это управляющий символ. То есть мы под root'ом. Таким образом мы достигли PoC. Можно двигаться дальше. Для удобства сделаем программу на python котороая будет переводить ascii коды в привычные нам символы:
4. Теперь попробуем вывести все доступные файлы в текущей директории:
Получаем наш новый кукис и вставляем его в Cookie Editor:
Скопируем эти коды и декодируем их с помощью написанной ранее программы:
Отлично, теперь аналогичным образом прочитаем файл с флагом:
Результат:
Декодируем:
Готово, флаг найден.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Я сказал вначале, что решение необычное, потому что насколько я знаю это задание нужно было решать через реверс шелл (в интернете все передавли как пейлоад именно netcat reverse shell):
Но если я правильно понимаю, для реверс шелла нужен белый ip (если мы не в одной локальной сети, конечно): ведь по сути это машина жертвы должна инициировать соединение, а атакующий - открыть определенный порт и слушать.
То есть самое главное, что я хотел спросить, что обычно делается если нужно начать реверс шелл: покупается в vps, проброс портов на роутере или может есть какие-то сервисы, чтобы разово принять такое соединение?
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Благодарю за внимание. Надеюсь получить ответ на вопрос выше. В ctf играх я недавно поэтому, если где что не так сказал - не судите строго.
Вложения
Последнее редактирование модератором: