2018 seccon pwn q-escape

在这里插入图片描述
先看一眼保护

没开PIE

瞅一眼启动脚本
在这里插入图片描述
设备就叫cydf-vga
然后在本地的2222端口开启了qemu monitor

脚本跑一下
在这里插入图片描述没跑起来,缺个库

然后这样解决
在这里插入图片描述

然后IDA分析一下
在这里插入图片描述
首先是总的结构体 cydf_vga_register_types
然后是type_init一直往下调用的函数 do_qemu_init_cydf_vga_register_types ,里面继续调用module_init用来初始化typeinfo、typelmpl结构体。
然后调用 cydf_vga_class_init 初始化基类
然后调用 pci_cydf_vga_realize 初始化类对象
然后我们熟悉的还有cydf_vga_mem_read、cydf_vga_mem_write

我们不熟悉的有啥
isa_cydf_vga_class_init
isa_cydf_vga_realizefn
cydf_vga_ioport_read、cydf_vga_ioport_write
cydf_vga_write_gr

在这里插入图片描述首先我们发现似乎注册了两个module。
所以我们在旁边的函数里面看到了有一些isa开头的

那么isa是啥?

ISA总线:是IBM公司为PC/AT电脑而制定的总线标准,是“Industry Standard Architecture”的英文缩写。由于它是16位体系结构,所以只能支持16位的I/O设备,数据传输率大约是16MB/S。1984年ISA总线在原来8位总线的基础上扩充出16位数据总线宽度。同时地址总线宽度也由20位扩充到24位,但仍保持原8位ISA总线的完整性。形成了现在使用的8位基本插槽加上16位扩充插槽的16位ISA总线标准。

两个模块应该分别对应结构体
怎么找这两个结构体呢
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述其中我们发现一个结构体是另一个结构体中的成员。

然后我们继续看两个init函数
在这里插入图片描述
在这里插入图片描述函数我已经转了结构体
转结构体的方法,也就是为什么会转成这个结构体,也是要看汇编

举个例子
在这里插入图片描述我们看到在PCI对应的那个结构体里面定义了设备号,厂商号啥的
所以其实我们就会有个大体的了解
VGA设备用了两个模块,一个pci,一个isa

他们都有对应的结构体
在这里插入图片描述
然后里面有我们上面提到的那个总的结构体。
我们剩下的四个函数,又对应两个结构体

对应的设备

在这里插入图片描述

就是最后一个。

在这里插入图片描述

在proc目录下有iomem和ioports文件,其主要描述了系统的io内存和io端口资源分布。

还有两个初始化类对象的realize函数也没啥好看的,我们每次都要注意mmio的注册。
我们上面看到应该是有三个mmio空间
但是我们只找到一个。
在这里插入图片描述
那另外两个在哪?
我们交叉引用一下

在这里插入图片描述
就找到了一大堆的 memory_region_init_io与memory_region_init函数。
那么他俩有啥区别?

x86的qemu模拟的时候有两个全局的memory_region结构体,memory_region就是管理qemu内存的基本单位,有根级MR,实体MR,抽象MR,这里大家需要补一些qemu内存管理相关的知识。

所以memory_region_init_io,其实是对memory_region_init的一个封装,两个函数一个初始化system_io,一个初始化system_memory。

至此,我们找到了三个mmio空间。
但是里面有一个叫cydf_bar。
这个是啥意思?
又需要补一补pci设备的知识了。
在这里插入图片描述网上找了个图

Base Address Registers(BAR)。BAR是PCI配置空间中从0x10 到 0x24的6个register,用来定义PCI需要的配置空间大小以及配置PCI设备占用的地址空间。

每个PCI设备在BAR中描述自己需要占用多少地址空间,UEFI通过所有设备的这些信息构建一张完整的关系图,描述系统中资源的分配情况,然后在合理的将地址空间配置给每个PCI设备。

BAR在bit0来表示该设备是映射到memory还是IO,bar的bit0是readonly的,也就是说,设备寄存器是映射到memory还是IO是由设备制造商决定的,其他人无法修改。

那么所以这块应该是吧设备寄存器映射到了IO。

然后漏洞在哪呢?
我们看着整体的程序还是非常复杂的。

去网上参考了大佬的思路,果然不是硬逆。
是这样的。

首先发现呢有这样的一个字符串
在这里插入图片描述然后程序是改了qemu里面的设备来的。

我们可以直接找到qemu原来的设备,然后看看改了哪些地方,从而快速按定位漏洞。

在这里插入图片描述cydfvgastate结构体里面多了两个成员

漏洞在cydf_vga_mem_write函数
函数主要逻辑很简单,就是对不同的addr做不同的处理

函数里面多了的对addr大于0x10000小于0x18000的处理
在这里插入图片描述
其中主要逻辑就是
在这里插入图片描述首先做两个判断,然后将cydfvgastate结构体里sr数组序号0xcc的值拿出来模5,然后根据这个值做一个功能选择。

在这里插入图片描述
接下来就是利用

我们上面发现漏洞可以有数组越界跟堆溢出,但是其实我们只用到数组任意写就可以了。
因为我们可以直接控制vs[10]的地方,通过
在这里插入图片描述我们明显能够控制latch数组。

最后再利用一下
在这里插入图片描述
qemu_log函数中有一个vfprintf
参数是bss的一个地址。

因为没开PIE且居然可以劫持got表
所以我们直接将vfprintf劫持成system的plt
将printf劫持成vfprintf的plt
然后将bss写上参数,就可以了。

要注意的是,以往都是用户态打开对应的resource0文件进行映射,实现mmio的访问。但是这次不知道该打开哪个文件去映射,访问该地址空间才可以实现对cydf_vga_mem_write以及cydf_vga_mem_read的访问。

这时我们可以利用/dev/mem文件,dev/mem是物理内存的全映像,可以用来访问物理内存,用mmap来访问物理内存以及外设的IO资源,是实现用户空间驱动的一种方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值