コード例 #1
0
ファイル: dcerpc.py プロジェクト: vpereira/packetpig
    def _transport_send(self, rpc_packet, forceWriteAndx=0, forceRecv=0):

        rpc_packet['ctx_id'] = self._ctx
        if self.__auth_level in [
                ntlm.NTLM_AUTH_PKT_INTEGRITY, ntlm.NTLM_AUTH_PKT_PRIVACY
        ]:
            # Dummy verifier, just for the calculations
            verifier = ntlm.DCERPC_NTLMAuthVerifier()
            verifier['auth_pad_len'] = 0

            pad = (8 - (len(rpc_packet.get_packet()) % 8)) % 8
            if pad != 0:
                rpc_packet['pduData'] = rpc_packet['pduData'] + '\x00' * pad
                verifier['auth_pad_len'] = pad

            verifier['auth_level'] = self.__auth_level
            verifier['auth_ctx_id'] = self._ctx + 79231
            verifier['data'] = ' ' * 12
            rpc_packet['auth_data'] = str(verifier)

            plain_data = rpc_packet['pduData']
            if self.__auth_level == ntlm.NTLM_AUTH_PKT_PRIVACY:
                if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                    # When NTLM2 is on, we sign the whole pdu, but encrypt just
                    # the data, not the dcerpc header. Weird..
                    sealedMessage, signature = ntlm.SEAL(
                        self.__flags,
                        self.__clientSigningKey,
                        self.__clientSealingKey,
                        rpc_packet.get_packet()[:-16],
                        plain_data,
                        self.__sequence,
                        self.__clientSealingHandle,
                        isDCE=True)
                else:
                    sealedMessage, signature = ntlm.SEAL(
                        self.__flags,
                        self.__clientSigningKey,
                        self.__clientSealingKey,
                        plain_data,
                        plain_data,
                        self.__sequence,
                        self.__clientSealingHandle,
                        isDCE=True)
                rpc_packet['pduData'] = sealedMessage
            else:
                if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                    # Interesting thing.. with NTLM2, what is is signed is the
                    # whole PDU, not just the data
                    signature = ntlm.SIGN(self.__flags,
                                          self.__clientSigningKey,
                                          rpc_packet.get_packet()[:-16],
                                          self.__sequence,
                                          self.__clientSealingHandle,
                                          isDCE=True)
                else:
                    signature = ntlm.SIGN(self.__flags,
                                          self.__clientSigningKey,
                                          plain_data,
                                          self.__sequence,
                                          self.__clientSealingHandle,
                                          isDCE=True)

            signature['auth_level'] = self.__auth_level
            signature['auth_ctx_id'] = verifier['auth_ctx_id']
            signature['auth_pad_len'] = pad
            rpc_packet['auth_data'] = str(signature)

            self.__sequence += 1

        self._transport.send(rpc_packet.get_packet(),
                             forceWriteAndx=forceWriteAndx,
                             forceRecv=forceRecv)
コード例 #2
0
ファイル: dcerpc.py プロジェクト: vpereira/packetpig
    def recv(self):
        finished = False
        forceRecv = 0
        retAnswer = ''
        while not finished:
            # At least give me the MSRPCRespHeader, especially important for TCP/UDP Transports
            self.response_data = self._transport.recv(
                forceRecv, count=MSRPCRespHeader._SIZE)
            self.response_header = MSRPCRespHeader(self.response_data)
            # Ok, there might be situation, especially with large packets, that the transport layer didn't send us the full packet's contents
            # So we gotta check we received it all
            while (len(self.response_data) < self.response_header['frag_len']):
                self.response_data += self._transport.recv(
                    forceRecv,
                    count=(self.response_header['frag_len'] -
                           len(self.response_data)))
            off = self.response_header.get_header_size()
            if self.response_header[
                    'type'] == MSRPC_FAULT and self.response_header[
                        'frag_len'] >= off + 4:
                status_code = unpack("<L", self.response_data[off:off + 4])[0]
                if rpc_status_codes.has_key(status_code):
                    raise Exception(rpc_status_codes[status_code])
                else:
                    raise Exception('Unknown DCE RPC fault status code: %.8x' %
                                    status_code)
            if self.response_header['flags'] & MSRPC_LASTFRAG:
                # No need to reassembly DCERPC
                finished = True
            else:
                # Forcing Read Recv, we need more packets!
                forceRecv = 1
            answer = self.response_data[off:]
            auth_len = self.response_header['auth_len']
            if auth_len:
                auth_len += 8
                auth_data = answer[-auth_len:]
                ntlmssp = ntlm.DCERPC_NTLMAuthHeader(data=auth_data)
                answer = answer[:-auth_len]

                if ntlmssp['auth_level'] == ntlm.NTLM_AUTH_PKT_PRIVACY:

                    if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                        # TODO: FIX THIS, it's not calculating the signature well
                        # Since I'm not testing it we don't care... yet
                        answer, signature = ntlm.SEAL(
                            self.__flags,
                            self.__serverSigningKey,
                            self.__serverSealingKey,
                            answer,
                            answer,
                            self.__sequence,
                            self.__serverSealingHandle,
                            isDCE=True)
                    else:
                        answer, signature = ntlm.SEAL(
                            self.__flags,
                            self.__serverSigningKey,
                            self.__serverSealingKey,
                            answer,
                            answer,
                            self.__sequence,
                            self.__serverSealingHandle,
                            isDCE=True)
                        self.__sequence += 1
                else:
                    ntlmssp = ntlm.DCERPC_NTLMAuthVerifier(data=auth_data)
                    if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                        signature = ntlm.SIGN(self.__flags,
                                              self.__serverSigningKey,
                                              answer,
                                              self.__sequence,
                                              self.__serverSealingHandle,
                                              isDCE=True)
                    else:
                        signature = ntlm.SIGN(self.__flags,
                                              self.__serverSigningKey,
                                              ntlmssp['data'],
                                              self.__sequence,
                                              self.__serverSealingHandle,
                                              isDCE=True)
                        # Yes.. NTLM2 doesn't increment sequence when receiving
                        # the packet :P
                        self.__sequence += 1

                if ntlmssp['auth_pad_len']:
                    answer = answer[:-ntlmssp['auth_pad_len']]

            retAnswer += answer
        return retAnswer
