QEMU堆溢出漏洞----CVE-2015-7504

CVE-2015-7504是QEMU在仿真pcnet网卡中出现的一个堆溢出漏洞,可以溢出四个字节,可以劫持程序的执行流,结合前面的CVE-2015-5165可以实现任意代码执行。但有一个很致命的问题,宿主机内核需要使用CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE 标志进行编译,否则在溢出的四个字节没法成功修改地址(总体八个字节的地址,因此需要高四字节与目标地址一致)。这个编译标志在目前最新的Ubuntu16.04中似乎已经没有了,所以就不进行完整的复现了,仅复现至PoC部分。

PCNET网卡

AMD 的PCNET系列网卡被许多虚拟机或仿真器支持,如QEMU、VMware和VirtualBox。虽然没有RTL8139简易,但它的支持更加广泛,RTL8139只在QEMU中有支持。

网卡有16位和32位两种模式,这取决于DWIO 的值(储存在卡中变量),16位模式是网卡重置之后的默认模式。网卡有两类内部寄存器:CSR(控制和状态寄存器)和BCR(Bus Control Register)。

1
2
3
4
5
6
7
8
9
10
11
12
0                                  16
+----------------------------------+
| EPROM |
+----------------------------------+
| RDP - Data reg for CSR |
+----------------------------------+
| RAP - Index reg for CSR and BCR |
+----------------------------------+
| Reset reg |
+----------------------------------+
| BDP - Data reg for BCR |
+----------------------------------+

QEMU信息泄露漏洞分析与利用----CVE-2015-5165

参考大佬们的文章复现CVE-2015-5165。

环境搭建

宿主机环境 Ubuntu 20.10

QEMU编译

QEMU commit-bd80b59源码下载。

1
2
3
4
5
6
$ unzip qemu.zip
$ mkdir -p bin/debug/native
$ cd bin/debug/native
$ sudo apt-get install zlib1g-dev libglib2.0-dev libpixman-1-dev
$ ../../../configure --target-list=x86_64-softmmu --enable-debug --disable-werror
$ make

如果出现以下错误,给文件 commands-posix.c 增加头文件 <sys/sysmacros.h> 即可解决。

