You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: content/blog/seccon2024-babyqemu/index.md
+6-6
Original file line number
Diff line number
Diff line change
@@ -6,21 +6,21 @@ params:
6
6
links:
7
7
- name: channel
8
8
link: https://t.me/theinkyvoid
9
-
title: "seccon 2024 - BabyQEMU"
9
+
title: "Seccon Quals 2024 - BabyQEMU"
10
10
tldr: "simple qemu escape challenge"
11
11
date: "2024-11-24"
12
12
tags: [pwn]
13
13
summary: |
14
14
Given heap offset write and read in custom qemu pcie device obtain qemu escape.
15
15
---
16
16
17
-
# BabyQEMU (seccon quals 2024)
17
+
# BabyQEMU
18
18
19
-
After solving a complicated rop challenge on Seccon quals, we came across this deceptivly simple challenge, where the goal was to escape qemu through a custom pcie device. I had never solved hypervisor escape challenges prior and really am not a pwn guy, but I had a friend and thought it would be fun.
19
+
After solving a complicated rop challenge on Seccon quals, we came across this deceptively simple challenge, where the goal was to escape qemu through a custom pcie device. I had never solved hypervisor escape challenges prior and really am not a pwn guy, but I had a friend and thought it would be fun.
20
20
21
21
## Quick summary
22
22
23
-
We are given a modified qemu version with a custom pcie device that impliments memory maped io. It basicly has 2 addresses: data and offset. Writting to offset address will change the offset in the device structure. Reading or writing from data will read or write at the offset from the buffer stored in the device structure. Pretty simple right?
23
+
We are given a modified qemu version with a custom pcie device that implements memory mapped io. It basically has 2 addresses: data and offset. Writting to offset address will change the offset in the device structure. Reading or writing from data will read or write at the offset from the buffer stored in the device structure. Pretty simple right?
Whats not so simple is actually interfacing with device. At first I tried to write a kernel module (which would have been the optimal solution), I won't bore you with the detail, suffice to say I tried everything and nothing worked. Then searching the wired I found that busybox (which is installed) in qemu has a devmem module that just so happens to allow us to read and write to/from memory maped io. So I quickly tested that I worked, wrote some helped functions that would execute `busybox devmem`, the wrote some more helper functions to write to an offset. I should note note that for some reason devmem only allowed me to write 32 bits worth of data, so I also had to write functions to write 64 bit integers.
64
+
Whats not so simple is actually interfacing with device. At first I tried to write a kernel module (which would have been the optimal solution), I won't bore you with the detail, suffice to say I tried everything and nothing worked. Then searching the wired I found that busybox (which is installed) in qemu has a devmem module that just so happens to allow us to read and write to/from memory mapped io. So I quickly tested that it worked, wrote some helper functions that would execute `busybox devmem`, then wrote more helper functions to write to an offset. I should note that for some reason devmem only allowed me to write 32 bits worth of data, so I also had to write functions to write 64 bit integers.
The very first thing I did was telescope the heap address of the device structure, which yielded a heap and binary leak. Than by calculating the offset of got from buf I was able to leak libc base. Then from libc I was able to leak environ and thus the stack. That was the easy part. Unfortunately qemu had full relro and the stack of the mmio functions was some kind of thread stack. Also the sort of main device structure (separate from the custom part) was located in a strange region, which I was able to leak, but it was had a different offset. So after a long time beating my head against a brick wall, it finally broke and I found a way to leak this strange structure pointer: I first leaked the thread stack from the heap and then the structure address from the stack. The reason I was looking for that pointer was that a function was called from a vtable without checking for the vtable region. The vtable itself was ro, but we could construct a custom vtable and point the vtable pointer to it. I also miracolosly discovered an rwx region, which I also leak from the heap.
123
+
The very first thing I did was telescope the heap address of the device structure, which yielded a heap and binary leak. Than by calculating the offset of got from buf I was able to leak libc base. Then from libc I was able to leak environ and thus the stack. That was the easy part. Unfortunately qemu had full relro and the stack of the mmio functions was some kind of thread stack. Also the sort of main device structure (separate from the custom part) was located in a strange region, which I was able to leak, but it had a different offset. So after a long time beating my head against a brick wall, it finally broke and I found a way to leak this strange structure pointer: I first leaked the thread stack from the heap and then the structure address from the stack. The reason I was looking for that pointer was that a function was called from a vtable without checking for the vtable region. The vtable itself was ro, but we could construct a custom vtable and point the vtable pointer to it. I also miraculously discovered an rwx region, which I also leak from the heap.
0 commit comments