绕行或类似技术可能会导致 SQL Server 出现意外行为
本文介绍在 SQL Server 中使用第三方绕行时Microsoft支持策略,以及使用 SQL Server 时可能出现的问题。
原始产品版本:SQL Server
原始 KB 数: 920925
总结
Microsoft支持遇到许多第三方产品,这些产品使用绕行向 SQL Server 提供附加功能。 这些功能通常是审核功能。 对于Microsoft应用程序,第三方绕道没有认证过程。 因此,通常,Microsoft强烈劝阻使用绕道。
使用绕行或类似技术更改 SQL Server 行为的功能可能会导致以下问题:
- 性能问题。
- 结果不正确。
- 磁盘和内存损坏。
- SQL Server 响应丢失。
- 进程意外终止。
- 无法使用标准诊断,例如fn_get_sql函数和
DBCC INPUTBUFFER
命令。 - 在 SQL Server 中使用内存中 OLTP 表时,100% 的 CPU 利用率和长时间的数据库恢复时间。
在 SQL Server 进程中使用非Microsoft软件(如链接服务器、扩展过程或 COM 对象)时,可能会遇到这些相同的问题。 从 DBA 视图中隐藏绕行。 若要发现绕道,必须使用后面的“更多信息”部分中介绍的技术。 链接服务器、COM 对象和扩展过程具有显式注册和定义的接口。
注意
由于绕行和缺少已发布接口的隐藏性质,Microsoft不提供使用绕行或类似技术的第三方功能的支持服务。 第三方负责支持自己的代码,就像它负责自己的链接服务器或其他批准的部署一样。
通常,在故障排除过程中,Microsoft支持服务要求你禁用非正常作业以及禁用或删除第三方组件和其他类似技术是常见的做法。 Microsoft始终尝试在识别问题时减少问题的占用空间。 将问题确定为与作业或第三方产品无关后,这些作业或第三方产品可能会重新引入生产环境。
我们无意发现一个绕道,然后考虑不支持 SQL Server 的实例。 Microsoft确认某些实现是必需的。 但是,Microsoft要求验证绕行者的可支持性。 来自信誉和受信任的公司的绕道与病毒使用意外的绕道绝对不同。 Microsoft不保证或认证这些第三方产品或第三方产品与Microsoft产品和服务的交互方式。 相反,第三方供应商负责其产品和服务的识别和可信度。 如果对第三方产品和服务有任何疑问,请联系适用的第三方。 Microsoft不负责因使用与 SQL Server 相关的第三方产品或服务而导致的任何问题。
详细信息
绕行提供增强的功能和风险/回报权衡。 通常,在 SQL Server 中实现绕道时,第三方代码将注入进程空间。 此活动可能会更改 SQL Server 的行为。
下面是一些示例情况和可能的副作用:
将扫描和更改传入网络流量(TDS)数据包。 在net_readdata网络进程线程的关键位置添加绕道。 即使此位置的 100 个 CPU 周期也会显著降低批处理速率吞吐量。
实际 TDS 数据的更改可能会导致内存刻板。 此问题触发了各种 SQL Server 稳定性问题和数据损坏。 问题可能会导致 TDS 数据包部分更改,并将垃圾重播到 SQL Server。 此级别的日志记录设施可能会公开 SQL Server 跟踪旨在抑制和帮助保护的密码和其他敏感数据。
SQL Server 分析例程被转为更改行为。 以下是可能的副作用:
- 执行计划与实际查询文本不匹配。
- 仅从客户端提交一次命令。 但是,该命令会多次执行。
- 跟踪输出显示原始命令,而不是更改的查询。
- 该
DBCC INPUTBUFFER
命令显示原始命令,而不是更改的查询。 - 该
fn_get_sql
函数显示不正确的数据。 此外,该fn_get_sql
函数容易受到异常和不正确的结果的影响。 该fn_get_sql
函数由许多监视解决方案使用,并可能导致监视解决方案出现问题。 - 整体用户模式计划程序(UMS)和 SQL Server 操作系统(SQLOS)计划可能会中断。 这会导致 SQL Server 响应丢失、性能更改和中断。
提供增强安全功能的 Win32 API 被弃用。 根据实现的不同,此级别的日志记录设施可能会公开密码和其他敏感数据。 总体 UMS 和 SQLOS 计划中断。 这会导致 SQL Server 响应和中断丢失。
SQL Server 进程不支持修改函数表和重定向核心 SQL Server 函数或 Windows API。 这可能会导致 SQL Server 功能中的不稳定和意外行为。
以下示例显示 kernel32!GetQueuedCompletionStatus
函数已被绕行。
MyDLL!MyGetQueuedCompletionStatus
ssnetlib!ConnectionReadAsyncWait
在函数的 GetQueuedCompletionStatus
程序集中,第一个指令已替换为跳转指令。
0:038> u kernel32!GetQueuedCompletionStatus
kernel32!GetQueuedCompletionStatus
77e660f1 e90a9f00aa jmp 21e70000 ß This points to an address that does not appear in the loaded module list (lm). It is injected code.
77e660f6 83ec10 sub esp,10h
注入代码的程序集显示已绕行的活动和对 MyDLL 文件的调用。
0:038> u 21e70000
21e70000 55 push ebp
21e70001 8bec mov ebp,esp
21e70003 51 push ecx
21e70004 8b4518 mov eax,dword ptr [ebp+18h]
21e70007 50 push eax
21e70008 8b4d14 mov ecx,dword ptr [ebp+14h]
21e7000b 51 push ecx
21e7000c 8b5510 mov edx,dword ptr [ebp+10h]
21e7000f 52 push edx
21e70010 8b450c mov eax,dword ptr [ebp+0Ch]
21e70013 50 push eax
21e70014 8b4d08 mov ecx,dword ptr [ebp+8]
21e70017 51 push ecx
21e70018 e8234d19ee call MyDLL+0x4d40 (10004d40) <- Call to the MyDLL file.
21e7001d 8945fc mov dword ptr [ebp-4],eax
21e70020 8b55fc mov edx,dword ptr [ebp-4]
可以使用适用于 Windows 的调试工具来确定是否使用了绕行工具。 要设置部门,请按照以下步骤操作。
注意
在生产环境中试用此方法之前,请始终测试此方法。 使用适用于 Windows 的调试工具时,运行命令时,进程可能会冻结。 此行为可能会对生产服务器产生不利影响。
将适用于 Windows 的调试工具附加到 SQL Server,或加载完整的用户转储文件。
发出以下调试器命令。 此命令根据磁盘映像检查每个映像,以确定是否已注入绕行。
!for_each_module "!chkimg -v @#Base -d"
分离调试器。
如果内存中映像已更改,输出可能如下所示:
Comparison image path: c:\program files\microsoft sql server\mssql\binn\ssnetlib.dll\ssnetlib.dll
Scanning section: .text
Size: 56488
Range to scan: 0c261000-0c26eca8
0c263710-0c26371a 11 bytes - ssnetlib!ConnectionClose
[ 8b ff 55 8b ec 83 ec 10:68 00 00 00 00 e9 27 8a ]
0c2641e0-0c2641ea 11 bytes - ssnetlib!ConnectionReadAsync (+0xad0)
[ 8b ff 55 8b ec 83 ec 38:68 00 00 00 00 e9 00 7e ]
0c265160-0c26516a 11 bytes - ssnetlib!ConnectionWriteAsync (+0xf80)
[ 8b ff 55 8b ec 83 ec 28:68 00 00 00 00 e9 ba 70 ]
Total bytes compared: 56488(100%)
Number of errors: 33
33 errors : 0c260000 (0c263710-0c26516a)
可以查看程序集,以更仔细地查看问题,如下所示:
0:038> u ssnetlib!ConnectionClose
ssnetlib!ConnectionClose]:
0c263710 6800000000 push 0
0c263715 e9278ada03 jmp MyDLL!MyGetQueuedCompletionStatus <- A detour has been installed.
跟踪 SQL 注入攻击的防病毒程序可能会绕道 SQL Server 代码。 在此方案中,扩展的 !for_each_module "!chkimg -v @#Base -d"
输出可能显示 SQL Server 函数 yyparse
并 ex_raise2
进行了修改:
Comparison image path: <symbol file path>\sqlservr.exeRange to scan: c81000-3de7d48 ed71a8-ed71ad 6 bytes - sqlservr!yyparse [ ff f5 41 54 41 55:e9 c7 95 5c 76 90 ]1202820-1202824 5 bytes - sqlservr!ex_raise2 (+0x32b678) [ ff f3 57 41 54:e9 20 e0 29 76 ] Total bytes compared: 51801416(17%)Number of errors: 11
建议联系绕行者提供程序或类似技术,了解有关它如何使用 SQL Server 中的绕道的详细信息。 有关绕行和类似技术的详细信息,请参阅“绕行”。