Description

Host : pwn2.chal.ctf.westerns.tokyo

Port : 16317

Note: To prevent from DoS attacks, output length is limited in 131072 characters.

As always our task is to obtain the flag on the remote server and as always we will try to obtain a remote shell.

The research

After running, the binary nicely asks us for our name:

Let’s take a look at what it exactly is doing:

First, it calls getnline with two arguments: a pointer to a local buffer and 0x40. Let’s see:

So it reads at most 0x40 bytes from stdin, stores it in the given buffer, replaces the first occurrence of a new line character with a null byte and returns length of the string.

Getting back to main, it uses sprintf to format our buffer to another one with:

Then it calls printf with the second buffer as the first argument. Yay, a format string vulnerability is present!

The pwn

We have a few options to go with now:

  1. Overwrite strlen’s address in the GOT section with system’s address and force the program to execute main once again. This way the program would run system with the provided argument ( /bin/sh).
  2. Leak stack address, write ‘sh’ to some place in the memory and execute main again. Next overwrite return address with system’s address and pass it address of ‘sh’ string as it’s argument.

The first option is definitely easier, but second one is more universal and can target more similar challenges, so we will choose the latter.

Now we have to find how to change the program flow and execute the main function. After dumping section headers:

we can see there is .fini_array with one entry – we can override that (You can read about it here: http://docs.oracle.com/cd/E19683-01/817-1983/6mhm6r4es/index.html). Overwriting a GOT entry would be an option, but there is no call to any address from GOT after our vulnerable printf.

Side note: you can check what’s inside .init_array (there iss a function which makes finding system’s address trivial).

We can also see that the BSS section ends at 0x08049a80 + 0x28 = 0x08049aa8 and we can write ‘sh’ string we need there (this memory page has write permission).

Let’s dump some stack values:

and we get:

(we could dump a lot more, but 2 values were enough in this case). After checking locally with disabled ASLR we can find, that this stack address points to 0x90 below our return address.

Now we have everything we need to write the exploit:

Note that we added 2 bytes of padding to align addresses in our buffer to 4 bytes.

Running above script gives us:

It’s working! Now we change ls to cat flag and enjoy our victory:

 

Tagged with:

Leave a Reply