This week, I decided to solve a challenge on pwnable.kr called mipstake. It is a simple mips userspace pwnable, but since I did not have any MIPS device I went through some painful processes during the debugging environment setup. In this post, I will be introducing the usage of qemu-system-mips
to emulate MIPS userspace binaries and debug them using GDBserver.
This part is easy. Just execute apt-get install qemu qemu-system
This process can be done with the following script.
#!/bin/sh
wget http://ftp.debian.org/debian/dists/stable/main/installer-mips/current/images/malta/netboot/initrd.gz
wget http://ftp.debian.org/debian/dists/stable/main/installer-mips/current/images/malta/netboot/vmlinux-4.19.0-5-4kc-malta
qemu-img create -f qcow2 hda.img 20G
qemu-system-mips -M malta \ -m 256 -hda hda.img \ -kernel vmlinux-4.19.0-5-4kc-malta \ -initrd initrd.gz \ -append "console=ttyS0 nokaslr" \ -nographic
The last line will pop up a curses based install, where you can just set options as you wish.
This can be done with the following script.
#!/bin/sh
sudo modprobe nbd max_part=63
sudo qemu-nbd -c /dev/nbd0 hda.img
sudo mount /dev/nbd0p1 /mnt
cp -r /mnt/boot/initrd.img-4.19.0-5-4kc-malta . # copy only initrd.img file
cp -r /mnt/boot .
sudo umount /mnt
sudo qemu-nbd -d /dev/nbd0
#!/bin/sh
qemu-system-mips -M malta \
-m 256 -hda hda.img \
-kernel vmlinux-4.19.0-5-4kc-malta \
-initrd initrd.img-4.19.0-5-4kc-malta \
-append "root=/dev/sda1 console=ttyS0 nokaslr" \
-nographic \
-redir tcp:2222::22 \
-redir tcp:5555::1234 \
-redir tcp:5556::9033
There are a total of 3 TCP redirections. The first one, 2222::22 is used for ssh and sftp. You can ssh the VM via: ssh <user>@localhost -p 2222
The redirection 5555:1234 is for GDBserver, as GDBserver’s default port is 1234.
The last redirection 5556:9033 is required to send packets to the userspace binary we will be exploiting.
Easy: apt-get install gdbserver gdb
Easy again: apt-get install gdb-multiarch
gdbserver localhost:1234 <userprog_name>
First, execute gdb-multiarch
. Then execute the following commands. Afterwards, you can add breakpoints, view memory, set follow-fork-mode or whatever. It is convenient to save the necessary commands as a script and use the source
command in GDB to execute them all at once.
set architecture mips
target remote localhost:5555
The thing with GDBserver is that all GDB plugins in the host (outside the vm) are applied, so it is possible to use plugins like pwndbg and peda if you use gdbserver instead of just gdb’ing the binary.