コード例 #3
0
    def _transport_send(self, rpc_packet, forceWriteAndx = 0, forceRecv = 0):
        rpc_packet['ctx_id'] = self._ctx
        if self.__auth_level in [RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, RPC_C_AUTHN_LEVEL_PKT_PRIVACY]:
            # Dummy verifier, just for the calculations
            sec_trailer = SEC_TRAILER()
            sec_trailer['auth_type'] = self.__auth_type
            sec_trailer['auth_level'] = self.__auth_level
            sec_trailer['auth_pad_len'] = 0
            sec_trailer['auth_ctx_id'] = self._ctx + 79231 

            pad = (4 - (len(rpc_packet.get_packet()) % 4)) % 4
            if pad != 0:
               rpc_packet['pduData'] = rpc_packet['pduData'] + '\xBB'*pad
               sec_trailer['auth_pad_len']=pad

            rpc_packet['sec_trailer'] = str(sec_trailer)
            rpc_packet['auth_data'] = ' '*16

            plain_data = rpc_packet['pduData']
            if self.__auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
                if self.__auth_type == RPC_C_AUTHN_WINNT:
                    if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                        # When NTLM2 is on, we sign the whole pdu, but encrypt just
                        # the data, not the dcerpc header. Weird..
                        sealedMessage, signature =  ntlm.SEAL(self.__flags, 
                               self.__clientSigningKey, 
                               self.__clientSealingKey,  
                               rpc_packet.get_packet()[:-16], 
                               plain_data, 
                               self.__sequence, 
                               self.__clientSealingHandle)
                    else:
                        sealedMessage, signature =  ntlm.SEAL(self.__flags, 
                               self.__clientSigningKey, 
                               self.__clientSealingKey,  
                               plain_data, 
                               plain_data, 
                               self.__sequence, 
                               self.__clientSealingHandle)
                    rpc_packet['pduData'] = sealedMessage
            else: 
                if self.__auth_type == RPC_C_AUTHN_WINNT:
                    if self.__flags & ntlm.NTLMSSP_NTLM2_KEY:
                        # Interesting thing.. with NTLM2, what is is signed is the 
                        # whole PDU, not just the data
                        signature =  ntlm.SIGN(self.__flags, 
                               self.__clientSigningKey, 
                               rpc_packet.get_packet()[:-16], 
                               self.__sequence, 
                               self.__clientSealingHandle)
                    else:
                        signature =  ntlm.SIGN(self.__flags, 
                               self.__clientSigningKey, 
                               plain_data, 
                               self.__sequence, 
                               self.__clientSealingHandle)
                elif self.__auth_type == RPC_C_AUTHN_NETLOGON:
                    from impacket.dcerpc import netlogon
                    signature = netlogon.SIGN(rpc_packet.get_packet()[:-16], self.__sequence, '', self.__sessionKey)

            rpc_packet['sec_trailer'] = str(sec_trailer)
            rpc_packet['auth_data'] = str(signature)

            self.__sequence += 1

        self._transport.send(rpc_packet.get_packet(), forceWriteAndx = forceWriteAndx, forceRecv = forceRecv)