$ cat writeup.md…
$ cat writeup.md…
hackthebox
Task: ARM 32-bit binary exploitation under QEMU user-mode with PIE, Canary, and NX enabled. Solution: Multi-stage ROP chain — leak canary via partial overwrite, leak PIE base from saved LR, use ARM ret2csu to leak libc via GOT, then ret2libc with system("/bin/sh").
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
ARM binary exploitation challenge running under QEMU user-mode emulation with a custom ASLR patch.
ARM 32-bit ELF binary (little-endian, EABI5), dynamically linked, not stripped. Runs via qemu-arm with a custom ASLR patch. Contains a string_storer() function that reads strings in a loop, copies them to a stack buffer, and outputs them back via puts().
Remote target: 154.57.164.72:31410.
Files: arms_roped (ARM ELF binary), libc.so.6 (ARM 32-bit libc), Dockerfile (socat + qemu-arm), patch.diff (QEMU ASLR patch), build_docker.sh.
| Protection | Status |
|---|---|
| PIE | Enabled |
| NX | Enabled |
| Canary | Enabled |
| RELRO | Partial |
socat tcp-l:1337,reuseaddr,fork EXEC:./qemu_arm -L /usr/arm-linux-gnueabihf/ ./arms_roped
QEMU user-mode typically doesn't support ASLR. The organizers added a custom patch (patch.diff) that randomizes addresses via srand(time(NULL)) — a weak entropy source, but this doesn't matter for exploitation since we obtain address leaks directly.
main() (0x8dc)Sets up stdout/stderr buffering via setvbuf, then calls string_storer().
string_storer() (0x790) — Vulnerable FunctionLoop:
scanf("%m[^\n]%n", &tmp, &n) — %m allocates a heap buffer for input, %n writes the number of bytes read to a global variable nmemcpy(stack_buf, tmp, n) — copies n bytes to a 32-byte stack buffer without bounds checkingfree(tmp) — frees the heap buffermemcmp(stack_buf, "quit", 4) — if it starts with "quit", exit the loopputs(stack_buf) — otherwise outputs the buffer contentsfp-0x30: buffer[32] ← memcpy destination (32 bytes)
fp-0x10: stack canary ← 4 bytes
fp-0x0c: padding ← 4 bytes
fp-0x08: saved r4 ← 4 bytes
fp-0x04: saved fp ← 4 bytes
fp+0x00: saved lr ← 4 bytes (return address)
...
$ grep --similar