面向已有域 + SQL Server 2014 实验环境的可执行测试方案。
完整 108 函数验收见 Acceptance-Tests.md;本文档聚焦当前已实现命令的首轮集成验证。
| 组件 | 你的环境 | 说明 |
|---|---|---|
| SQL Server | 2014(Developer / Standard / Express) | 覆盖 Batch 1 核心路径;部分 Batch 2 语法在 2014 上可用 |
| 域 | 已部署 DC + 至少 1 台域成员 SQL Server | 支持 Get-SQLInstanceDomain |
| 客户端 | 域成员 Windows 10/11 或 Server | 推荐在此运行测试脚本 |
| 网络 | 客户端可解析 SQL 主机名、UDP 1434 可达 | SQL Browser 服务需启用 |
| 工具 | PowerShell 5.1+、MSBuild / VS 2022 | 用于构建 dist\PowerUpSQLSharp.exe |
SQL 2014 不在最终验收文档的「2016/2019/2022」清单内,但开发阶段完全足够验证发现、连接、信息收集等核心逻辑。后续可在 AutomatedLab 环境补测多版本差异。
git clone https://github.com/lee-miya/PowerUpSQLSharp.git
cd PowerUpSQLSharp
git pull.\scripts\release.ps1产物:dist\PowerUpSQLSharp.exe(单文件,已通过 strip 验证)。
Copy-Item .\scripts\test-env.example.ps1 .\scripts\test-env.ps1
notepad .\scripts\test-env.ps1 # 填写 SqlInstance、SqlHost、sa 密码等同时编辑 scripts\instances.example.txt,将 SQL01 改为你的实例名(或复制为新文件并在 test-env.ps1 中引用)。
# 全量(Infra + Discovery + Connection + Recon + Batch2 + Batch3 + Batch4)
.\scripts\Run-IntegrationTests.ps1
# 仅 Batch 3 审计与 OS 命令执行
.\scripts\Run-IntegrationTests.ps1 -Category Batch3
# 仅 Batch 4 AD / 链接 / 提权 / Fuzz / DLL
.\scripts\Run-IntegrationTests.ps1 -Category Batch4
# 仅发现类
.\scripts\Run-IntegrationTests.ps1 -Category Discovery
# 已有 exe、跳过构建
.\scripts\Run-IntegrationTests.ps1 -SkipBuild报告输出:TestResults\integration-YYYYMMDD-HHmmss.json
- 全部通过 → 进入「对照测试」阶段(见第 4 节)
- 有失败 → 将 JSON 报告与失败命令的标准输出提交 issue
| ID | 命令 / 脚本 | 预期 | 自动化 |
|---|---|---|---|
| B1-080 | PowerUpSQLSharp.exe --help |
exit 0,列出已实现命令 | ✅ |
| B1-081 | 未知子命令 | exit 2 | ✅ |
| B1-083 | scripts\verify-strip.ps1 |
无路径泄露、PE 时间戳为 0 | ✅ |
| B1-084 | scripts\release.ps1(两次构建) |
SHA256 一致 | ✅(release 内置) |
在域成员客户端上执行(或在 SQL 主机上测 B1-001):
| ID | 命令 | 关键参数 | 预期 | 自动化 |
|---|---|---|---|---|
| B1-001 | Get-SQLInstanceLocal |
— | 本机有 SQL 则返回 Instance | ✅ |
| B1-003 | 同上 | --format json |
合法 JSON | ✅ |
| B1-010 | Get-SQLInstanceBroadcast |
--timeout 5 |
子网内可见实例(视网络而定) | ✅ |
| B1-011 | 同上 | --timeout 1 |
不挂死,exit 0 | ✅ |
| B1-020 | Get-SQLInstanceDomain |
— | 返回域内 MSSQL SPN | ✅ |
| B1-021 | 同上 | 非域机器 | 空结果 + 警告,exit 0 | ✅(非域时运行,域内 SKIP) |
| B1-004 | Get-SQLServiceLocal |
— | 返回本机 SQL 服务 | ✅ |
| B1-030 | Get-SQLInstanceFile |
-InstanceFile scripts\instances.example.txt |
解析文件内实例 | ✅ |
| B1-031 | 同上 | 不存在的文件 | exit 2 | ✅ |
| B1-040 | Get-SQLInstanceScanUDP |
-ComputerName <SqlHost> |
发现目标实例 | ✅ |
| B1-041 | Get-SQLInstanceScanUDPThreaded |
-ComputerName <SqlHost> --threads 5 |
与单线程结果一致 | ✅ |
手动补充(B1-002): 在本机无 SQL 的机器上运行 Get-SQLInstanceLocal,应返回空,exit 0。
手动补充(B1-021 域内): 域成员机上 B1-021 自动 SKIP;非域机见上表。
| ID | 命令 | 场景 | 预期 exit | 自动化 |
|---|---|---|---|---|
| B1-050 | Get-SQLConnectionTest |
正确 sa 凭据 | 0,Success=true | ✅ |
| B1-051 | 同上 | 错误密码 | 3 | ✅ |
| B1-052 | 同上 | 无 Username(Windows 集成) | 0 或 3(视当前用户权限) | ✅ |
| B1-053 | Get-SQLConnectionTestThreaded |
--threads 3 + sa |
0,含 Accessible | ✅ |
| B1-015 | Get-SQLLocalAdminCheck |
— | 0,含 IsLocalAdmin | ✅ |
示例:
.\dist\PowerUpSQLSharp.exe Get-SQLConnectionTest -Instance SQL01 -Username sa -Password "<密码>"
.\dist\PowerUpSQLSharp.exe Get-SQLConnectionTest -Instance SQL01| ID | 命令 | 预期输出字段 | 自动化 |
|---|---|---|---|
| B1-070 | Get-SQLServerInfo |
Version、CurrentLogin、IsSysadmin、XpCmdShellEnabled | ✅ |
| B1-072 | Get-SQLServerInfoThreaded |
同上,--threads 3 |
✅ |
| B1-060 | Get-SQLServerLoginDefaultPw |
exit 0(强密码环境无匹配) | ✅ |
| B1-071 | 与 PowerUpSQL 对照 | 关键字段语义一致 | 手动 |
# PowerUpSQLSharp
.\dist\PowerUpSQLSharp.exe Get-SQLServerInfo -Instance SQL01 -Username sa -Password "<密码>"
# PowerUpSQL 对照(需先 Import-Module PowerUpSQL)
Get-SQLServerInfo -Instance SQL01 -Username sa -Password "<密码>"在 SQL 2014 上验证已实现的 Recon / Priv / Dump 命令(需有效连接凭据)。exit 码允许 0 / 4 / 5(成功 / 权限不足 / 部分失败)。
| ID | 命令 | 说明 |
|---|---|---|
| B2-001 | Get-SQLDatabase |
枚举数据库 |
| B2-002 | Get-SQLTable |
枚举表 |
| B2-003 | Get-SQLServerConfiguration |
服务器配置 |
| B2-004 | Get-SQLSysadminCheck |
sysadmin 检查 |
| B2-005 | Get-SQLServerLogin |
登录账户 |
| B2-006 | Get-SQLStoredProcedureXp |
xp 扩展存储过程 |
| B2-007 | Get-SQLDatabaseThreaded |
多线程枚举数据库 |
| B2-008 | Get-SQLDatabaseUser |
数据库用户 |
| B2-009 | Get-SQLDatabaseSchema |
数据库架构 |
| B2-010 | Get-SQLDatabaseRole |
数据库角色 |
| B2-011 | Get-SQLDatabaseRoleMember |
角色成员 |
| B2-012 | Get-SQLDatabasePriv |
数据库权限 |
| B2-013 | Get-SQLTableTemp |
临时表 |
| B2-014 | Get-SQLColumn |
列信息 |
| B2-015 | Get-SQLColumnSampleData |
列采样(-DatabaseName master -NoOutput) |
| B2-016 | Get-SQLColumnSampleDataThreaded |
多线程列采样 |
| B2-017 | Get-SQLView |
视图 |
| B2-018 | Get-SQLStoredProcedure |
存储过程 |
| B2-019 | Get-SQLStoredProcedureCLR |
CLR 存储过程 |
| B2-020 | Get-SQLStoredProcedureSQLi |
潜在 SQLi 存储过程 |
| B2-021 | Get-SQLStoredProcedureAutoExec |
启动存储过程 |
| B2-022 | Get-SQLTriggerDdl |
服务器 DDL 触发器 |
| B2-023 | Get-SQLTriggerDml |
数据库 DML 触发器 |
| B2-024 | Get-SQLSession |
活动会话 |
| B2-025 | Get-SQLQuery |
自定义查询 |
| B2-026 | Get-SQLQueryThreaded |
多线程自定义查询 |
| B2-027 | Get-SQLServerPasswordHash |
登录哈希 |
| B2-028 | Get-SQLServerRole |
服务器角色 |
| B2-029 | Get-SQLServerRoleMember |
服务器角色成员 |
| B2-030 | Get-SQLServerPriv |
服务器权限 |
| B2-031 | Get-SQLServerCredential |
凭据 |
| B2-032 | Get-SQLServerPolicy |
服务器策略 |
| B2-033 | Get-SQLServiceAccount |
服务账户 |
| B2-034 | Get-SQLAgentJob |
Agent 作业 |
| B2-035 | Get-SQLAssemblyFile |
程序集文件 |
| B2-036 | Get-SQLOleDbProvder |
OLE DB 提供程序 |
| B2-037 | Get-SQLAuditDatabaseSpec |
数据库审计规范 |
| B2-038 | Get-SQLAuditServerSpec |
服务器审计规范 |
| B2-039 | Get-SQLRecoverPwAutoLogon |
自动登录密码恢复 |
| B2-040 | Invoke-SQLDumpInfo |
导出 CSV 到 TestResults\dump-* |
以上均已纳入 Run-IntegrationTests.ps1 -Category Batch2。
在具备 sysadmin 凭据的实验 SQL Server 上验证 Audit / OSCmd 命令。审计类用例 exit 0(无发现时输出可为空);OS 命令类在无权限或功能未启用时仍 exit 0,输出含 No sysadmin / Could not enable 等提示。
| ID | 命令 | 说明 | 自动化 |
|---|---|---|---|
| B3-001 | Invoke-SQLAudit |
聚合全部子检查 | ✅ |
| B3-002 | Invoke-SQLAuditPrivTrustworthy |
Trustworthy 数据库 | ✅ |
| B3-003 | Invoke-SQLAuditDefaultLoginPw |
默认口令(无需现有凭据) | ✅ |
| B3-004 | Invoke-SQLAuditWeakLoginPw |
弱口令(-NoUserEnum -TestUsername sa) |
✅ |
| B3-005 | Invoke-SQLAuditPrivImpersonateLogin |
IMPERSONATE 权限 | ✅ |
| B3-006 | Invoke-SQLAuditPrivServerLink |
链接服务器静态凭据 | ✅ |
| B3-007 | Invoke-SQLAuditPrivDbChaining |
DB chaining | ✅ |
| B3-008 | Invoke-SQLAuditPrivCreateProcedure |
CREATE PROCEDURE 权限 | ✅ |
| B3-009 | Invoke-SQLAuditPrivXpDirtree |
xp_dirtree EXECUTE | ✅ |
| B3-010 | Invoke-SQLAuditPrivXpFileexit |
xp_fileexist EXECUTE | ✅ |
| B3-011 | Invoke-SQLAuditRoleDbDdlAdmin |
db_ddladmin 角色 | ✅ |
| B3-012 | Invoke-SQLAuditRoleDbOwner |
db_owner 角色 | ✅ |
| B3-013 | Invoke-SQLAuditSampleDataByColumn |
敏感列探测(-Keyword Password) |
✅ |
| B3-014 | Invoke-SQLAuditSQLiSpExecuteAs |
EXECUTE AS OWNER SQLi SP | ✅ |
| B3-015 | Invoke-SQLAuditSQLiSpSigned |
签名 SP SQLi | ✅ |
| B3-016 | Invoke-SQLAuditPrivAutoExecSp |
启动 SP 权限 | ✅ |
| B3-017 | Invoke-SQLAudit 多实例 |
exit 2(仅支持单 -Instance) |
✅ |
| B3-018 | Invoke-SQLAudit -OutFolder |
指定 CSV 输出目录 | ✅ |
| B3-020 | Invoke-SQLOSCmd |
xp_cmdshell 执行 whoami |
✅ |
| B3-021 | Invoke-SQLOSCmd -RawResults |
原始输出模式 | ✅ |
| B3-022 | Invoke-SQLOSCmdCLR |
CLR 程序集向量 | ✅(需 RunOsCmdAdvancedTests) |
| B3-023 | Invoke-SQLOSCmdCOle |
OLE Automation | ✅(需 RunOsCmdAdvancedTests) |
| B3-024 | Invoke-SQLOSCmdPython |
Python 外部脚本 | ✅(需 RunOsCmdAdvancedTests) |
| B3-025 | Invoke-SQLOSCmdR |
R 外部脚本 | ✅(需 RunOsCmdAdvancedTests) |
| B3-026 | Invoke-SQLOSCmdAgentJob |
SQL Agent 作业 | ✅(需 RunOsCmdAdvancedTests) |
| B3-027 | Invoke-SQLOSCmd 缺 -Command |
exit 2 | ✅ |
以上均已纳入 Run-IntegrationTests.ps1 -Category Batch3。
配置项(test-env.ps1):
| 键 | 默认 | 说明 |
|---|---|---|
RunOsCmdTests |
$true |
为 $false 时跳过 B3-020–027 |
RunOsCmdAdvancedTests |
$false |
为 $true 时启用 CLR/OLE/Python/R/AgentJob |
OsCmdCommand |
whoami |
OS 命令执行测试用的命令 |
仍为手动 / 环境依赖的 Batch 3 项:
| ID | 说明 |
|---|---|
| B3-028 | Invoke-SQLOSCmd -RestoreState:执行前后对比 Get-SQLServerInfo 中 XpCmdShellEnabled |
| B3-029 | Invoke-SQLAudit -Exploit 提权路径(仅隔离实验环境) |
| B3-030 | 与 PowerUpSQL 对照 Invoke-SQLAudit / Invoke-SQLOSCmd 输出 |
.\scripts\Run-IntegrationTests.ps1 -Category Batch3 -SkipBuild
.\dist\PowerUpSQLSharp.exe Invoke-SQLAudit -Instance SQL01 -Username sa -Password "<密码>"
.\dist\PowerUpSQLSharp.exe Invoke-SQLOSCmd -Instance SQL01 -Command whoami -Username sa -Password "<密码>"在**域成员客户端 + 域内 SQL Server(建议 sysadmin)**上执行;部分用例可在无域环境跳过。
| ID | 命令 | 关键参数 | 预期 | 自动化 |
|---|---|---|---|---|
| B4-001 | Get-SQLDomainObject |
-Instance + SQL 凭据 |
exit 0/4/5,ADSI 查询 | ✅(需 RunAdTests) |
| B4-002 | Get-SQLDomainUser |
同上 | 同上 | ✅ |
| B4-003 | Get-SQLDomainComputer |
同上 | 同上 | ✅ |
| B4-004 | Get-SQLDomainSubnet |
同上 | 同上 | ✅ |
| B4-005 | Get-SQLDomainSite |
同上 | 同上 | ✅ |
| B4-006 | Get-SQLDomainGroup |
同上 | 同上 | ✅ |
| B4-007 | Get-SQLDomainOu |
同上 | 同上 | ✅ |
| B4-008 | Get-SQLDomainAccountPolicy |
同上 | 同上 | ✅ |
| B4-009 | Get-SQLDomainTrust |
同上 | 同上 | ✅ |
| B4-010 | Get-SQLDomainPasswordsLAPS |
同上 | 同上 | ✅ |
| B4-011 | Get-SQLDomainController |
同上 | 同上 | ✅ |
| B4-012 | Get-SQLDomainExploitableSystem |
同上 | 同上 | ✅ |
| B4-013 | Get-SQLDomainGroupMember |
同上 | 同上 | ✅ |
| B4-014 | Get-DomainSpn |
可选 -DomainController |
exit 0,LDAP SPN 列表 | ✅(需 RunAdTests) |
| B4-015 | Get-DomainObject |
-Limit 5 |
exit 0,LDAP 对象 | ✅ |
| B4-016 | Get-SQLServerLink |
SQL 凭据 | exit 0/4/5 | ✅ |
| B4-017 | Get-SQLServerLinkCrawl |
同上 | 同上 | ✅ |
| B4-018 | Get-SQLServerLinkData |
同上 | 同上 | ✅ |
| B4-019 | Get-SQLServerLinkQuery |
-Sql + -Path(无需 Instance) |
exit 0,含 OPENQUERY | ✅ |
| B4-020 | Invoke-SQLUncPathInjection |
-CaptureIp |
exit 0/4/5 | ✅(需 RunUncPathTests + CaptureIp) |
| B4-021 | Invoke-SQLUncPathInjection 缺 -CaptureIp |
— | exit 2 | ✅ |
| B4-022 | Invoke-SQLEscalatePriv |
SQL 凭据 | exit 0/4/5 | ✅(需 RunPrivEscTests) |
| B4-023 | Invoke-SQLImpersonateService |
同上 | 同上 | ✅ |
| B4-024 | Invoke-SQLImpersonateServiceCmd |
-Exe whoami |
同上 | ✅ |
| B4-025 | Invoke-TokenManipulation |
-WhoAmI 1 |
exit 0 | ✅ |
| B4-026 | Get-SQLPersistRegRun |
SQL 凭据 | exit 0/4/5 | ✅ |
| B4-027 | Get-SQLPersistRegDebugger |
同上 | 同上 | ✅ |
| B4-028 | Get-SQLPersistTriggerDDL |
-Remove |
同上 | ✅ |
| B4-029 | Get-SQLFuzzObjectName |
-StartId 1 -EndId 5 |
exit 0/4/5 | ✅ |
| B4-030 | Get-SQLFuzzDatabaseName |
同上 | 同上 | ✅ |
| B4-031 | Get-SQLFuzzServerLogin |
同上 | 同上 | ✅ |
| B4-032 | Get-SQLFuzzDomainAccount |
-Domain |
同上 | ✅ |
| B4-033 | Create-SQLFileCLRDll |
-OutDir |
exit 0,生成 .dll |
✅ |
| B4-034 | Create-SQLFileXpDll |
无 -SourceDllPath |
exit 0,Status=Skipped | ✅ |
| B4-035 | Get-SQLServerLinkQuery 缺 -Sql |
— | exit 2 | ✅ |
test-env.ps1 Batch 4 开关:
| 键 | 默认 | 说明 |
|---|---|---|
RunAdTests |
$true |
为 $false 时跳过 B4-001–015 |
RunUncPathTests |
$false |
为 $true 且配置 CaptureIp 时运行 B4-020 |
RunPrivEscTests |
$false |
为 $true 时运行 B4-022–024 |
DomainController |
空 | 传给直接 LDAP / UNC 测试 |
CaptureIp |
空 | UNC 捕获 IP(实验环境) |
仍为手动 / 环境依赖的 Batch 4 项:
| ID | 说明 |
|---|---|
| B4-036 | Invoke-SQLEscalatePriv -Exploit 提权路径(仅隔离实验环境) |
| B4-037 | Create-SQLFileXpDll -SourceDllPath 使用真实 XP 模板 DLL |
| B4-038 | 与 PowerUpSQL 对照 Get-SQLServerLinkCrawl / Get-DomainSpn 输出 |
.\scripts\Run-IntegrationTests.ps1 -Category Batch4 -SkipBuild
.\dist\PowerUpSQLSharp.exe Get-SQLDomainUser -Instance SQL01 -Username sa -Password "<密码>"
.\dist\PowerUpSQLSharp.exe Get-DomainSpn -DomainController DC01.example.com
.\dist\PowerUpSQLSharp.exe Create-SQLFileCLRDll -OutDir C:\Temp\pus-clr仍为手动 / 环境依赖的 Batch 1 项:
| ID | 说明 |
|---|---|
| B1-002 | 本机无 SQL 时 Get-SQLInstanceLocal 空结果 |
| B1-061 | sa 弱口令实例上 Get-SQLServerLoginDefaultPw 检出 |
| B1-082 | Sliver --in-process ANSI 检查 |
| B1-084 | release.ps1 两次构建 SHA256 一致(release 内置) |
- 在测试 SQL Server 上记录:实例名、版本、sa 状态、xp_cmdshell 是否启用
- 对同一实例、同一凭据,分别运行 PowerUpSQL 与 PowerUpSQLSharp
- 对比关键字段(不要求列顺序一致)
- 差异分类:
- 语义差异(Success 相反、权限判断不同)→ 缺陷
- 格式差异(列名大小写、空值表示)→ 可接受,记录即可
建议优先对照:
Get-SQLInstanceLocal/Get-SQLInstanceDomainGet-SQLConnectionTestGet-SQLServerInfoGet-SQLDatabase/Get-SQLTableInvoke-SQLAudit/Invoke-SQLOSCmd(Batch 3)Get-SQLDomainUser/Get-DomainSpn/Get-SQLServerLinkCrawl(Batch 4)
为覆盖更多用例,可在测试库上按需配置(仅实验环境):
-- B1-060:弱口令检测(可选)
ALTER LOGIN sa WITH PASSWORD = '';
ALTER LOGIN sa ENABLE;
-- B1-070:xp_cmdshell 状态(可选)
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;配置后重新运行:
.\scripts\Run-IntegrationTests.ps1 -Category Recon
.\dist\PowerUpSQLSharp.exe Get-SQLServerLoginDefaultPw -Instance SQL01 -Username sa -Password ""| 码 | 含义 |
|---|---|
| 0 | 成功 |
| 2 | 参数错误 |
| 3 | 连接失败 |
| 4 | 权限不足 |
| 5 | 部分失败 |
| 现象 | 处理 |
|---|---|
Get-SQLInstanceDomain 空结果 |
确认客户端已加入域、DNS 指向 DC |
| UDP 扫描无结果 | 检查 SQL Browser 服务、防火墙 UDP 1434 |
| B1-050 失败 exit 3 | 确认 TCP 1433 可达、SQL 身份验证已启用 |
| B1-052 Windows 认证失败 | 当前登录用户需为 SQL 登录或 Windows 映射登录 |
| Batch2 命令 exit 4 | 凭据权限不足,换 sa 或 sysadmin 账户 |
| Batch3 OSCmd 输出 No sysadmin | 使用 sysadmin 账户,或在 test-env.ps1 设 RunOsCmdTests = $false |
| Batch3 CLR/OLE/Python/R 失败 | 在 test-env.ps1 设 RunOsCmdAdvancedTests = $true 并确保实例已启用对应功能 |
- 多版本 SQL(2016/2019/2022):见 AutomatedLab-TestEnvironment.md
- 全量 108 函数:随实现进度在 Acceptance-Tests.md 追加用例
- CI:单元测试在 GitHub Actions 运行;集成测试保留为手动/实验环境触发
-
release.ps1构建成功,verify-strip.ps1通过 -
Run-IntegrationTests.ps1阶段 A–F 全绿(或已知跳过项已记录) - 至少 3 个命令与 PowerUpSQL 对照无语义差异
- JSON 报告已归档到
TestResults\ - 失败项已开 issue(如有)
最后更新:2026-07-04