Posts WPICTF 2021 - Strong ARM [Pwn]
Post
Cancel

WPICTF 2021 - Strong ARM [Pwn]

In this challenge we have an ELF binary that has been compiled for the aarch64 architecture. We do not need to reverse engineer the file because the source is already provided.

First of all, we execute checksec against the binary and we notice that the binary is only compiled with NX protection.

1
2
3
4
5
6
7
Checksec:

Arch:     aarch64-64-little
RELRO:    No RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

The vulnerable function calls gets, which introduces a buffer overflow vulnerability.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int vulnerable() {
	char buffer[128];

	printf("> ");
	fflush(stdout);

	gets(buffer);

	puts("Your Input: \n");
	puts(buffer);
	fflush(stdout);
}

int main(int argc, char** argv) {
	printf("print at %p\n", printf);
	vulnerable();

	return EXIT_SUCCESS;
}

All this program does is print the user’s input. The program leaks printf’s address that we will use to bypass the ASLR protection.

1
2
3
4
5
6
7
$ qemu-aarch64-static -L /usr/aarch64-linux-gnu/ ./arm

print at 0x5500896080
> w00t
Your Input: 

w00t

If we input a long string we will exceed the expected buffer and we will cause a segfault, because we will overwrite the return address when the vulnerable function returns.

1
2
3
4
5
6
7
8
$ qemu-aarch64-static -L /usr/aarch64-linux-gnu/ ./arm

print at 0x5500896080
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
Your Input: 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
qemu: uncaught target signal 11 (Segmentation fault) - core dumped

We need to prepare the debbuging enviroment to be able to interact with the binary. On one side we have the qemu-aarch64-static emulator to be able to run it. On the other side we have the gdb-multiarch debugger that connects to the emulator in order to debug the binary.

In aarch64 architecture the instruction pointer register is called x30 and arguments are passed using first eight registers (x0 to x7)

1. Calculating offset

The first step is to calculate the offset at which our input buffer overwrites the return address. We use pwntools’ cyclic generator or a similar function to obtain it. The number of bytes until we overwrite x30 are 136.

2. Leaking libc base address

We can use the printf leaked address to calculate the libc base address. This way we are able to locate the execl function address and the /bin/sh string during execution.

3. Preparing the ropchain

Now we have all the addresses to perform a ret2libc. The execl function has to be called with two arguments. The first one is the pointer to a string indicating the path of the binary to execute, and the second one is the pointer to the arguments string.

In this case we want to execute the following:

1
execl(ptr_to_binsh,NULL);

This is the high level diagram of the explotation:

Full exploit code it is available here

Running the previous exploit we receive a shell, which we use to get the flag: WPI{a1ARM3d_arM315}

This post is licensed under CC BY 4.0 by the author.