1
2
3
/usr/bin/ld: qga/commands-posix.o: in function `dev_major_minor':
/repo/qemu/qga/commands-posix.c:640: undefined reference to `major'
/usr/bin/ld: /repo/qemu/qga/commands-posix.c:641: undefined reference to `minor'

制作QEMU虚拟机

这里我使用的Ubuntu 16.04 Server i386作为QEMU客户机系统。点击下载

还需要下载安装VNC-Viewer,稍后会用到。链接

1
2
3
4
5
6
$ ./qemu-img create -f qcow2 ~/tmp/vm/ubuntu.img 10G
$ sudo dpkg -i VNC-Viewer-6.20.529-Linux-x64.deb
$ x86_64-softmmu/qemu-system-x86_64 -boot d -cdrom \ # 能用嵌套虚拟就用(添加--enable-kvm)
~/tmp/iso/ubuntu-16.04.6-server-i386.iso \
-hda ~/tmp/vm/ubuntu.img -m 1024
$ vncviewer host:port # 连接上,安装就好

(尽量使用–enable-kvm,否则卡的受不了,安装系统安了四五个小时。。。)

HITB GSEC 2017:babyqemu

题目下载地址:babyqemu.tar.gz

分析

tar xvzf babyqemu.tar.gz解压看到启动脚本launch.sh

1
2
3
4
5
6
7
8
9
10
#! /bin/sh
./qemu-system-x86_64 \
-initrd ./rootfs.cpio \
-kernel ./vmlinuz-4.8.0-52-generic \
-append 'console=ttyS0 root=/dev/ram oops=panic panic=1' \
-enable-kvm \ # 需要CPU virtualization,现在与hyper-v共存的VMware不支持此选项。可以删掉
-monitor /dev/null \
-m 64M --nographic -L ./dependency/usr/local/share/qemu \
-L pc-bios \
-device hitb,id=vda

在最后一行可以看到设备名称为hitb,在ida左侧Functions window,ctrl+f搜索hitb就可以找到相关函数。通过在ida的Local Types窗口搜索hitb可以找到HitbState结构体,其中还包含dma_state结构体。

【翻译】Virtio:一种Linux I/O虚拟化框架

首发于安全客Virtio:一种Linux I/O虚拟化框架 - 安全客,安全资讯平台 (anquanke.com)

原文:Virtio: An I/O virtualization framework for Linux – IBM Developer

学习Virtio推荐首先看这一篇,国内好多文章写的太乱了,看来看不去都不明白整体的架构,给人很模糊的感觉。这篇文章好很多。

受限于个人水平,翻译肯定有不妥之处,译注根据自己的理解加入,也不一定准确。如有错误,还请不吝指出。

简言之,virtio是设备和半虚拟化管理程序(paravirtualized hypervisor)之间的一个抽象层。virtio是Rusty Russell为了支持他自己的虚拟化方案lguest而开发的。这篇文章以对半虚拟化和设备仿真的介绍开始,然后探寻virtio中的一些细节。采用kernel 2.6.30版本的virtio框架进行讲解。

Linux是hypervisor的“游乐场”。正如我在文章使用Linux作为hypervisor中所展现的,Linux提供了许多具有不同特性和优势的虚拟化解决方案。例如KVM(Kernel-based Virtual Machine),lguest、和用户态的Linux。在Linux使用这些虚拟化解决方案给操作系统造成了重担,因为它们各自都有独立的需求。其中一个问题就是设备的虚拟化。virtio为各种各样设备(如:网络设备、块设备等等)的虚拟提供了通用的标准化前端接口,增加了各个虚拟化平台的代码复用。而不是各自为政般的使用繁杂的设备虚拟机制。

全虚拟化 vs. 半虚拟化

我们先来讨论两种完全不同的虚拟化方案:全虚拟化和半虚拟化。在全虚拟化中,客户操作系统在hypervisor上运行,相当于运行于裸机一般。客户机不知道它在虚拟机还是物理机中运行,不需要修改操作系统就可以直接运行。与此相反的是,在半虚拟化中,客户机操作系统不仅能够知道其运行于虚拟机之上,也必须包含与hypervisor进行交互的代码。但是能够在客户机和hypervisor的切换中,带来更高的效率(图1)。

译注:客户机与hypervisor的切换举例:客户机请求I/O,需要hypervisor中所虚拟的设备来响应请求,此时就会发生切换。

在全虚拟化中,hypervisor必须仿真设备硬件,也就是说模仿硬件最底层的会话(如:网卡驱动)。尽管这种仿真看起来方便,但代价是极低的效率和高度的复杂性。在半虚拟化中,客户机与hypervisor可以共同合作让这种仿真具有更高的效率。半虚拟化不足就是客户机操作系统会意识到它运行于虚拟机之中,而且需要对客户机操作系统做出一定的修改。

Qemu Escape ---- 以BlizzardCTF2017_STRNG为例

最近想学一下qemu escape的基础知识,进而分析一些Qemu的CVE漏洞。

本文主要参考raycp师傅的两篇文章。[1] [2]

Qemu概述

每个运行的qemu虚拟机对应于host上的一个进程,虚拟机的执行线程(如CPU线程、I/O线程等)对应于qemu进程中的一个线程。

qemu-architecture

qemu的内存结构,根据QEMU Case Study,虚拟机对应的内存结构为如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
                        Guest' processes
+--------------------+
Virtual addr space | |
+--------------------+
| |
\__ Page Table \__
\ \
| | Guest kernel
+----+--------------------+----------------+
Guest's phy. memory | | | |
+----+--------------------+----------------+
| |
\__ \__
\ \
| QEMU process |
+----+------------------------------------------+
Virtual addr space | | |
+----+------------------------------------------+
| |
\__ Page Table \__
\ \
| |
+----+-----------------------------------------------++
Physical memory | | ||
+----+-----------------------------------------------++