Wargames.MY 2023: Pak Mat Burger
Delight in Pak Mat's exclusive burger, reserved just for our special customers
TL;DR
Exploit read primitive of
printf()to leak random secret, canary, LIBC and PIE addresses, followed by a Buffer Overflow that leads to ret2win.
Challenge Overview
This challenge is almost identical to SiberSiaga 2023: Password Generator where we have a Format String Vulnerability to defeat Stack Canary & PIE, which then leads to a Buffer Overflow. However, this challenge introduces a twist by using a randomly generated secret. This write-up will mainly focus on leaking the secret.

Taking a look at the provided files, we understand that the SECRET is generated randomly at runtime using /dev/null.
The Dockerfile shows that the start.sh script is executed when the Docker container is built, instead of side-loading the execution to xinetd. This means that the SECRET will stay the same throughout connections, and only differ when the container is re-built. (Think of it like a PRNG with a known seed)
Leaking Secret
To find the location of the secret, we can enter a hardcoded secret and debug the program locally. Since PIE is enabled, I placed the 1st breakpoint at main to let GDB resolve the PIE base.

Then, place a 2nd breakpoint right after the program is done loading SECRET from environment variables.

Since the SECRET is located on the top of the stack, and we know that there are 6 registers rdi; rsi; rdx; rcx; r8; r9 that comes before the stack based on the calling convention.

This means that we can leak the SECRET through the 7th argument, or %6$s precisely (-1 due to indexing).

Solution
Since scanf limits our input to 11 characters, it thwarts our attempt to leak all 3 values of SECRET + CANARY + LIBC/PIE at once.

Thankfully, the SECRET value is always the same for all connections made to the remote instance. As a workaround, we can leak the SECRET in 1st connection, disconnect; and then leak the remaining values during the 2nd connection.

Method 1: ret2libc
Since there are ROP Gadgets available, leaking PIE is optional. We can just leak SECRET + CANARY + LIBC to perform a ret2libc attack.

Flag: wgmy{4a029bf40a28039c8492acfa866f8d96}
Method 2: ret2win
As an alternative, there is a win function called secret_order.

If we were to use this win function, we need to leak PIE instead of LIBC.

Flag: wgmy{4a029bf40a28039c8492acfa866f8d96}
Final Script
Method 1
Method 2
Last updated