qemu 是纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备。目前qemu出问题比较多的地方以及比赛中出题目的形式都在在设备模拟中。
所以其实这种题型一般就是关注它描述设备自定义的那个设备结构体还有与这个设备通信的相关函数。
0x01 qemu基础
主要参考这篇博客吧qemu-pwn-基础知识 « 平凡路上 (ray-cp.github.io)通过memory space访问设备I/O的方式称为memory mapped I/O,即MMIO,这种情况下,CPU直接使用普通访存指令即可访问设备I/O。
通过I/O space访问设备I/O的方式称为port I/O,或者port mapped I/O,这种情况下CPU需要使用专门的I/O指令如IN/OUT
访问I/O端口。
1.1 查看pci设备
1 | ubuntu@ubuntu:~$ lspci |
xx:yy:z
的格式为总线:设备:功能
的格式。
0x02 2021 AntCtf d3dev
2.1 设备分析
首先可以通过d3dev_class_init来判断它是哪个设备,与lspci列表下的设备对比,发现对应设备是/sys/devices/pci0000:00/0000:00:03.0
然后一般来讲,设备的数据类型IDA是没有自动加载的,需要我们手动加载一下。在IDA->views->subview->localtype里搜索 d3 可以找到这个设备结构体,用了这个结构体以后代码就好看很多了。
2.2 漏洞分析
pmio_write
首先看pmio_write函数,主要功能就四个
- addr为8时设置seek
- addr为28时调用r_rand函数
- addr为4时将key重置
- 设置memory_mode
1 | void __fastcall d3dev_pmio_write(d3devState *opaque, hwaddr addr, uint64_t val, unsigned int size) |
pmio_read
然后再分析pmio_read函数,这个函数朴实无华,功能也十分简单。
1 | uint64_t __fastcall d3dev_pmio_read(void *opaque, hwaddr addr, unsigned int size) |
进入到dword_7ADF30之后算一下偏移发现是一串gadget,基本上的功能就是读那个设备结构体的一些值,比如seek,key之类的。
mmio_write
这个有一个越界写漏洞,出现在设置v4这个index的时候这个seek是我们自主可控的,因此会造成越界写。还有一点需要注意的就是,它那个do while实际上是一个解密的过程。x是低32位,y是高32位。
1 | void __fastcall d3dev_mmio_write(d3devState *opaque, hwaddr addr, uint64_t val, unsigned int size) |
mmio_read
这个地方跟上面的越界写一样,就是个越界读。然后还会把读出的数据进行一个加密。
1 | void __fastcall d3dev_pmio_write(d3devState *opaque, hwaddr addr, uint64_t val, unsigned int size) |
2.3 利用思路
- 利用越界读读出rand_r的地址,算出libc地址
- 利用越界写将system地址写入rand_r的位置
- 将原来seek的位置以及后面的block写入cat flag命令
- 利用pmio_write调用rand_r从而实现命令执行
2.4 本地调试
解压
1 | cpio -idmv < rootfs.img |
编译写好的exp
1 | gcc -O0 -o exp -static d3dev.c |
将写好的二进制文件编译后打包入rootfs.img中
1 | find . | cpio -o --format=newc > ../rootfs.img |
然后直接运行它的laungh.sh就行了
我在20.04的环境下可以直接运行起来,然后ps -ax
查看当前有哪些进程,使用gdb attach对应的进程就可以进行相应的调试了
调试时查看结构体可以在d3dev相关函数断点下
1
2 >p *((d3devState *)$rdi)
>
就可以查看了
0x03 exp
1 |
|
0x04 远程exp
模板来自[这里]([[Pwn 笔记]Linux Kernel 调试文件总结 | binLep’s Blog](https://binlep.github.io/2020/03/12/[Pwn 笔记]Linux Kernel 调试文件总结/))
1 | #!/usr/bin/env python |