This lab is build around a vulnerable HTTP daemon which runs on a virtualized QEMU environment on an eumulated ARMv7 Cortex-A15 processor.

|                  |
|  armbox          |
|                  |
|      +-----------+      attacking myhttpd
|      |myhttpd   ||
|      |TCP 8080  || <----------------+
|      +-----------+
|                  |

I prepared scripts, the vulnerable daemon and everything else you need to successfully write your own ROP chain. You can find the latest version of the scripts and the vulnerable daemon in my Github repository. If you have suggestions to improve the setup, I'd happy to include them!

Clone the whole repo. For this part of this series you will need the scripts in the armbox directory.

Set up the QEMU environment

QEMU is a pain. I wrote a set of scripts to build a RAW QEMU ArchLinuxArm image, which boots in QEMUs with a emulated Cortex-A15. Use the scripts as reference - I do not make any checks for failed commands. I used the "-M virt" as emulated maschine in QEMU.

The basic process to set up the initial QEMU armbox (folder in repo: inital_image)

  1. Download the latest ArchLinuxARM image using
  2. will create a RAW QEMU image, loopback-mount it, extract the downloaded ArchLinuxARM-armv7-latest.tar.gz into the mounted image.
  3. will create an initramfs. This initramfs will contain ALL current kernel modules. That way we can be sure that all QEMU devices are initialized correctly in initramfs during boot. This script will extract the latest modules from the downloaded ArchLinuxArm tar.gz file and repack them into a new all-modules containing initramfs.
  4. will extract the kernel image (zImage).
  5. boot your device using Take a look at the QEMU start command, which will explain the previous scripts further more.

After you booted the initial image successfully, you may update the image. After the first kernel update inside the armbox use to extract the latest initramfs and kernel image out of the updated armbox.img RAW image partition. We need these files to boot our system in QEMU (we add the initramfs and the kernel image (zImage) as parameters, when qemu-system-arm is executed. See You have to extract the initramfs and the kernel image after each kernel update!

Why the extraction process?

The qemu-system-arm's "-M virt" emulated hardware needs kernel modules which are not included in the default initramfs of ArchLinuxARM. Thats why I added a script to prepare an initramfs which includes all-modules. When Archlinux updates the kernel on a booted installation, an autodetect script checks the current hardware and includes only the modules which are really needed for booting YOUR hardware into the new initramfs. Thats also the reason for the really big initial initramfs my script builds and the comparatively small one, after the first kernel update, extracted by

You can use the to boot QEMU using the extracted initramfs and kernel image.

The armbox has 2 network interfaces, one NATed and the other one is added to a bridge on the host called vmboxnet. On my host thats an interface on which I bind services (like SSH and in this case myhttpd) to access them. If you see IP addresses through this post:

  • is the hosts IP on the vmboxnet
  • is the virtualized armbox QEMU guest on vmboxnet

You will also need to to create the file /etc/qemu/bridge.conf and add:

allow vmboxnet

to that file so that the qemu vm boots successfully.

Important: (For now) disable ASLR on the virtual environment:

echo 0 > /proc/sys/kernel/randomize_va_space

myhttpd: vulnerable microhttpd implementation

I created a simple vulnerable HTTP daemon based on GNU Libmicrohttpd's example code. Spot the Stack Based Overflow :)

Find the code in my GitHub

You will need libmicrohttpd installed on the armbox. Archlinux has a precompiled package: pacman -S libmicrohttpd

Then compile myhttpd:

gcc -lmicrohttpd httpd.c -o myhttpd`

and copy it into the folder /usr/sbin.

For easier use I wrote a systemd service file, which restarts myhttpd, after it crashed:

[root@armbox microhttps]# cat /etc/systemd/system/myhttpd.service

ExecStart=/usr/sbin/myhttpd 8080
systemctl enable myhttpd
systemctl start myhttpd


I am going to use the latest radare2 version, together with gdbserver running on the armbox. Through the vmboxnet interface I connect radare2 to armboxnet.

For reference:

armbox: while true; do gdbserver --attach :5000 $(pidof myhttpd);done
host: r2 -a arm -D gdb gdb://

<< previous post of this series | next post of this series >>