The Bandit Surfer
The Bandit Yeti is surfing to town.

TryHackMe: Прохождение комнаты The Bandit Surfer. Заключительная часть побочного квеста Advent of Cyber 2023.
Просканируем с помощью nmap
все порты (-p-
) цели в ускоренном режиме (-T4
) и с отображением версий (-sV
) сервисов:

Проверим доступ по ssh, там вход закрыт и доступен только по ключам. Изучим веб-сервис на 8000
порту – это некое приложение в раннем доступе для скачивания изображений. Ссылка на скачивание выглядит следующим образом: http://$RHOST:8000/download?id=xx
.
принимает целочисленный параметр
id
если указать неверное значение, получаем трассировку с сообщением об ошибке.
What is the user flag?
Из ошибки, как и из результатов сканирования следует, что веб-приложение использует Werkzeug. Данная библиотека хорошо известна и имеет в наличии консоль с доступом к python’у для отладки приложения. Попробуем открыть данный адрес: http://$RHOST:8000/console
. Как и ожидалось, там располагается панель для отладки, но она защищена неизвестным пин-кодом. Откроем исходный код библиотеки и посмотрим как генерируется данный пин-код, а конкретно функция get_pin_and_cookie_name()
. Самое интересное это то, какие данные используются в алгоритме:
=
=
username
– имя пользователя, его видно в трассировке как часть директории.modname
–flask.app
getattr(app, "__name__", type(app).__name__)
–Flask
getattr(mod, "__file__", None)
– абсолютный путь к приложению, его так же видно из трассировки (/home/#redacted#/flask/app.py
).uuid.getnode()
– mac-адрес машины.get_machine_id()
– для разных ОС считается разными способами, в случае нашей машины, а это линукс, гарантировано берется значение из/etc/machine-id
, а так же опционально возможно это значение нужно сложить со значением из/proc/sys/kernel/random/boot_id
и строкой после последнего символа/
из первой строки в файле/proc/self/cgroup
.
Итого первые четыре значения имеются сразу, необходимо узнать мак-адрес и идентификатор машины.
Вернемся к ссылке для скачивания изображений. Проверим её на SQL-инъекции:
Получим перечень обнаруженных возможных типов инъекций: слепая, основанная на ошибках, на временны́х задержках, с запросом на объединение.
Сдампим содержимое базы:
Database: elfimages
+---------------------------------------+
| elves |
+---------------------------------------+
Database: elfimages
Table: elves
+----+--------+------------------------------------------------+
| id | url_id | url |
+----+--------+------------------------------------------------+
| 1 | 1 | http://127.0.0.1:8000/static/imgs/mcblue1.svg |
| 2 | 2 | http://127.0.0.1:8000/static/imgs/mcblue2.svg |
| 3 | 3 | http://127.0.0.1:8000/static/imgs/mcblue3.svg |
| 4 | 4 | http://127.0.0.1:8000/static/imgs/suspects.png |
+----+--------+------------------------------------------------+
Ничего примечательного нет, судя по всему, приложение работает довольно примитивно: берет идентификатор url_id
и выдает файл по соответствующему полю url
. Попробуем осуществить подделку запроса на стороне сервера (SSRF), сделав такой запрос в результате которого значение url
будет подменено нашим.
://10.10.89.98:8000/ ?=
Запрос работает, получаем файл /etc/machine-id
. Повторим то же самое для /sys/class/net/eth0/address
и получим mac-адрес.
Теперь имеется полный набор данных необходимых для генерации пин-код:
=
=
=
continue
=
= None
=
= None
=
break
=
Получив пин-код теперь можно успешно авторизоваться в отладочной консоли Werkzeug. Для удобства сразу добавим свой ssh-ключ на сервер:
Ключи можно сгенерировать при помощи команды
ssh-keygen
, после чего необходимо передать содержимое файлаid_rsa.pub
Теперь можно комфортно подключиться, первый флаг (user.txt
) сразу же в домашней директории:

What is the root flag?
What is the yetikey4.txt
flag?
Проверим веб-приложение (~/app
), там можно обнаружить git-репозиторий, если посмотреть историю коммитов (git log
), то находится интересный коммит с заголовком “Changed MySQL user”. Изучим его:
diff --git a/app.py b/app.py
index 5f5ff6e..875cbb8 100644
-app.config['MYSQL_PASSWORD'] = '#redacted#'
+app.config['MYSQL_PASSWORD'] = 'fSXT8582GcMLmSt6'
app.config['MYSQL_DB'] = 'elfimages'
mysql = MySQL(app)
# MySQL configuration
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'mcskidy'
Получаем старый и новый пароль пользователя в MySQL. Высока вероятность, что один из них может являться действующим паролем в системе. Пробуем старый, он является действующим:
Пользователю доступен для запуска некий скрипт от имени root пользователя. Внимательно изучим данный скрипт:
#!/bin/bash
WEBSITE_URL="http://127.0.0.1:8000"
response=
# Check the HTTP response code
if [; then
else
fi
Скрипт проверяет работу веб-приложения и на первый взгляд ничем не может помочь в эскалации привилегий. Однако он импортирует /opt/.bashrc
. Изучим данный скрипт. На первый взгляд он выглядит как стандартный .bashrc
, но сравним с эталонным:
< enable -n [ # ]
>
Отличия все же имеются, отменяется использование встроенной команды [
. А данная команда используется в скрипте, можно подменить её на свою. Создадим исполняемый файл [
единственной задачей которого будет передача управления оболочке (/bin/bash
) и запустим скрипт /opt/chech.sh
от имени root
пользователя:
На этом всё,
первые части прохождений здесь.