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

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
简介: 本文讲的是Windows Server中的 WINS 服务器远程内存损坏漏洞分析,在2016年12月,FortiGuard Labs发现并报告了Microsoft Windows Server中的WINS Server远程内存损坏漏洞。
本文讲的是 Windows Server中的 WINS 服务器远程内存损坏漏洞分析

漏洞概要

在2016年12月,FortiGuard Labs发现并报告了Microsoft Windows Server中的WINS Server远程内存损坏漏洞。在2017年6月,微软向FortiGuard实验室答复说:“要修复程序漏洞需要对代码进行全面彻底的检查,WINS所提供的功能会被DNS所取代,微软已经建议客户将其迁移出去。也就是说,由于修复漏洞所需要的工作量,Microsoft不会修补此漏洞。相反,Microsoft是建议用户使用DNS来替换WINS。

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

在本文中,我想分享一下这个漏洞的一些细节。

漏洞复现

要复现此漏洞,请按照以下步骤操作。

1. 在受影响的Windows Server版本中的“服务器管理器”中安装“WINS服务器”。本文中,我们正在使用的是Windows Server 2016.按照“服务器管理器”的安装向导,然后选中“WINS服务器”选项。请参见图1中的操作。

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

图1.安装WINS Server服务

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

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

图2.创建WINS复制伙伴

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

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

图3.输入WINS服务器IP地址

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

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

图4.捕获的攻击报文

漏洞分析

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

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

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

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

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

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

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

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

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

.text:00007FF7F87E35D4 DeallocEnt      proc near      ; 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 points to the head of the list (rdx, named entry A here) which equals sAssocQueHd global variable
 
.text:00007FF7F87E35F1                 mov     rcx, r8         ; lpCriticalSection
 
.text:00007FF7F87E35F4                 call    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 points to the entry B, which will be deallocated
 
.text:00007FF7F87E3604                 mov     [rbx+10h], eax
 
.text:00007FF7F87E3607                 mov     rax, [rdi+8]
 
.text:00007FF7F87E360B                 cmp     [rax], rdi
 
.text: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     ---> entry B’s Blink points to entry A
 
.text:00007FF7F87E361A                 mov     [rbx+8], rax   ---> entry B’s Flink points to entry C
 
.text:00007FF7F87E361E                 mov     [rax], rbx    ---->   set entry C’s Blink to entry B
 
.text:00007FF7F87E3621                 mov     [rdi+8], rbx  ---->   set entry A’s Flink to entry 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将不存在于第一个释放列表中。关系如下表所示。

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

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

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

你可以清楚地看到, 释放分配函数被调用了两次,B中的列表元素Flink和Blink指向了它们自己。这会导致列表错误。

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

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

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

.text: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 here was obtained from the second packet (Wirehark parses it as "WINS-Replication WREPL_REPL_UPDATE2"), "Assoc_Ctx"="00 00 00 3f".
 
.text:00007FF7F87E0288           call    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, because rcx is obtained from Assoc_Ctx=0x3f -1
 
.text:00007FF7F87E0390           xor     esi, esi

