DejaBlue(CVE-2019-1181/1182) Windows RDP漏洞分析
2019-12-17 23:02:53 Author: bbs.pediy.com(查看原文) 阅读量:635 收藏

在2019年8月的例行更新中,微软修复了DejaBlue(CVE-2019-1181/1182)漏洞,称其和BlueKeep(CVE-2019-0708)一样也是wormable的,并且影响win7-win10的操作系统。下面我们就来探究一下这两个漏洞(环境win10 64bit)。
因为DejaBlue是在每月例行更新中修复的,并不像BlueKeep一样有单独的补丁包,所以首先需要确定存在漏洞的组件。在checkpoint的一篇文章中提到了windows系统中与RDP有关的组件。

经过分析,最终确定存在漏洞的组件为rdpbase.dll,通过补丁对比确定了存在漏洞的函数为DecompressUnchopper::Decompress。

有两处不同,看上去都像是增加了对整数溢出的判断。
第一处:
After

Before

第二处:
After

Before

在这个函数下断点试试。这里调试方法和BlueKeep有所不同,BlueKeep中存在漏洞的组件是一个内核态组件,需要使用内核调试的方法进行调试;DejaBlue中存在漏洞的组件是一个用户态组件,对windows系统有所了解的话应该知道这种服务的组件是通过svchost加载的,以管理员权限启动Process Explorer搜索rdpbase.dll就可以找到相应的svchost进程,再用管理员权限启动windbg即可附加进程调试。然而下断点建立RDP连接之后并没有断下来,只好尝试静态分析找一找调用该函数的方法。

DecompressUnchopper::DecompressUnchopper应该是DecompressUnchopper类的构造函数,DecompressRdp8__CreateInstance调用了DecompressUnchopper::DecompressUnchopper。rdpbase.dll中导出了该函数,rdpserverbase.dll中导入了该函数,调用链依次是CRdpDynVCMgr::HandleIncomingDvcData->CRdpDynVC::GetDecompressor-> DecompressRdp8__CreateInstance。DynVC指的是Dynamic Virtual Channel,rdesktop中的dvc.c就有相应的实现。能够在dvc.c中看到dvc_channel的回调函数是dvc_process_pdu,dvc_process_pdu中有DYNVC_DATA_COMPRESSED这样的case,能够和在IDA中看到的函数名对应上。


找到微软关于RDP的文档中与Dynamic Virtual Channel有关的文档([MS-RDPEDYC].pdf),猜测我们可能需要发送DVC Data First Compressed PDU或者DVC Data Compressed PDU。

我们用rdesktop建立连接看看:RDESKTOP_DEBUG=Protocol ./rdesktop 192.168.112.132

在Opening a DVC这一步当收到DVC Create Request PDU之后因为没有找到对应的channel所以不能进行到Sending and Receiving Data这一步。

阅读文档我们可以知道必须先发送DVC Data First Compressed PDU才能发送DVC Data Compressed PDU,DVC Data First Compressed PDU的格式如下所示。

Data的格式为RDP_SEGMENTED_DATA,在另一个文档里面([MS-RDPEGFX].pdf)。

阅读文档之后我们对rdesktop的代码进行一些修改。从前面图片中的dvc_process_pdu函数中可以看到rdesktop是并没有实现Sending and Receiving Data这部分逻辑的,需要自己构造。首先在dvc_init函数中注册一个收到的DVC Create Request PDU中request的channel。

在收到DVC Create Request PDU之后进行处理的dvc_process_create_pdu函数中发送DVC Create Response PDU的dvc_send_create_response函数之后增加发送DVC Data First Compressed PDU的dvc_send_first_compressed函数。

dvc_send_first_compressed函数按照文档构造即可。注意到文档中RDP_SEGMENTED_DATA结构的descriptor可为0xE0或0xE1,从前面图片中的DecompressUnchopper::Decompress函数中可以看到a2=255(0xE1)才会进入存在漏洞的路径,因此descriptor要按照0xE1构造。RDP8_BULK_ENCODED_DATA结构中的数据来自文档中的示例。

这一次成功断下,对照dvc_send_first_compressed函数可以知道是uncompressedSize字段发生了整数溢出。

将dvc_send_first_compressed函数中的uncompressedSize字段改成0xffffe001,溢出之后即为0x1,而根据文档中的示例发送的数据解压之后是1595个字节的q(0x71),这样肯定会造成堆溢出。果然这里发送的数据导致了crash。


以我有限的知识水平来看,利用起来应该比较困难或者可能还需要其它漏洞配合。
参考资料:
1.DejaBlue: Analyzing a RDP Heap Overflow
2.Reverse RDP Attack: Code Execution on RDP Clients
3.Patch new wormable vulnerabilities in Remote Desktop Services (CVE-2019-1181/1182)

[进行中] 看雪20周年庆典报名通道开启!


文章来源: https://bbs.pediy.com/thread-256766.htm
如有侵权请联系:admin#unsafe.sh