WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

  • A+
所属分类:颓废's Blog
摘要

此漏洞影响Windows Server 2008,2012和2016版本。 存在此漏洞是因为在处理格式错误的WINS数据包时触发远程内存损坏。

漏洞影响Windows Server 2008,2012和2016版本。 存在此漏洞是因为在处理格式错误的WINS数据包时触发远程内存损坏。

重现脆弱性
要重现此漏洞,请按照以下步骤操作。

在受影响的Windows Server版本的“服务器管理器”中安装“WINS服务器”。 对于这种情况,我们正在使用Windows Server 2016.按照“服务器管理器”安装向导,然后选中“WINS服务器”选项。 请参见图1中的屏幕截图。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

2:打开“控制面板” - >“管理工具” - >“WINS”。 然后导航到“WINS” - >“复制伙伴”,右键单击“复制伙伴”,然后选择“新建复制伙伴”。 见图中的截图

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

3:在弹出的对话框中,输入WINS服务器IP地址,然后单击确定。 请注意,WINS服务器的IP地址必须是攻击者的主机IP地址。 在我的测试中,IP地址为10.0.0.1。 请参见图3中的屏幕截图。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

4:在另一台机器上,如Windows 7 x64(其IP地址必须是您在步骤3中输入的WINS服务器IP地址),请在CLI中运行PoC,如“trigger_poc.py”。 发送数据包后,您可以看到Windows Server 2016上的WINS Server服务停止工作,或者使用新的pid自动重新启动该过程。 您可以继续运行PoC,直到由于远程内存损坏而导致WINS Server服务停止工作。 攻击报文的捕获如图4所示。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

                                                                                   图4.攻击报文的捕获

分析
存在此漏洞,因为Windows Server未正确处理多个挂起的WINS-Replication会话。 所以让我们先来看看数据包捕获。 参见图5。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

                                                                     图5.攻击数据包中的数据

当使用复制命令WREPL_REPL_UPDATE2(0x00000005)处理多个(> 3)待处理的WINS-Replication会话时,会触发此漏洞。 它导致“int 29h”,错误代码为0xC0000409。 参见图6。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

                                                                               图6.“int 29h”,错误代码为0xC0000409

“int 29h”是在Windows 8或更新版本中发现的新安全声明。 它有许多断言项目。 这里,断言在伪代码中检查以下条件: 损坏的列表指针 。

     if(((Entry-> Flink) - > Blink)!= Entry)

     {

         mov ecx,3

         int 29h

 } 

当我们建立多个挂起的WINS-Replication会话时,列表指针将被破坏。 根本原因是将同一个缓冲区多次释放到列表池。 请参阅以下代码:

 DeallocEnt proc附近; .text:00007FF7F87E35D4  CODE XREF:CommAssocDeallocAssoc + 2Ap .text:00007FF7F87E35D4;  CommAssocDeallocDlg + 2Ap .text:00007FF7F87E35D4;  DATA XREF:... .text:00007FF7F87E35D4 .text:00007FF7F87E35D4 arg_0 = qword ptr 8 .text:00007FF7F87E35D4 arg_8 = qword ptr 10h .text:00007FF7F87E35D4 arg_10 = qword ptr 18h .text:00007FF7F87E35D4 arg_20 = qword ptr 28h .text:00007FF7F87E35D4 arg_28 = qword ptr 30h .text:00007FF7F87E35D4 .text:00007FF7F87E35D4 mov [rsp + arg_0],rbx.text:00007FF7F87E35D9 mov [rsp + arg_8],rsi.text:00007FF7F87E35DE mov [rsp + arg_10],r8 .text:00007FF7F87E35E3 push rdi.text:00007FF7F87E35E4 sub rsp,20h .text:00007FF7F87E35E8 mov rbx,r9 .text:00007FF7F87E35EB mov rsi,r8 .text:00007FF7F87E35EE mov rdi,rdx ---> rdi指向列表的头(rdx,命名条目这里)等于sAssocQueHd全局变量 .text:00007FF7F87E35F1 mov rcx,r8;  lpCriticalSection .text:00007FF7F87E35F4调用cs:__ imp_EnterCriticalSection .text:00007FF7F87E35FA nop .text:00007FF7F87E35FB inc dword ptr [rbx] .text:00007FF7F87E35FD mov eax,[rbx] .text:00007FF7F87E35FF mov rbx,[rsp + 28h + arg_20];  ---> rbx指向条目B,将被释放 .text:00007FF7F87E3604 mov [rbx + 10h],eax .text:00007FF7F87E3607 mov rax,[rdi + 8] .text:00007FF7F87E360B cmp [rax],rdi。文本:00007FF7F87E360E jz short loc_7FF7F87E3617 .text:00007FF7F87E3610 mov ecx,3 .text:00007FF7F87E3615 int 29h;  Win8:RtlFailFast(ecx).text:00007FF7F87E3617 .text:00007FF7F87E3617 loc_7FF7F87E3617:;  CODE XREF:DeallocEnt + 3Aj.text:00007FF7F87E3617 mov [rbx],rdi ---> 条目B的Blink指向条目A .text:00007FF7F87E361A mov [rbx + 8],rax ---> 条目B的Flink指向条目C .text:00007FF7F87E361E mov [rax],rbx ----> 设置条目C的Blink到条目B .text:00007FF7F87E3621 mov [rdi + 8],rbx ----> 将条目A的Flink设置为条目B .text:00007FF7F87E3625 mov rdi,[rsp + 28h + arg_28] .text:00007FF7F87E362A cmp dword ptr [rdi],64h ... 