从上面的代码段可以看出,一旦获得了对象指针poi(poi(7FF7F8804D28)+0x3e*8 

,最终的目标指针(之前传递给条目B的指针)在第一次调用释放分配函数时是确定的,它被分配了B指针。在第二次和第三次调用释放函数时,最终的目标指针(入口B指针)保持不变。在我的测试中,它是1306 1306 ff70 f1。这将导致内存损坏。

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

总而言之,该漏洞是由于复制命令WREPL_REPL_UPDATE2(这是触发此漏洞的关键)处理多个(> 3)挂起的WINS复制会话所导致的。其结果是相同的列表条目被多次释放,这就导致了远程内存损坏。

漏洞缓解措施

我们鼓励那些易受攻击的Microsoft Windows Server的所有用户立即从WINS服务器进行迁移。另外,针对此漏洞,已经部署了Fortinet IPS解决方案的企业组织已经通过MS.Windows.WINS.Server.Remote.Memory.Corruption签名得到保护。




原文发布时间为:2017年6月21日
本文作者:丝绸之路 
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。
相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
Linux入门到精通
本套课程是从入门开始的Linux学习课程,适合初学者阅读。由浅入深案例丰富,通俗易懂。主要涉及基础的系统操作以及工作中常用的各种服务软件的应用、部署和优化。即使是零基础的学员,只要能够坚持把所有章节都学完,也一定会受益匪浅。
目录
相关文章
|
1月前
|
存储 数据安全/隐私保护 索引
Windows Server 各版本搭建文件服务器实现共享文件(03~19)
Windows Server 各版本搭建文件服务器实现共享文件(03~19)
150 1
|
26天前
|
Shell Windows
Windows服务器 开机自启动服务
Windows服务器 开机自启动服务
14 0
|
3天前
|
安全 Unix Linux
Windows如何远程连接服务器?服务器远程连接图文教程
服务器操作系统可以实现对计算机硬件与软件的直接控制和管理协调,任何计算机的运行离不开操作系统,服务器也一样,服务器操作系统主要分为四大流派:Windows Server、Netware、Unix和Linux。今天驰网飞飞将和你分享Windows server远程连接图文教程,希望可以帮助到你
16 4
Windows如何远程连接服务器?服务器远程连接图文教程
|
1月前
|
安全 Java 数据中心
Confluence 数据中心和服务器中的严重漏洞 CVE-2023-22515
Confluence 的开发者 Atlassian 已承认此漏洞,并将其归类为损坏的访问控制问题。他们强调需要立即采取行动,并建议用户升级到最新版本以保护他们的系统。Atlassian 将该漏洞的严重级别评定为 Critical CVSS 10。
19 0
|
1月前
|
Linux 数据安全/隐私保护 Docker
linux和windows中安装emqx消息服务器
linux和windows中安装emqx消息服务器
27 0
|
1月前
|
存储 运维 安全
服务器数据恢复—存储互斥不当导致VMFS卷损坏的数据恢复案例
某公司的信息管理平台,通过3台虚拟机共享了一台存储设备供企业内部使用,存储设备中存放了公司内部重要的数据文件。 由于业务增长的需要,管理员又在这个存储网络上连接了一台Windows server服务器,结果这台存储变得不可用了。 管理员对该存储进行故障排查时发现存储中虚拟磁盘丢失,分区表丢失。重启该存储设备后故障依旧。 由于存储中的数据十分重要,没有备份。管理员为了安全起见,联系北亚企安数据恢复中心寻求帮助。 经过硬件工程师的检测,没有发现存储存在硬件故障。存储中的硬盘经过硬件工程师的检测后也没有发现任何物理故障,都可以正常读取。基本上可以排除故障是由于硬件导致的。
|
1月前
|
监控 JavaScript 安全
监控内网电脑软件设计与实现:基于Node.js的服务器端架构分析
在当今信息技术高度发达的时代,监控内网电脑的需求日益增长。企业需要确保网络安全,个人用户也需要监控家庭网络以保护隐私和安全。本文将介绍一种基于Node.js的服务器端架构,用于设计和实现监控内网电脑软件。
99 0
|
1月前
|
存储 Windows
windows server 2019 云服务器看不见硬盘的解决方案
windows server 2019 云服务器看不见硬盘的解决方案
|
1月前
|
数据安全/隐私保护 Windows
Windows Server 各版本搭建终端服务器实现远程访问(03~19)
左下角开始➡管理工具➡管理您的服务器,点击添加或删除角色点击下一步勾选自定义,点击下一步蒂埃涅吉终端服务器,点击下一步点击确定重新登录后点击确定点击开始➡管理工具➡计算机管理,展开本地用户和组,点击组可以发现有个组关门用来远程登录右键这个组点击属性,点击添加输入要添加的用户名,点击确定添加成功后点击确定打开另一台虚拟机(前提是在同一个局域网内),按 WIN + R 输入 mstsc 后回车输入 IP 地址后点击连接输入用户名及密码后点击确定连接成功!
32 0
|
1月前
|
Windows
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
54 2