# compile qemu
sudo apt update
sudo apt install libglib2.0-dev libpixman-1-dev libsdl2-dev libsdl1.2-dev
git clone https://gitlab.com/qemu-project/qemu.git && cd qemu
or git clone https://mirrors.tuna.tsinghua.edu.cn/git/qemu.git && cd qemu
## install Ninja
sudo apt install re2c
sudo apt install build-essential python
git clone git://github.com/ninja-build/ninja.git && cd ninja
./configure.py --bootstrap
sudo cp ninja /usr/bin/
## make
mkdir -p bin/debug/naive && cd bin/debug/naive
../../../configure --target-list=x86_64-softmmu --enable-debug --disable-werror
make -j4
./qemu-system-x86_64 --version
# make rootfs
#!/bin/sh
sudo apt-get install debootstrap
mkdir rootfs
sudo debootstrap --include=openssh-server,curl,tar,gcc,\
libc6-dev,time,strace,sudo,less,psmisc,\
selinux-utils,policycoreutils,checkpolicy,selinux-policy-default \
stretch rootfs
set -eux
sudo sed -i '/^root/ { s/:x:/::/ }' rootfs/etc/passwd
echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a rootfs/etc/inittab
printf '\nallow-hotplug enp0s3\niface enp0s3 inet dhcp\n' | sudo tee -a rootfs/etc/network/interfaces
echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a rootfs/etc/fstab
echo "kernel.printk = 7 4 1 3" | sudo tee -a rootfs/etc/sysctl.conf
echo 'debug.exception-trace = 0' | sudo tee -a rootfs/etc/sysctl.conf
echo "net.core.bpf_jit_enable = 1" | sudo tee -a rootfs/etc/sysctl.conf
echo "net.core.bpf_jit_harden = 2" | sudo tee -a rootfs/etc/sysctl.conf
echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a rootfs/etc/sysctl.conf
echo -en "127.0.0.1\tlocalhost\n" | sudo tee rootfs/etc/hosts
echo "nameserver 8.8.8.8" | sudo tee -a rootfs/etc/resolve.conf
echo "ubuntu" | sudo tee rootfs/etc/hostname
sudo mkdir -p rootfs/root/.ssh/
rm -rf ssh
mkdir -p ssh
ssh-keygen -f ssh/id_rsa -t rsa -N ''
cat ssh/id_rsa.pub | sudo tee rootfs/root/.ssh/authorized_keys
dd if=/dev/zero of=rootfs.img bs=1M seek=2047 count=1
sudo mkfs.ext4 -F rootfs.img
sudo mkdir -p /mnt/rootfs
sudo mount -o loop rootfs.img /mnt/rootfs
sudo cp -a rootfs/. /mnt/rootfs/.
sudo umount /mnt/rootfs
# compile linux
sudo apt install libelf-dev
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.2.11.tar.xz -O linux-5.2.11.tar.xz
tar -xvf linux-5.2.11.tar.xz && cd linux-5.2.11/
make defconfig
make kvmconfig
#编辑 .config 文件, 将 CONFIG_8139CP=y 和 CONFIG_PCNET32=y 打开
make -j4
# run
./qemu/bin/debug/naive/x86_64-softmmu/qemu-system-x86_64 \
-kernel ./linux-5.2.11/arch/x86/boot/bzImage \
-append "console=ttyS0 root=/dev/sda rw" \
-hda ./rootfs.img \
-enable-kvm -m 2G -nographic \
-netdev user,id=t0, -device rtl8139,netdev=t0,id=nic0 \
-netdev user,id=t1, -device pcnet,netdev=t1,id=nic1 \
-net user,hostfwd=tcp::10021-:22 -net nic \
-device virtio-gpu-pci \
-device strng
# debug
- GDB调试QEMU时经常遇到SIGUSR1与SIGUSR2后停下来,解决办法是执行命令:
(gdb) handle SIGUSR1 SIGUSR2 noprint nostop
- qemu fuzz时是启动子进程,下断点时需要执行:
(gdb) set follow-fork-mode child
- stacktrace
gef➤ bt
#0 strng_mmio_write (opaque=0x7ffff54a86b8, addr=0xec4cb480, val=0xffffffff, size=0x0) at ../../../hw/6
#1 0x0000555555bdba85 in memory_region_write_accessor (mr=0x55555787bdf0, addr=0x8, value=0x7ffff54a862
#2 0x0000555555bdbcc8 in access_with_adjusted_size (addr=0x8, value=0x7ffff54a86b8, size=0x4, access_s4
#3 0x0000555555bdedbc in memory_region_dispatch_write (mr=0x55555787bdf0, addr=0x8, data=0x20746163, o4
#4 0x0000555555bd1b22 in flatview_write_continue (fv=0x7fffec305e20, addr=0xfebf4008, attrs=..., ptr=02
#5 0x0000555555bd1c6b in flatview_write (fv=0x7fffec305e20, addr=0xfebf4008, attrs=..., buf=0x7ffff7fc2
#6 0x0000555555bd1fe7 in address_space_write (as=0x555556723de0 <address_space_memory>, addr=0xfebf4004
#7 0x0000555555bd2058 in address_space_rw (as=0x555556723de0 <address_space_memory>, addr=0xfebf4008, 4
#8 0x0000555555cf2f71 in kvm_cpu_exec (cpu=0x555556a06df0) at ../../../accel/kvm/kvm-all.c:2903
#9 0x0000555555cf4df2 in kvm_vcpu_thread_fn (arg=0x555556a06df0) at ../../../accel/kvm/kvm-accel-ops.c9
#10 0x0000555555ed4669 in qemu_thread_start (args=0x555556a14f00) at ../../../util/qemu-thread-posix.c:6
#11 0x00007ffff76e9609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#12 0x00007ffff7610293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
# fuzz
mkdir fuzz && cd fuzz
sudo apt install clang
CC=clang-11 CXX=clang++-11 ../configure --enable-sanitizers --enable-fuzzing
make qemu-fuzz-i386 -j4
./qemu-fuzz-i386 --fuzz-target=FUZZ_NAME
# reproducer
QEMU_FUZZ_TIMEOUT=0 QTEST_LOG=1 FUZZ_SERIALIZE_QTEST=1 qemu-fuzz-i386 --fuzz-target... ./crash-... &> /tmp/trace
scripts/oss-fuzz/reorder_fuzzer_qtest_trace.py /tmp/trace > /tmp/reproducer
./qemu/bin/debug/naive/x86_64-softmmu/qemu-system-x86_64 -display none -machine accel=qtest -m 512M -machine q35 -nodefaults -device virtio-gpu -qtest stdio < /tmp/reproducer
export QEMU_ARGS="-display none -machine accel=qtest, -m 512M -machine q35 -nodefaults -device virtio-gpu"
export QEMU_PATH="./qemu/bin/debug/naive/x86_64-softmmu/qemu-system-x86_64"
$QEMU_PATH $QEMU_ARGS -qtest stdio < /tmp/reproducer
# minimize reproducer
export CRASH_TOKEN="memory_ldst_cached.h.inc"
qemu/scripts/oss-fuzz/minimize_qtest_trace.py -M1 -M2 /tmp/reproducer /tmp/reproducer-minimized
$QEMU_PATH $QEMU_ARGS -qtest stdio < /tmp/reproducer-minimized
qemu/scripts/oss-fuzz/output_reproducer.py -bash /tmp/reproducer-minimized
# exp tpl
#include <stdio.h>
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/pci.h>
#include <sys/io.h>
#include <string.h>
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)
#define PFN_PRESENT (1ull << 63)
#define PFN_PFN ((1ull << 55) - 1)
uint8_t *mmio_base;
uint32_t port_base = 0xc040;
int fd;
uint32_t mmio_read(uint32_t addr)
{
return *(uint32_t *)(mmio_base + addr);
}
void mmio_write(uint32_t addr, uint32_t val)
{
*(uint32_t *)(mmio_base + addr) = val;
}
uint32_t pmio_read(uint32_t port)
{
return inl(port_base + port);
}
void pmio_write(uint32_t port, uint32_t val)
{
outl(val, port_base + port);
}
uint32_t page_offset(uint32_t addr)
{
return addr & ((1 << PAGE_SHIFT) - 1);
}
uint64_t gva_to_gfn(void *addr)
{
uint64_t pme, gfn;
size_t offset;
offset = ((uintptr_t)addr >> 9) & ~7;
lseek(fd, offset, SEEK_SET);
read(fd, &pme, 8);
if (!(pme & PFN_PRESENT))
return -1;
gfn = pme & PFN_PFN;
return gfn;
}
uint64_t gva_to_gpa(void *addr)
{
uint64_t gfn = gva_to_gfn(addr);
assert(gfn != -1);
return (gfn << PAGE_SHIFT) | page_offset((uint64_t)addr);
}
int main(int argc, char const *argv[])
{
fd = open("/proc/self/pagemap", O_RDONLY);
if (fd < 0)
{
puts("[*]pagemap error!");
exit(0);
}
uint32_t *target = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
mlock(target, 0x1000);
printf("[*] visual addr 0x%lx\n", target);
uint32_t pt = gva_to_gpa(target);
printf("[*] physical addr 0x%lx\n", pt);
int mmio_fd = open("/sys/devices/pci0000:00/0000:00:06.0/resource0", O_RDWR | O_SYNC);
if (mmio_fd < 0)
{
puts("[*]mmio open file error!");
exit(0);
}
mmio_base = mmap(0, 256, PROT_READ | PROT_WRITE, MAP_SHARED, mmio_fd, 0);
mmio_write(8, 0x11228899);
uint32_t x=mmio_read(8);
printf("val %x\n",x);
if (iopl(3) !=0 )
exit("I/O permission is not enough");
return 0;
}
# fix
> Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
> ---
> hw/virtio/virtio.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 874377f37a7..04ffe5f420e 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -2255,6 +2255,7 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
> return;
> }
> vdev->vq[n].vring.num = num;
> + virtio_queue_update_rings(vdev, n);
> }
>
> VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector)
> --
> 2.31.1
>
# links
https://gsec.hitb.org/sg2017/sessions/qemu-attack-surface-and-security-internals/
http://brieflyx.me/2019/linux-tools/qemu-escape-attack-surface/
https://paper.seebug.org/955/
https://www.136.la/jingpin/show-109662.html
https://www.ei.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2020/02/07/Hyper-Cube-NDSS20.pdf
https://arxiv.org/pdf/2109.10660.pdf
https://www.youtube.com/watch?v=dk6SUD8ovXw
https://i.blackhat.com/asia-20/Thursday/asia-20-Shao-3D-Red-Pill-A-Guest-To-Host-Escape-On-QEMUKVM-Virtio-Device.pdf
https://www.anquanke.com/post/id/211930
https://www.usenix.org/system/files/sec21summer_schumilo.pdf
https://gsec.hitb.org/materials/sg2017/D2%20-%20Qiang%20Li%20and%20ZhiBin%20Hu%20-%20QEMU%20Attack%20Surface%20and%20Security%20Internals.pdf
https://larry.ngrep.me/2019/07/22/wctf-2019-virtualhole-write-up/
http://pwn4.fun/2020/02/02/%E8%B0%83%E8%AF%95Qemu-CVE-2016-4952/
https://cool-y.github.io/2021/04/10/vm-escape1/
https://a1ex.online/2021/10/24/CVE-2019-6788-Qemu%E9%80%83%E9%80%B8%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0%E4%B8%8E%E5%88%86%E6%9E%90/
qemu编译安装
https://www.cnblogs.com/from-zero/p/14327440.html
QEMU 虚拟机逃逸漏洞分析与利用(CVE-2019-14378)
https://www.anquanke.com/post/id/184949
qemu pwn-基础知识
https://xz.aliyun.com/t/6562
qemu-pwn-DefconQuals-2018-EC3
https://xz.aliyun.com/t/6778
调试qemu 硬盘io的过程
https://www.nul.pw/2020/02/05/285.html
跟踪qemu-kvm下的磁盘写入
https://www.nul.pw/2020/02/06/286.html
qemu-pwn 强网杯2019 两道qemu逃逸题writeup
https://ray-cp.github.io/archivers/qemu-pwn-%E5%BC%BA%E7%BD%91%E6%9D%AF2019-%E4%B8%A4%E9%81%93qemu%E9%80%83%E9%80%B8%E9%A2%98writeup
QEMU 虚拟机逃逸漏洞分析(CVE-2019-15890)
https://www.anquanke.com/post/id/201137
Qemu开源实战(一)
https://juejin.cn/post/6844904090577666056
CVE-2020-14364 QEMU逃逸 漏洞分析 (含完整EXP)
https://mp.weixin.qq.com/s/MQyczZXRfOsIQewNf7cfXw
QEMU study
https://www.anquanke.com/post/id/221268
QEMU KVM Note Ⅱ
https://github.com/Resery/Learning_Note/blob/master/QEMU/Qemu_2.md
CVE-2016-4952漏洞复现———Qemu拒绝服务漏洞
https://www.anquanke.com/post/id/226748
CVE-2020-14364漏洞复现——Qemu逃逸漏洞
https://www.anquanke.com/post/id/227283
再看云虚拟化安全 QEMU通用漏洞挖掘新思路
https://vipread.lanzoui.com/iQURjlddemd
qemu逃逸学习
https://www.anquanke.com/post/id/235191
Qemu漏洞分析记录 CVE-2015-5165
https://www.anquanke.com/post/id/239263
多种方法利用QEMU-CVE-2020-14364(一)
https://www.anquanke.com/post/id/243343
基于Qemu/kvm硬件加速的下一代安全对抗平台
https://vipread.lanzoui.com/iYE5cwbadsj
Virtio:一种Linux I/O虚拟化框架
https://www.anquanke.com/post/id/224001
VirtIO-GPU环境搭建与应用
https://blog.csdn.net/huang987246510/article/details/106245900/
虚拟化之——virtio-net基础篇
https://blog.csdn.net/21cnbao/article/details/116311054
CVE-2020-14364 Qemu越界读写漏洞复现与分析
https://ama2in9.top/2021/01/09/cve-2020-14364/
Qemu Fuzzer学习
https://blog.csdn.net/weixin_42733202/article/details/119715287
PCI配置空间
https://wiki.osdev.org/PCI