Skip to content

Latest commit

 

History

History
74 lines (45 loc) · 4.25 KB

README.md

File metadata and controls

74 lines (45 loc) · 4.25 KB

Web | hard | OnlyTweets

Информация

Нам попал в руки прототип будущей соц-сети от экс-сотрудников Твиттера. Еще не все функции реализованы, но можно заценить.

Администратор новой соцсети даже запостил там флаг.

Деплой

Поменять LOGIN_URL config.env на публичный адрес http://<ip>:4321/login (необязательно).

cd deploy
docker-compose -p web_onlytweets up --build -d

Выдать участинкам

Архив из директории public/ и IP:PORT сервера

Описание

Идея задачи - эксплуатация CSRF с включенными CSRF-токенами.

На сайте есть возможность делиться твитами и есть бот, который ходит по ссылкам.

В задаче есть XSS, но его эксплуатация должна быть невозможной из-за CSP.

Решение

Перед нами типичный таск на XSS: есть платформа, на платформе есть бот, ходящий по ссылкам от участников.

Важно заметить, что бот использует firefox, а не Chromium-based браузер.

После просмотра кода можно найти XSS, однако ее эксплуатация маловероятна.

Тогда можно вспомнить про другую client-side атаку - CSRF. Для нее у нас есть несколько важных составляющих:

  1. У нас есть возможность отправить бота на любую страницу (не только на страницы приложения).
  2. Бот использует firefox, а на сервере не указана SameSite policy, из-за чего CSRF с другого домена возможен.
  3. В приложении есть функционал 'поделиться' постом. Мы знаем ID поста админа, можем заставить его поделиться с нами постом.

Проблема в том, что в задании используется защита от CSRF с использованием CSRF-токенов.

Можно заметить что в задании нестандартно используется фреймворк Flask:

  1. Вместо request.form/request.args всегда используется request.values (получить значение либо из body, либо из URL).
  2. Обработчики GET/POST запросов сначала проверяют что пришел GET-запрос.

Flask, как и многие другие веб-фреймворки, обрабатывает HEAD-запросы, если обработчик уже поддерживает GET-запросы.

Тогда, если мы отправим HEAD-запрос с нужными нам URL-параметрами(?share_to=ouruser&tweet_id=1), то условие if request.method == 'GET' не выполнится и будет вызван код для шэринга твита. Так как в обработчике используется request.values, то параметры будут взяты из URL.

CSRF-защита не сработает на такой запрос, т.к. обычно работает только на POST/PUT/DELETE.

Решение:

  1. Создать HTML-файл, в котором выполнить JS, отправляющий HEAD-запрос с нужными параметрами на backend:4321/share. Тем самым заставить бота поделиться с нами его флагом.
  2. Отправить ссылку на HTML-файл боту.
  3. Прочитать флаг, который будет в приватной ленте.

Payload

Флаг

CUP{bb1f209d615d1f6338170c4105965a}