Sheep Shellcode

The hackery blog of Vincent Moscatello.

Login + ? = Profit

Simple login is a 50 point 32bit pwnable from pwnable.kr! Although finding the vulnerability in this challenge was pretty simple, the actual exploitation was a bit trickier than your standard buffer overflow. This write-up contains spoilers so if that’s important to you, try out the challenge for yourself first!

The point of this challenge is to try and bypass the “Authenticate” prompt above. When running the executable normally the program appears to take whatever string you entered, perform some operation on it, then hash that value and print the hash below.

Doing some further reverse engineering reveals that this “operation” before hashing is simply a base64 decoding of whatever string you entered.

Further reverse engineering also revealed that the program has a function called auth (0x08049402 above). When called the auth function compares the hashed value of your base64 decoded string to a hash compiled right into the executable. An obvious first approach would be to try and brute the hash but unfortunately the password for the hash was not easily guessable.

It’s time to get a bit more creative, upon further analysis of the auth function it becomes clear that it may be possible to cause a 4 byte overflow using the memcpy function. You can figure this out by looking at addresses 0x080492B1, 0x080492B4, and 0x080492A2. Starting at address 0x080492B1, the address of the base pointer minus 20 is loaded into eax. At 0x080492B4 12 bytes are then added to eax. This makes 20 – 12 = 8 bytes of space for the memcpy function to write into. At 0x080492A2, arg_0 contains the length of our string after it’s been base64 decoded. This string length can be up to 12 bytes large! We can copy 12 bytes into an 8 byte buffer, BUFFER OVERFLOW!

But wait… A FOUR byte buffer overflow and not an EIGHT byte buffer overflow? All we can do with that is control ebp not the instructional pointer (eip)! To figure out a solution I relied on an obscure phrack article I read about a year ago http://phrack.org/issues/55/8.html . In the article klog describes how he is able to get code execution by exploiting a 1 byte overflow into ebp. Although his method doesn’t really work here with modern OS protections like DEP/ASLR enabled, we can still adapt his method to solve our problem.

The diagram I have drawn above does a good job at explaining how the attack works. In summation, we are using the fact that we control ebp after two function returns to get code execution. The trickiest part was figuring out the address to overwrite the base pointer with since most things were moving.

Fortunately, our string is copied into the bss segment before making a call to auth. There is enough room here to allow us to store a fake ebp (just some padding) and an address we want to jump to.

BUT wait! The bss segment is unfortunately not executable so we can’t simply put some shellcode in it. In fact, there wouldn’t really be enough room to store the shellcode to begin with. The solution is to jump back into the text segment at the address in the picture above so we can all system. Excellent! We now know everything we need to in order to write an exploit in python.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python

import struct
import base64

#Call to system from the textsegment
system = struct.pack("<L",0x08049284)

#This address is found in the data segment so it shouldn't relocate
#even if aslr is enabled
corrupted_ebp = struct.pack("<L",0x0811EB40)

#4 As are added as padding
exploit =  "A"*4 + system + corrupted_ebp

base_64 = base64.b64encode(exploit)
print(base_64)

And finally, let’s claim the spoils of victory by feeding our exploit through ncat.