PWN: Delulu

This challenge was the first challenge I've done which included a format string vulnerability. It was a cool learning experience and helped to demonstrate why printf() can be a dangerous function.

The challenge provided a x86-64 binary with the following protections:

The strong protections but easy rating of the challenge indicated a simple vulnerability to exploit.

I loaded the file into ghidra to decompile it and saw the function delulu along with the main:

A buffer overflow wouldn't work to overwrite the checked variable as it was at a lower address on the stack from where read() was writing to. The one thing that stood out was the pointer to the checked variable. After some digging, I found this website which explained format string vulnerabilities; specifically the ability to write to a memory location. It explained:

So how do we turn this into an arbitrary write primitive? Well, printf has a really interesting format specifier: %n. From the man page of printf: The number of characters written so far is stored into the integer indicated by the int * (or variant) pointer argument. No argument is converted. If we were to pass the string AAAA%10$n, we would write the value 4 to the address 0x41414141!

The article also mentioned how values could be printed off the stack using format specifiers such as %p. This could then be leveraged to write to the address of the pointer to the checked variable. After printing variables off the stack the pointer came up as the seventh item.

The value to be written was 0x1337beef which is 322420463. That was a few too many characters for the buffer so a width modifier was used to print some number of characters prior to the rest of the format string arguments. For example, %25x means the characters printed should be at least 25. Finally, the format specifier %7$n could be used to refer to the 7th argument from the stack to be the location to write to.

This was all that was needed to make the format string to overwrite the checked varaible. It was: %322420463x%7$n. It says; write the value 322420463 to the memory location of the 7th argument printed from the stack.

Unfortunately, I am writing this after the event ended and no longer have access to the challenge server hence the fake flag.