QEMU VM ESCAPE 环境搭建
0.参考
1.安装操作系统 ubuntu 17.10
1
| http://mirrors.163.com/ubuntu-releases/17.10/ubuntu-17.10.1-desktop-amd64.iso
|
2. 安装指定版本的qemu
不要使用make install. 后续使用绝对路径执行qemu
1 2 3 4 5 6 7 8
| $ git clone git://git.qemu-project.org/qemu.git $ cd qemu $ git checkout bd80b59 $ mkdir -p bin/debug/native $ cd bin/debug/native $ ../../../configure --target-list=x86_64-softmmu --enable-debug \ $ --disable-werror $ make -j 4
|
3. 创建ubuntu镜像,用户qemu运行虚拟机
3.1) 下载linux源代码
1
| https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.15.18.tar.xz
|
3.2) 编译内核
可能需要安装一下依赖包,发现错误百度一下即可。
1 2 3
| make defconfig make kvmconfig make -j 4
|
3.3) 创建Debian-Stretch image
*脚本中 enp0s3为host机网卡的名称,通过ifconfig先查看后,修改脚本保持一至
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 26 27 28
| set -eux
# Set some defaults and enable promtless ssh to the machine for root. sudo sed -i '/^root/ { s/:x:/::/ }' qemu/etc/passwd echo 'T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100' | sudo tee -a qemu/etc/inittab printf '\nauto enp0s3\niface enp0s3 inet dhcp\n' | sudo tee -a qemu/etc/network/interfaces echo 'debugfs /sys/kernel/debug debugfs defaults 0 0' | sudo tee -a qemu/etc/fstab echo "kernel.printk = 7 4 1 3" | sudo tee -a qemu/etc/sysctl.conf echo 'debug.exception-trace = 0' | sudo tee -a qemu/etc/sysctl.conf echo "net.core.bpf_jit_enable = 1" | sudo tee -a qemu/etc/sysctl.conf echo "net.core.bpf_jit_harden = 2" | sudo tee -a qemu/etc/sysctl.conf echo "net.ipv4.ping_group_range = 0 65535" | sudo tee -a qemu/etc/sysctl.conf echo -en "127.0.0.1\tlocalhost\n" | sudo tee qemu/etc/hosts echo "nameserver 8.8.8.8" | sudo tee -a qemu/etc/resolve.conf echo "ubuntu" | sudo tee qemu/etc/hostname sudo mkdir -p qemu/root/.ssh/ rm -rf ssh mkdir -p ssh ssh-keygen -f ssh/id_rsa -t rsa -N '' cat ssh/id_rsa.pub | sudo tee qemu/root/.ssh/authorized_keys
# Build a disk image dd if=/dev/zero of=qemu.img bs=1M seek=2047 count=1 sudo mkfs.ext4 -F qemu.img sudo mkdir -p /mnt/qemu sudo mount -o loop qemu.img /mnt/qemu sudo cp -a qemu/. /mnt/qemu/. sudo umount /mnt/qemu
|
4.运行qemu
1 2 3 4 5 6 7
| ../Security/qemu/bin/debug/build/x86_64-softmmu/qemu-system-x86_64 \ -kernel /home/dango/Kernel/linux-4.15.7/arch/x86/boot/bzImage \ -append "console=ttyS0 root=/dev/sda rw" \ -hda /home/dango/Kernel/Image/image03/qemu.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
|
../Security/qemu/bin/debug/build/x86_64-softmmu/qemu-system-x86_64
为第2步生成qemu程序路径
/home/dango/Kernel/linux-4.15.7/arch/x86/boot/bzImage
为第3.2中生成的路径
/home/dango/Kernel/Image/image03/qemu.img
为第3.3.4中生成文件
虚拟机运行起来后,提示输入用户名root,即登录guest虚拟机。
5.测试qemu。
在第4步中运行起的客户机,在guest 虚拟机执行如下操作
5.1 用vim创建c源代码文件mmu.c
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| //mmu.c #include <stdio.h> #include <string.h> #include <stdint.h> #include <stdlib.h> #include <fcntl.h> #include <assert.h> #include <inttypes.h>
#define PAGE_SHIFT 12 #define PAGE_SIZE (1 << PAGE_SHIFT) #define PFN_PRESENT (1ull << 63) #define PFN_PFN ((1ull << 55) - 1)
int fd;
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() { uint8_t *ptr; uint64_t ptr_mem;
fd = open("/proc/self/pagemap", O_RDONLY); if (fd < 0) { perror("open"); exit(1); }
ptr = malloc(256); strcpy(ptr, "Where am I?"); printf("%s\n", ptr); ptr_mem = gva_to_gpa(ptr); printf("Your physical address is at 0x%"PRIx64"\n", ptr_mem);
return 0; }
|
5.2 用gcc编译如下代码
如果没有先安装gcc,编译可能会有一些warning,不用在意。
5.3 执行程序