def GSS_Unwrap(self, sessionKey, data, sequenceNumber, direction = 'init', encrypt=True, authData=None): from impacket.dcerpc.v5.rpcrt import SEC_TRAILER cipher = self.cipherType() token = self.WRAP(authData[len(SEC_TRAILER()):]) rotated = authData[len(self.WRAP())+len(SEC_TRAILER()):] + data cipherText = self.unrotate(rotated, token['RRC'] + token['EC']) plainText = cipher.decrypt(sessionKey, KG_USAGE_ACCEPTOR_SEAL, cipherText) return plainText[:-(token['EC']+len(self.WRAP()))], None
def sendBindType1(self, iface_uuid, auth_data): bind = MSRPCBind() item = CtxItem() item['AbstractSyntax'] = iface_uuid item['TransferSyntax'] = self.transfer_syntax item['ContextID'] = 0 item['TransItems'] = 1 bind.addCtxItem(item) packet = MSRPCHeader() packet['type'] = rpcrt.MSRPC_BIND packet['pduData'] = bind.getData() packet['call_id'] = 0 sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT sec_trailer['auth_ctx_id'] = 79231 pad = (4 - (len(packet.get_packet()) % 4)) % 4 if pad != 0: packet['pduData'] += b'\xFF' * pad sec_trailer['auth_pad_len'] = pad packet['sec_trailer'] = sec_trailer packet['auth_data'] = auth_data self._transport.send(packet.get_packet()) s = self._transport.recv() if s != 0: resp = MSRPCHeader(s) else: return 0 #mmm why not None? if resp['type'] == rpcrt.MSRPC_BINDACK or resp['type'] == rpcrt.MSRPC_ALTERCTX_R: bindResp = MSRPCBindAck(resp.getData()) elif resp['type'] == rpcrt.MSRPC_BINDNAK or resp['type'] == rpcrt.MSRPC_FAULT: if resp['type'] == rpcrt.MSRPC_FAULT: resp = MSRPCRespHeader(resp.getData()) status_code = unpack('<L', resp['pduData'][:4])[0] else: resp = MSRPCBindNak(resp['pduData']) status_code = resp['RejectedReason'] if status_code in rpc_status_codes: raise DCERPCException(error_code = status_code) elif status_code in rpc_provider_reason: raise DCERPCException("Bind context rejected: %s" % rpc_provider_reason[status_code]) else: raise DCERPCException('Unknown DCE RPC fault status code: %.8x' % status_code) else: raise DCERPCException('Unknown DCE RPC packet type received: %d' % resp['type']) self.set_max_tfrag(bindResp['max_rfrag']) return bindResp
def sendBindType3(self, auth_data): sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_PKT_PRIVACY sec_trailer['auth_ctx_id'] = 79231 auth3 = MSRPCHeader() auth3['type'] = rpcrt.MSRPC_AUTH3 # pad (4 bytes): Can be set to any arbitrary value when set and MUST be # ignored on receipt. The pad field MUST be immediately followed by a # sec_trailer structure whose layout, location, and alignment are as # specified in section 2.2.2.11 auth3['pduData'] = b' ' auth3['sec_trailer'] = sec_trailer auth3['auth_data'] = auth_data auth3['call_id'] = 0 self._transport.send(auth3.get_packet(), forceWriteAndx=1)
def bind_ntlm_authinfo(dcerpc, iface_uuid): # Build MSRPCBind information bind = MSRPCBind() item = CtxItem() item['AbstractSyntax'] = iface_uuid item['TransferSyntax'] = uuidtup_to_bin( ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0')) item['ContextID'] = 0 item['TransItems'] = 1 bind.addCtxItem(item) # Build NTLM Authentication Negociate auth = ntlm.NTLMAuthNegotiate() auth['flags'] = ntlm.NTLMSSP_NEGOTIATE_UNICODE # Build Security Trailer sec_trailer = SEC_TRAILER() sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT sec_trailer['auth_ctx_id'] = 0xb0b0d0ba # Build MSRPC Header packet = MSRPCHeader() packet['type'] = MSRPC_BIND packet['call_id'] = 1 packet['flags'] = 0x03 packet['pduData'] = str(bind) packet['sec_trailer'] = sec_trailer packet['auth_data'] = str(auth) # Send MSRPC request dcerpc._transport.send(packet.get_packet()) # Receive MSRPC response s = dcerpc._transport.recv() if s == 0: print "Failed to retrieve a Bind response!" return 0 resp = MSRPCHeader(s) return resp
def GSS_Wrap(self, sessionKey, data, sequenceNumber, direction='init', encrypt=True, authData=None): # Damn inacurate RFC, useful info from here # https://social.msdn.microsoft.com/Forums/en-US/fb98e8f4-e697-4652-bcb7-604e027e14cc/gsswrap-token-size-kerberos-and-rc4hmac?forum=os_windowsprotocols # and here # http://www.rfc-editor.org/errata_search.php?rfc=4757 GSS_WRAP_HEADER = '\x60\x2b\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02' token = self.WRAP() # Let's pad the data pad = (8 - (len(data) % 8)) & 0x7 padStr = chr(pad) * pad data = data + padStr token['SGN_ALG'] = GSS_HMAC token['SEAL_ALG'] = GSS_RC4 if direction == 'init': token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\x00' * 4 else: token['SND_SEQ'] = struct.pack('>L', sequenceNumber) + '\xff' * 4 # Random confounder :) token['Confounder'] = '12345678' Ksign = HMAC.new(sessionKey.contents, 'signaturekey\0', MD5).digest() Sgn_Cksum = MD5.new( struct.pack('<L', 13) + str(token)[:8] + token['Confounder'] + data).digest() Klocal = '' for n in sessionKey.contents: Klocal += chr(ord(n) ^ 0xF0) Kcrypt = HMAC.new(Klocal, struct.pack('<L', 0), MD5).digest() Kcrypt = HMAC.new(Kcrypt, struct.pack('>L', sequenceNumber), MD5).digest() Sgn_Cksum = HMAC.new(Ksign, Sgn_Cksum, MD5).digest() token['SGN_CKSUM'] = Sgn_Cksum[:8] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L', 0), MD5).digest() Kseq = HMAC.new(Kseq, token['SGN_CKSUM'], MD5).digest() token['SND_SEQ'] = ARC4.new(Kseq).encrypt(token['SND_SEQ']) if authData is not None: from impacket.dcerpc.v5.rpcrt import SEC_TRAILER wrap = self.WRAP(authData[len(SEC_TRAILER()) + len(GSS_WRAP_HEADER):]) snd_seq = wrap['SND_SEQ'] Kseq = HMAC.new(sessionKey.contents, struct.pack('<L', 0), MD5).digest() Kseq = HMAC.new(Kseq, wrap['SGN_CKSUM'], MD5).digest() snd_seq = ARC4.new(Kseq).encrypt(wrap['SND_SEQ']) Kcrypt = HMAC.new(Klocal, struct.pack('<L', 0), MD5).digest() Kcrypt = HMAC.new(Kcrypt, snd_seq[:4], MD5).digest() rc4 = ARC4.new(Kcrypt) cipherText = rc4.decrypt(token['Confounder'] + data)[8:] elif encrypt is True: rc4 = ARC4.new(Kcrypt) token['Confounder'] = rc4.encrypt(token['Confounder']) cipherText = rc4.encrypt(data) else: cipherText = data finalData = GSS_WRAP_HEADER + token.getData() return cipherText, finalData