绕行或类似的技术可能会导致 SQL Server 出现意外行为

本文介绍在 SQL Server 中使用第三方弯道时Microsoft支持策略,以及使用它们时可能发生的问题。

原始产品版本: SQL Server
原始 KB 编号: 920925

摘要

Microsoft支持遇到许多第三方产品,这些产品使用弯道为 SQL Server 提供其他功能。 这些通常是审核功能。 Microsoft申请的第三方绕道没有认证流程。 因此,一般来说,Microsoft强烈劝阻使用弯道。

使用绕行或类似技术更改 SQL Server 行为的功能可能会导致以下问题:

  • 性能问题。
  • 结果不正确。
  • 磁盘和内存损坏。
  • SQL Server 响应丢失。
  • 意外的进程终止。
  • 无法使用标准诊断,例如 fn_get_sql 函数和 DBCC INPUTBUFFER 命令。
  • 在 SQL Server 中使用内存中 OLTP 表时,CPU 利用率为 100%,数据库恢复时间较长。

在 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 的调试工具时,运行命令时进程可能会冻结。 此行为可能会对生产服务器产生不利影响。

  1. 将适用于 Windows 的调试工具附加到 SQL Server,或加载完整的用户转储文件。

  2. 发出以下调试器命令。 此命令针对磁盘映像检查每个映像,以确定是否已注入绕行。

    !for_each_module "!chkimg -v @#Base -d"
    
  3. 分离调试器。

如果更改了内存中映像,输出可能如下所示:

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 函数 yyparseex_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 中的弯道。 有关绕行和类似技术的详细信息,请参阅 绕行