在上面的列表中,Flink指针指向列表中的下一个条目,Blink指针指向列表中的上一个条目。

在PoC中,在会话1,2,3之后发送两个数据包并保持处于待处理状态(会话不被TCP重置数据包终止),首次使用条目B指针调用释放分配功能,例如0x1f11306ff70 。 条目A(ListHead)始终等于sAssocQueHd全局变量。 分配在父函数中完成。 所以在进入B被释放之后,条目C不存在于第一个释放中。 入口关系如下表所示。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

那么取消分配功能将被第二次用入口B指针调用,它仍然等于0x1f11306ff70。 条目A(ListHead)等于sAssocQueHd全局变量。 所以在条目B被释放之后,没有添加新条目。 条目关系如下图所示。

WINS服务器远程内存损坏Microsoft Windows Server中的漏洞

正如你可以清楚地看到,在deallocate函数调用两次之后,列表元素条目B的Flink和Blink都指向自己。 这会导致列表错误。

那么这个deallocate函数将被第三次调用。 所以“int 29h”由于列表指针检查被破坏而触发。

    if(((Entry-> Flink) - > Blink)!= Entry)  {  mov ecx,3  int 29h  } 

在以下函数中处理WREPL_REPL_UPDATE2数据包的Assoc_Ctx时,将对象指针设置为相同的指针:

。proc:00007FF7F87E0190 ProcTcpMsg proc near;  CODE XREF:MonTcp + 4C5p  .text:00007FF7F87E0190;  DATA XREF:.pdata:00007FF7F88077D4o 的.text:00007FF7F87E0190  ......  .text:00007FF7F87E0284 loc_7FF7F87E0284:;  CODE XREF:ProcTcpMsg + EDj  .text:00007FF7F87E0284 mov ecx,[r15 + 4] ---> netlong这里是从第二个数据包获取的(Wirehark解析为“WINS-Replication WREPL_REPL_UPDATE2”),“Assoc_Ctx”=“00 00 00 3f”。  .text:00007FF7F87E0288调用cs:__ imp_ntohl  .text:00007FF7F87E028E mov esi,eax ---> here esi = 0x3f  .text:00007FF7F87E0290 mov ecx,[r15 + 8];  netlong  ......  .text:00007FF7F87E0382 loc_7FF7F87E0382:;  CODE XREF:ProcTcpMsg + 1EAj  .text:00007FF7F87E0382 lea ecx,[rsi-1]  .text:00007FF7F87E0385 mov rax,qword ptr cs:xmmword_7FF7F8804D28  .text:00007FF7F87E038C mov rbx,[rax + rcx * 8];  ---> here rbx = poi(7FF7F8804D28)+ 0x3e * 8,因为rcx是从Assoc_Ctx = 0x3f -1获得的  .text:00007FF7F87E0390 xor esi,esi 

从上面的代码段可以看出,一旦获得了对象指针poi(poi(7FF7F8804D28)+ 0x3e * 8 ),最终目标指针(先前传递的条目B指针)在第一次释放分配函数调用中是确定的,它被分配在第二和第三次释放函数调用中,最终的目标指针(条目B指针)保持不变,在我的测试中,它是000001f1`1306ff70,这导致列表损坏。

注意:poi是获取地址值的函数。

总而言之,该漏洞是由复制命令WREPL_REPL_UPDATE2(这是触发此漏洞的关键)的多个(> 3)挂起的WINS复制会话引起的。结果是相同的列表条目多次释放,这导致远程内存损坏
减轻
鼓励易受攻击的Microsoft Windows Server的所有用户立即从WINS服务器迁移。 另外,已部署Fortinet IPS解决方案的组织已经通过签名MS.Windows.WINS.Server.Remote.Memory.Corruption保护此漏洞。

源自:https://blog.fortinet.com/

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: