首页
社区
课程
招聘
[翻译]虚拟机逃逸——QEMU的案例分析(二)
发表于: 2017-5-31 22:58 12108

[翻译]虚拟机逃逸——QEMU的案例分析(二)

2017-5-31 22:58
12108

其他部分链接:


3.内存泄露的利用

  本节中,我们将利用CVE-2015-5165——一个影响RTL8139

网卡仿真的内存泄露漏洞——来重现QEMU的内存泄露。更确切的说,我们需要泄露(1.text字段的基地址,用于构建shellcode2)用户物理内存的基地址,用于得到一些虚拟结构的准确地址。

 3.1漏洞代码

  REALTEK网卡支持两种接收/传送模式:C模式和C+模式。当网卡配置成C+模式时,NIC设备仿真器会错误计算IP数据包的长度并在结束时发送更多的数据。

  漏洞出现在hw/net/rtl8139.c文件中的rtl8139_cplus_transmit_one函数:


  IP头包括两个参数:hlen表示ip数据包长度,ip->ip_len表示IP头的长度(一个包20字节,不包括可选字段),数据包的总长度包括ip头的长度。如下所示的代码片段最后,在计算IP数据长度(ip_data_len)时没有检查确保ip->ip_len不小于hlen。因为ip_data_len参数类型为unsigned short,这会导致发送比传送缓冲区实际更多的数据。

  更确切的说,ip_data_len会被复制用于之后计算TCP数据的长度——如果数据超过了MTU的长度将会一直传送下去——最后进入一个malloced缓冲区:


  所以,如果我们伪造一个长度错误的包(比如长度ip->ip_len = hlen - 1),那我们就可以从QEMU的内存中泄露大约64KB的数据。这样,网卡就不会发送一个简单的包了,而是在结束时发送43个分散的包。

 3.2配置网卡

  为了传送我们伪造的包并读取泄露的数据,我们需要配置网卡的接收缓冲和发送缓冲,并设置一些标记来确保我们的包经过漏洞代码的路径传输。

  下图是RTL8139的寄存器。这不是所有的寄存器,只列出与漏洞利用有关的寄存器。

  - TxConfig:开启/关闭Tx的标记,比如TxLoopBack(开启loopback测试模式),TxCRCTx包不添加冗余校验码)等。

  - RxConfig:开启/关闭Rx的标记,比如AcceptBroadcast(接收广播包), AcceptMulticast(接收组播包)等。

  - CpCmdC+指令寄存器用来执行一些函数,比如 CplusRxEnd(允许接收),CplusTxEnd(允许发送)等。

  - TxAddr0Tx表的物理内存地址。

  - RxRingAddrLORx表的物理内存地址的低32位。

  - RxRingAddrHIRx表的物理内存地址的高32位。

  - TxPoll:告诉网卡检查Tx

  一个Rx/Tx-descriptor定义有如下特征:buf_lobuf_hi分别表示Tx/Rx缓冲的物理内存地址的低32位和高32位。这些地址指向存储要发送/接收的包的缓冲区,必须与页面大小对齐。变量dw0表示缓冲区的长度加上额外的标记,比如用来标记缓冲区归网卡还是驱动所有的ownership标记。

  网卡通过in*()out*()(定义在sys/io.h)进行配置。配置需要CAP_SYS_RAWIO特权。以下代码段配置网卡并构建一个简单的Tx descriptor

 3.3 漏洞利用

  完整的漏洞利用代码(cve-2015-5165.c)可参见附录的源代码压缩包。首先配置会用到的网卡寄存器并构建了TxRx缓冲。然后伪造一个IP包并发送给网卡的MAC地址。这让我们能在配置的Rx缓冲中读到泄露的数据。

  当分析泄露的数据时,会出现很多函数指针。仔细分析后发现,这些函数指针都有相同的QEMU内部结构:

  QEMU遵循一个对象模型来管理设备、内存等。QEMU在启动时会创建一些对象并分配属性。例如,以下调用会给一个内存对象添加属性“may-overlap”。该属性通过getter方法获得一个布尔值。

  RTL8139网卡需要在头中分配64KB的空间来重组包。很有可能这个空间与对象属性撤销后的空间正好合适。

  在漏洞利用中,我们在溢出内存中搜索已知的对象属性。更确切的说,我们搜索至少有一个函数指针被设置(获取、设置、解决或释放)的80字节的内存块(一个自由ObjectProperty结构的块)。即使这些地址有ASLR(一种针对缓冲区溢出安全保护技术)保护,但我们仍可以猜.text字段的基地址。实际上,他们的页偏移地址是确定的(12个最小有效位或虚地址都不是随机的)。我们可以计算获得一些QEMU函数的地址。我们还可以得到一些LibC函数的地址,比如从PLT入口获得mprotect()system()的地址。

  我们还发现PHY_MEM + 0x78的地址多次泄露,PHY_MEM表示分配给用户的物理内存空间的首地址。

  目前的漏洞利用是搜索泄露的内存并尝试找到(1.text字段的基地址(2)物理内存的基地址。

4.堆溢出的利用

  这部分讨论漏洞CVE-2015-7504并利用漏洞获得%rip寄存器的控制权。

 4.1 漏洞代码


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/07/12
最新回复 (4)
雪    币: 6108
活跃值: (3087)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢分享!
2017-6-1 07:02
0
雪    币: 6112
活跃值: (1212)
能力值: (RANK:30 )
在线值:
发帖
回帖
粉丝
3
文章很好!建议可以合为一篇发,或者在这两篇文章  都加上  另一篇文章的链接,方便查看
2017-6-1 10:57
0
雪    币: 1475
活跃值: (482)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
4
哆啦咪 文章很好![em_63]建议可以合为一篇发,或者在这两篇文章 都加上 另一篇文章的链接,方便查看[em_12]
已修改~
2017-6-1 18:50
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
请问文章提到的源代码要怎么下载?想学习一下
2017-6-28 22:23
0
游客
登录 | 注册 方可回帖
返回
//