![]() |
В этом посте хотел бы рассмотреть необычное решение, которое я нашел в процессе выполнения CTF таска "Соленый огурец" из веба на платформе Antichat.
https://forum.antichat.xyz/attachmen...788b92d1dc.png 1. Открываем указанный iport в браузере и перед нами открывается простое веб приложение для создания заметок. https://forum.antichat.xyz/attachmen...7910167614.png 2. В самом начале на странице с заданием можно было скачать исходники к этому приложению. После того как архив скачался, заглянем в app.py: видно что это приложение на фласке; стоит обратить внимание на маршрут "/add_none" - интересным моментом является то, что введенная заметка сериализируется (метод dumps) с помощью модуля pickle, затем кодировка base64 и потом сохраняется в куки с названием "notes". Для вывода заметки производятся обратные действия: из куки декодировка base64 и затем десериализация (метод loads). https://forum.antichat.xyz/attachmen...b1a46e8695.png 3. Таким образом можно предположить, что если "завернуть" нужные нам команды с помощью pickles, закодировав полученный результат с помощью base64, и передать их в кукис, то можно добиться удаленного выполенния кода. Далее пришлось полазить по Интернету в поисках каких-либо подсказок насчет данной ситуации. Во всех случаях, которые мне попались, люди переопределяли метод __reduce__() внутри какого-либо класса, вызывая выполнение системных команд. Справедливо было бы спросить почему именно этот метод. Почитав докуметацию к pickles, надеюсь, я правильно понял, что метод __reduce__() является частью протокола сериализации Python, который позволяет объектам определить специальную логику для их сериализации и десериализации; когда объект передается функции pickle.dump() или pickle.dumps(), модуль pickle проверяет, есть ли у объекта метод __reduce__(). Если такой метод определен, то вызывается __reduce__(), который должен вернуть кортеж из функции, класса или строки и аргументов, которые будут использоваться для создания объекта при его десериализации. В нашем случае, когда переопределяется метод __reduce__(), вызывается команда из терминала. Для проверки я сделал тестовую программу которая сериализует класс Inject c методом __reduce__() (внутри c помощью subprocess.check_output, которая сохраняет stdout, попробуем вывести текущего пользователя): https://forum.antichat.xyz/attachmen...7913014602.png Запустим данный скрипт и получим закодированный в base64 сериализованный объект: "gASVLwAAAAAAAACMCnN1YnB......" Скопируем вывод и всавим его прямо в кукис notes и обновим страницу: https://forum.antichat.xyz/attachmen...7913226412.png Получим такой вывод - похоже на посимаолный вывод ascii кодов в десятеричной с.к. Воспользовавшись таблицой ascii, можно легко сопоставить 114 - 'r', 111 - 'o', 116 - 't', 10 - это управляющий символ. То есть мы под root'ом. Таким образом мы достигли PoC. Можно двигаться дальше. Для удобства сделаем программу на python котороая будет переводить ascii коды в привычные нам символы: https://forum.antichat.xyz/attachmen...7913553766.png 4. Теперь попробуем вывести все доступные файлы в текущей директории: https://forum.antichat.xyz/attachmen...7913704020.png Получаем наш новый кукис и вставляем его в Cookie Editor: https://forum.antichat.xyz/attachmen...7913835613.png Скопируем эти коды и декодируем их с помощью написанной ранее программы: https://forum.antichat.xyz/attachmen...7913928951.png Отлично, теперь аналогичным образом прочитаем файл с флагом: https://forum.antichat.xyz/attachmen...7914009150.png Результат: https://forum.antichat.xyz/attachmen...7914453774.png Декодируем: https://forum.antichat.xyz/attachmen...7914591436.png Готово, флаг найден. --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Я сказал вначале, что решение необычное, потому что насколько я знаю это задание нужно было решать через реверс шелл (в интернете все передавли как пейлоад именно netcat reverse shell): https://forum.antichat.xyz/attachmen...7914870292.png Но если я правильно понимаю, для реверс шелла нужен белый ip (если мы не в одной локальной сети, конечно): ведь по сути это машина жертвы должна инициировать соединение, а атакующий - открыть определенный порт и слушать. То есть самое главное, что я хотел спросить, что обычно делается если нужно начать реверс шелл: покупается в vps, проброс портов на роутере или может есть какие-то сервисы, чтобы разово принять такое соединение? --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Благодарю за внимание. Надеюсь получить ответ на вопрос выше. В ctf играх я недавно поэтому, если где что не так сказал - не судите строго. |
Также реализовал, только в одно сплоите:
Python: Код:
importЦитата:
|
Да, у вас более красивое решение. За ngrok - спасибо, как раз ждал чего-то подобного. Так как сервер или порт форвардинг слишком замудренно для заданий легкого уровня.
|
Цитата:
Цитата:
|
А я подупоролся)
Через subprocess и system не получил выводов и решил заабузит код инжект aka SSTI. Python: Код:
def |
Отличное решение
|
| Время: 16:16 |