leak32
Using a format string to leak an address.
Last updated
Using a format string to leak an address.
Last updated
In this case, we won't be provided a leak. Instead, we must combine how we used format strings and find our own leak. Solving this challenge will be remarkably similar to how we solve canary challenges, so be sure you're confident in Sections 0x3 and 0x4 before moving on.
PIE is indeed enabled, and there is no canary:
We'll move straight to the read_in
function. You can verify that main
and win
haven't changed. This code is actually the same as one of the canary challenges, replacing the canary with PIE. We'll see that it doesn't change our exploit that much.
Here is the source code for read_in
. This was collected straight from gdb
, so please ensure you're confident doing this.
We'll use a format string against the first input. Let's test what happens when we do that to see what addresses get printed. In this case, because we are looking for addresses, we use %p
instead of %x
:
The only item here that looks like an address is 0x566301f9
. 0xf7ee2540
a far away instruction or a stack address, so it's not as helpful. We'll check both just to be sure our intuition is correct.
When using breakpoints on a binary with PIE enabled, they must be an offset from a known function. Addressing based on what you see in disas read_in
won't work. Use something like disas *(read_in+8)
.
Also, we can't check those specific addresses because PIE is enabled. We need to check the addresses shown on each specific run. To do this, put a breakpoint at the vulnerable printf
call and check the stack.
The first address is the address of the format string. We start counting from the second item (which reads (nil)
in the standard output). We want the third and fourth options, which also have the same high bytes.
Aha! The third value resolves to read_in + 12
, which happens to be the base pointer for read_in
. The fourth value resolves to __kernel_vsyscall
, which is a function in the kernel. The first one is more useful, so we use that.
We'll use a very similar exploit to the previous binary, just accounting for how we will receive the leak.
We'll start by establishing the binary and process:
Then, we need to receive the leak. We'll receive the third format string parameter, which we know is at read_in + 12
. From there, we'll compute elf.address
:
Now, we can build the payload. It's a simple ret2win from here!
Finally, we send the payload.
This gets us the flag! Here is the full exploit: