Introduction
In the previous part, I give an introduction on how to create an ubuntu image for QEMU. However, after beginning to analyse the qemu vulnerability I feel the debugging process is very uncomfortable. What I prefer is just a terminal of QEMU with a guest running on that. This makes me recall what I do on Syzkaller fuzzer.
In this post, I just list the necessary steps to create a much more friendly debugging environment.
Set Up Environment
Step 1: Download Linux Kernel
Go to https://www.kernel.org/ and download the latest version of linux kernel. In this post, I use linux-4.15.7 for building. Then go to the kernel directory and build the kernel
make defconfig make kvmconfig make -j 4
Step 2: Create Debian-Stretch Linux image
Install debootstrap first.
sudo apt-get install debootstrap
Then install the necessary utilities for Debian Image
mkdir qemu sudo debootstrap --include=openssh-server,curl,tar,gcc,\ libc6-dev,time,strace,sudo,less,psmisc,\ selinux-utils,policycoreutils,checkpolicy,selinux-policy-default \ stretch qemu
Next create the debian image
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
Step 3: Run QEMU
I use the following script to start up the virtual machine hosted by QEMU for debugging.
../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
After running the guest OS in the terminal, we can simply use copy-and-paste to share the text between the guest and host. To pass large file to virtual machine, we can use the SimpleHTTPServer module in python as mentioned in [2].
Final Step: Expected Result
Pass the mmu.c file to the guest machine, compile and run. We can get the same result as the previous post.
Some notes on the set-up
I make some modifications in the script given in [1].
The first point is adding “rw” in the -append option. Without this option, the file system of guest machine will be read-only with error message ” Failed to start Create Volatile Files and Directories.”
The second point is using “printf ‘\nauto enp0s3\niface enp0s3 inet dhcp\n'” in image creation. The name of the network interface seems to be dependent on the machine.
Conclusion
Except for the friendly debugging environment, another good point of such set-up is the separation of kernel and drive. Since many QEMU vulnerabilities involve the driver operation in the guest, we easily replace the kernel image with the required version and kernel support.
Reference
[1] https://github.com/google/syzkaller/blob/master/docs/linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md
[2] http://blog.vmsplice.net/2011/09/how-to-share-files-instantly-between.html
[…] launch script is very hard to debug. Therefore, I change the setting to the configuration given in QEMU Debugging Environment Set-up as […]
LikeLiked by 1 person
[…] and CONFIG_DEBUG_INFO. The image file is created with the same method in my previous post on QEMU debug environment. We use GDB+QEMU for debugging. Though the debugging is not easy compared to debugging on a virtual […]
LikeLiked by 1 person
[…] Then we use the following script to launch the testing machine. Option “-s” denotes to enable kernel debugging. The process to generate image file follows the same process in my previous Post […]
LikeLike
Thanks to your help,i made great progess.but i still met a problem,i do not know how to use gdb connect the qemu.,can you help me solve this problem
LikeLike
真是不好意思又要打扰你了。我不知道你是怎么做到“Pass the mmu.c file to the guest machine”,你可以告诉我具体怎么操作吗
LikeLike
For transferring the files between QEMU machine and your host, you can check reference [2]. The steps have been posted. You can take a try.
LikeLike
You can use ps -a | grep qemu to search for the PID of the lauched QEMU. Then use gdb -p XXXX to attach to the target process. XXXX is the PID of QEMU.
LikeLike