diff options
Diffstat (limited to 'epan/dissectors/packet-ntlmssp.c')
-rw-r--r-- | epan/dissectors/packet-ntlmssp.c | 326 |
1 files changed, 144 insertions, 182 deletions
diff --git a/epan/dissectors/packet-ntlmssp.c b/epan/dissectors/packet-ntlmssp.c index dcf9a3daab..3749e0d9ce 100644 --- a/epan/dissectors/packet-ntlmssp.c +++ b/epan/dissectors/packet-ntlmssp.c @@ -39,9 +39,7 @@ #include <epan/show_exception.h> #include <epan/proto_data.h> -#include <wsutil/rc4.h> -#include <wsutil/md4.h> -#include <wsutil/md5.h> +#include <wsutil/wsgcrypt.h> #include <wsutil/des.h> #include <wsutil/crc32.h> #include <wsutil/str_util.h> @@ -289,8 +287,8 @@ typedef struct _ntlmssp_blob { typedef struct _ntlmssp_info { guint32 flags; int is_auth_ntlm_v2; - rc4_state_struct rc4_state_client; - rc4_state_struct rc4_state_server; + gcry_cipher_hd_t rc4_handle_client; + gcry_cipher_hd_t rc4_handle_server; guint8 sign_key_client[NTLMSSP_KEY_LEN]; guint8 sign_key_server[NTLMSSP_KEY_LEN]; guint32 server_dest_port; @@ -360,6 +358,16 @@ LEBE_Convert(int value) } #endif +static gboolean +ntlmssp_sessions_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_) +{ + ntlmssp_info * conv_ntlmssp_info = (ntlmssp_info *) user_data; + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); + /* unregister this callback */ + return FALSE; +} + /* Perform a DES encryption with a 16-byte key and 8-byte data item. It's in fact 3 susbsequent call to crypt_des_ecb with a 7-byte key. @@ -498,7 +506,7 @@ get_md4pass_list(md4_pass** p_pass_list, const char* nt_password) nb_pass++; password_len = (int)strlen(nt_password); str_to_unicode(nt_password, nt_password_unicode); - crypt_md4(nt_password_hash, nt_password_unicode, password_len*2); + gcry_md_hash_buffer(GCRY_MD_MD4, nt_password_hash, nt_password_unicode, password_len*2); } if (nb_pass == 0) { /* Unable to calculate the session key without a password or if password is more than 128 char ......*/ @@ -545,7 +553,7 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge guint8 lm_challenge_response[24]; guint32 i; guint32 j; - rc4_state_struct rc4state; + gcry_cipher_hd_t rc4_handle; size_t user_len; size_t domain_len; md4_pass *pass_list = NULL; @@ -594,14 +602,18 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge memset(buf, 0, BUF_SIZE); memcpy(buf, user_uppercase, user_len*2); memcpy(buf+user_len*2, domain_name_unicode, domain_len*2); - md5_hmac(buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN, ntowf); + if (ws_hmac_buffer(GCRY_MD_MD5, ntowf, buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN)) { + return; + } printnbyte(ntowf, NTLMSSP_KEY_LEN, "NTOWF: ", "\n"); /* LM response */ memset(buf, 0, BUF_SIZE); memcpy(buf, serverchallenge, 8); memcpy(buf+8, clientchallenge, 8); - md5_hmac(buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, lm_challenge_response); + if (ws_hmac_buffer(GCRY_MD_MD5, lm_challenge_response, buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN)) { + return; + } memcpy(lm_challenge_response+NTLMSSP_KEY_LEN, clientchallenge, 8); printnbyte(lm_challenge_response, 24, "LM Response: ", "\n"); @@ -609,7 +621,9 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge memset(buf, 0, BUF_SIZE); memcpy(buf, serverchallenge, 8); memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, MIN(BUF_SIZE - 8, ntlm_response->length-NTLMSSP_KEY_LEN)); - md5_hmac(buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN, nt_proof); + if (ws_hmac_buffer(GCRY_MD_MD5, nt_proof, buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN)) { + return; + } printnbyte(nt_proof, NTLMSSP_KEY_LEN, "NT proof: ", "\n"); if (!memcmp(nt_proof, ntlm_response->contents, NTLMSSP_KEY_LEN)) { found = TRUE; @@ -620,14 +634,21 @@ create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge return; } - md5_hmac(nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, sessionbasekey); + if (ws_hmac_buffer(GCRY_MD_MD5, sessionbasekey, nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN)) { + return; + } + get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags); /* now decrypt session key if needed and setup sessionkey for decrypting further communications */ if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN); - crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN); - crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN); + if (!gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (!gcry_cipher_setkey(rc4_handle, keyexchangekey, NTLMSSP_KEY_LEN)) { + gcry_cipher_decrypt(rc4_handle, sessionkey, NTLMSSP_KEY_LEN, NULL, 0); + } + gcry_cipher_close(rc4_handle); + } } else { @@ -651,7 +672,6 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co unsigned char lm_password_upper[NTLMSSP_KEY_LEN]; unsigned char lm_password_hash[NTLMSSP_KEY_LEN]; unsigned char nt_password_hash[NTLMSSP_KEY_LEN]; - unsigned char challenges_hash[NTLMSSP_KEY_LEN]; unsigned char challenges_hash_first8[8]; unsigned char challenges[NTLMSSP_KEY_LEN]; guint8 md4[NTLMSSP_KEY_LEN]; @@ -660,8 +680,8 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co guint8 keyexchangekey[NTLMSSP_KEY_LEN]; guint8 lm_challenge_response[24]; guint8 nt_challenge_response[24]; - rc4_state_struct rc4state; - md5_state_t md5state; + gcry_cipher_hd_t rc4_handle; + gcry_md_hd_t md5_handle; char nt_password_unicode[256]; size_t password_len; unsigned int i; @@ -679,7 +699,7 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co password_len = strlen(nt_password); /*Do not forget to free nt_password_nt*/ str_to_unicode(nt_password, nt_password_unicode); - crypt_md4(nt_password_hash, nt_password_unicode, password_len*2); + gcry_md_hash_buffer(GCRY_MD_MD4, nt_password_hash, nt_password_unicode, password_len*2); /* Truncate password if too long */ if (password_len > NTLMSSP_KEY_LEN) password_len = NTLMSSP_KEY_LEN; @@ -717,11 +737,13 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co if(clientchallenge){ memcpy(lm_challenge_response, clientchallenge, 8); } - md5_init(&md5state); - md5_append(&md5state, serverchallenge, 8); - md5_append(&md5state, clientchallenge, 8); - md5_finish(&md5state, challenges_hash); - memcpy(challenges_hash_first8, challenges_hash, 8); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + break; + } + gcry_md_write(md5_handle, serverchallenge, 8); + gcry_md_write(md5_handle, clientchallenge, 8); + memcpy(challenges_hash_first8, gcry_md_read(md5_handle, 0), 8); + gcry_md_close(md5_handle); crypt_des_ecb_long(nt_challenge_response, nt_password_hash, challenges_hash_first8); if (ref_nt_challenge_response && !memcmp(ref_nt_challenge_response, nt_challenge_response, 24)) { found = TRUE; @@ -748,14 +770,15 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth * Otherwise it should be lm_password_hash ...*/ - crypt_md4(md4, nt_password_hash, NTLMSSP_KEY_LEN); + gcry_md_hash_buffer(GCRY_MD_MD4, md4, nt_password_hash, NTLMSSP_KEY_LEN); if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) { memcpy(challenges, serverchallenge, 8); if(clientchallenge){ memcpy(challenges+8, clientchallenge, 8); } - /*md5_hmac(text, text_len, key, key_len, digest);*/ - md5_hmac(challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN, sessionbasekey); + if (ws_hmac_buffer(GCRY_MD_MD5, sessionbasekey, challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN)) { + return; + } } else { memcpy(sessionbasekey, md4, NTLMSSP_KEY_LEN); @@ -776,8 +799,12 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co if(encryptedsessionkey){ memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN); } - crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN); - crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN); + if (!gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (!gcry_cipher_setkey(rc4_handle, keyexchangekey, NTLMSSP_KEY_LEN)) { + gcry_cipher_decrypt(rc4_handle, sessionkey, NTLMSSP_KEY_LEN, NULL, 0); + } + gcry_cipher_close(rc4_handle); + } } else { @@ -789,20 +816,21 @@ create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, co static void get_siging_key(guint8 *sign_key_server, guint8* sign_key_client, const guint8 key[NTLMSSP_KEY_LEN], int keylen) { - md5_state_t md5state; - md5_state_t md5state2; + gcry_md_hd_t md5_handle; memset(sign_key_client, 0, NTLMSSP_KEY_LEN); memset(sign_key_server, 0, NTLMSSP_KEY_LEN); - md5_init(&md5state); - md5_append(&md5state, key, keylen); - md5_append(&md5state, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1); - md5_finish(&md5state, sign_key_client); - md5_init(&md5state2); - md5_append(&md5state2, key, keylen); - md5_append(&md5state2, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1); - md5_finish(&md5state2, sign_key_server); - + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, key, keylen); + gcry_md_write(md5_handle, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1); + memcpy(sign_key_client, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_reset(md5_handle); + gcry_md_write(md5_handle, key, keylen); + gcry_md_write(md5_handle, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1); + memcpy(sign_key_server, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_close(md5_handle); } /* We return either a 128 or 64 bit key @@ -811,8 +839,7 @@ static void get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int flags , int *keylen , guint8 *clientsealkey , guint8 *serversealkey) { - md5_state_t md5state; - md5_state_t md5state2; + gcry_md_hd_t md5_handle; memset(clientsealkey, 0, NTLMSSP_KEY_LEN); memset(serversealkey, 0, NTLMSSP_KEY_LEN); @@ -838,14 +865,17 @@ get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int } } memcpy(serversealkey, clientsealkey, NTLMSSP_KEY_LEN); - md5_init(&md5state); - md5_append(&md5state, clientsealkey,*keylen); - md5_append(&md5state, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1); - md5_finish(&md5state, clientsealkey); - md5_init(&md5state2); - md5_append(&md5state2, serversealkey,*keylen); - md5_append(&md5state2, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1); - md5_finish(&md5state2, serversealkey); + if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { + return; + } + gcry_md_write(md5_handle, clientsealkey, *keylen); + gcry_md_write(md5_handle, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1); + memcpy(clientsealkey, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_reset(md5_handle); + gcry_md_write(md5_handle, serversealkey, *keylen); + gcry_md_write(md5_handle, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1); + memcpy(serversealkey, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); + gcry_md_close(md5_handle); } else { @@ -1485,6 +1515,7 @@ dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset, */ if (!conv_ntlmssp_info || memcmp(tmp, conv_ntlmssp_info->server_challenge, 8) != 0) { conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info); + wmem_register_callback(wmem_file_scope(), ntlmssp_sessions_destroy_cb, conv_ntlmssp_info); /* Insert the flags into the conversation */ conv_ntlmssp_info->flags = negotiate_flags; /* Insert the RC4 state information into the conversation */ @@ -1506,12 +1537,23 @@ dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset, create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge, NULL, sspkey, NULL, conv_ntlmssp_info->flags, conv_ntlmssp_info->ntlm_response.contents, conv_ntlmssp_info->lm_response.contents, ntlmssph); if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len); - conv_ntlmssp_info->server_dest_port = pinfo->destport; - conv_ntlmssp_info->rc4_state_initialized = 1; + if (!gcry_cipher_open(&conv_ntlmssp_info->rc4_handle_client, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_client, sspkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); + conv_ntlmssp_info->rc4_handle_client = NULL; + } + } + if (!gcry_cipher_open(&conv_ntlmssp_info->rc4_handle_server, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_server, sspkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); + conv_ntlmssp_info->rc4_handle_server = NULL; + } + } + if (conv_ntlmssp_info->rc4_handle_client && conv_ntlmssp_info->rc4_handle_server) { + conv_ntlmssp_info->server_dest_port = pinfo->destport; + conv_ntlmssp_info->rc4_state_initialized = 1; + } } - } conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info); } @@ -1623,6 +1665,7 @@ dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset, conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, proto_ntlmssp); if (conv_ntlmssp_info == NULL) { conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info); + wmem_register_callback(wmem_file_scope(), ntlmssp_sessions_destroy_cb, conv_ntlmssp_info); conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info); } /* XXX: The *conv_ntlmssp_info struct attached to the frame is the @@ -1806,10 +1849,22 @@ dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset, if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey); get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server, (guint8*)&conv_ntlmssp_info->sign_key_client, sspkey, ssp_key_len); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len); - crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len); - conv_ntlmssp_info->server_dest_port = pinfo->destport; - conv_ntlmssp_info->rc4_state_initialized = 1; + if (!gcry_cipher_open (&conv_ntlmssp_info->rc4_handle_server, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_server, serverkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); + conv_ntlmssp_info->rc4_handle_server = NULL; + } + } + if (!gcry_cipher_open (&conv_ntlmssp_info->rc4_handle_client, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { + if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_client, clientkey, ssp_key_len)) { + gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); + conv_ntlmssp_info->rc4_handle_client = NULL; + } + } + if (conv_ntlmssp_info->rc4_handle_server && conv_ntlmssp_info->rc4_handle_client) { + conv_ntlmssp_info->server_dest_port = pinfo->destport; + conv_ntlmssp_info->rc4_state_initialized = 1; + } } } } @@ -1857,7 +1912,7 @@ get_sign_key(packet_info *pinfo, int cryptpeer) * Get the encryption state tied to this conversation. cryptpeer indicates * whether to retrieve the client key (1) or the server key (0) */ -static rc4_state_struct * +static gcry_cipher_hd_t get_encrypted_state(packet_info *pinfo, int cryptpeer) { conversation_t *conversation; @@ -1885,9 +1940,9 @@ get_encrypted_state(packet_info *pinfo, int cryptpeer) crypt state tied to the requested peer */ if (cryptpeer == 1) { - return &conv_ntlmssp_info->rc4_state_client; + return conv_ntlmssp_info->rc4_handle_client; } else { - return &conv_ntlmssp_info->rc4_state_server; + return conv_ntlmssp_info->rc4_handle_server; } } } @@ -1900,15 +1955,6 @@ static void decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, packet_info *pinfo, proto_tree *tree, gpointer key); -#if 0 -static tvbuff_t * -dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb, - tvbuff_t *auth_tvb _U_, - int offset, - packet_info *pinfo, - dcerpc_auth_info *auth_info _U_) -#endif - static int dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { @@ -2027,23 +2073,23 @@ decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "Data: ", "\n");*/ } else { - rc4_state_struct *rc4_state; - rc4_state_struct *rc4_state_peer; + gcry_cipher_hd_t rc4_handle; + gcry_cipher_hd_t rc4_handle_peer; /* Get the pair of RC4 state structures. One is used for to decrypt the payload. The other is used to re-encrypt the payload to represent the peer */ if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { /* client */ - rc4_state = get_encrypted_state(pinfo, 1); - rc4_state_peer = get_encrypted_state(pinfo, 0); + rc4_handle = get_encrypted_state(pinfo, 1); + rc4_handle_peer = get_encrypted_state(pinfo, 0); } else { /* server */ - rc4_state = get_encrypted_state(pinfo, 0); - rc4_state_peer = get_encrypted_state(pinfo, 1); + rc4_handle = get_encrypted_state(pinfo, 0); + rc4_handle_peer = get_encrypted_state(pinfo, 1); } - if (rc4_state == NULL) { + if (rc4_handle == NULL) { /* There is no encryption state, so we cannot decrypt */ return NULL; } @@ -2060,8 +2106,8 @@ decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, } /* Do the decryption of the payload */ - crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, - encrypted_block_length); + gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->decrypted_payload, encrypted_block_length, NULL, 0); + /* decrypt the verifier */ /*printnchar(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "data: ", "\n");*/ /* We setup a temporary buffer so we can re-encrypt the payload after @@ -2071,7 +2117,7 @@ decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) { guint8 *peer_block; peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length); - crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length); + gcry_cipher_decrypt(rc4_handle_peer, peer_block, encrypted_block_length, NULL, 0); } packet_ntlmssp_info->payload_decrypted = TRUE; @@ -2190,8 +2236,8 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, proto_tree *decr_tree; conversation_t *conversation; guint8* sign_key; - rc4_state_struct *rc4_state; - rc4_state_struct *rc4_state_peer; + gcry_cipher_hd_t rc4_handle; + gcry_cipher_hd_t rc4_handle_peer; tvbuff_t *decr_tvb; /* Used to display decrypted buffer */ guint8 *peer_block; guint8 *check_buf; @@ -2239,16 +2285,16 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, } if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { /* client talk to server */ - rc4_state = get_encrypted_state(pinfo, 1); + rc4_handle = get_encrypted_state(pinfo, 1); sign_key = get_sign_key(pinfo, 1); - rc4_state_peer = get_encrypted_state(pinfo, 0); + rc4_handle_peer = get_encrypted_state(pinfo, 0); } else { - rc4_state = get_encrypted_state(pinfo, 0); + rc4_handle = get_encrypted_state(pinfo, 0); sign_key = get_sign_key(pinfo, 0); - rc4_state_peer = get_encrypted_state(pinfo, 1); + rc4_handle_peer = get_encrypted_state(pinfo, 1); } - if (rc4_state == NULL || rc4_state_peer == NULL) { + if (rc4_handle == NULL || rc4_handle_peer == NULL) { /* There is no encryption state, so we cannot decrypt */ return; } @@ -2263,7 +2309,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, /* The spec says that if we have have a key exchange then we have a the signature that is crypted * otherwise it's just a hmac_md5(keysign, concat(message, sequence))[0..7] */ - crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, 8); + if (gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->verifier, 8, NULL, 0)) { + return; + } } /* * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but @@ -2275,7 +2323,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, tvb_memcpy(tvb, &sequence, offset+8, 4); memcpy(check_buf, &sequence, 4); memcpy(check_buf+4, packet_ntlmssp_info->decrypted_payload, packet_ntlmssp_info->payload_len); - md5_hmac(check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN, calculated_md5); + if (ws_hmac_buffer(GCRY_MD_MD5, calculated_md5, check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN)) { + return; + } /* printnbyte(packet_ntlmssp_info->verifier, 8, "HMAC from packet: ", "\n"); printnbyte(calculated_md5, 8, "HMAC : ", "\n"); @@ -2285,8 +2335,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, else { /* The packet has a PAD then a checksum then a sequence and they are encoded in this order so we can decrypt all at once */ /* Do the actual decryption of the verifier */ - crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, - encrypted_block_length); + if (gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->verifier, encrypted_block_length, NULL, 0)) { + return; + } } @@ -2297,7 +2348,9 @@ decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, and it's also not needed when we have key exchange because server and client have independent keys */ if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) { peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->verifier, encrypted_block_length); - crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length); + if (gcry_cipher_decrypt(rc4_handle_peer, peer_block, encrypted_block_length, NULL, 0)) { + return; + } } /* Mark the packet as decrypted so that subsequent attempts to dissect @@ -2481,97 +2534,6 @@ wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb, tvbuff_t *auth_tvb _U_, return decrypted_tvb; } -#if 0 -static tvbuff_t * -dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb, - tvbuff_t *auth_tvb _U_, - int offset, - packet_info *pinfo, - dcerpc_auth_info *auth_info _U_) -{ - /* gssapi_decrypted_tvb = NULL */ - tvbuff_t *decr_tvb; /* Used to display decrypted buffer */ - guint8 *peer_block; - conversation_t *conversation; - guint32 encrypted_block_length; - rc4_state_struct *rc4_state; - rc4_state_struct *rc4_state_peer; - ntlmssp_info *conv_ntlmssp_info = NULL; - ntlmssp_packet_info *packet_ntlmssp_info; - - encrypted_block_length = tvb_length_remaining (data_tvb, offset); - - fprintf(stderr, "Called dissect_ntlmssp_encrypted_payload\n"); - /* Check to see if we already have state for this packet */ - packet_ntlmssp_info = p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY); - if (packet_ntlmssp_info == NULL) { - /* We don't have any packet state, so create one */ - packet_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_packet_info); - p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY, packet_ntlmssp_info); - } - - if (!packet_ntlmssp_info->payload_decrypted) { - /* Pull the challenge info from the conversation */ - conversation = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, - pinfo->ptype, pinfo->srcport, - pinfo->destport, 0); - if (conversation == NULL) { - /* There is no conversation, thus no encryption state */ - return NULL; - - } - conv_ntlmssp_info = conversation_get_proto_data(conversation, - proto_ntlmssp); - if (conv_ntlmssp_info == NULL) { - /* There is no NTLMSSP state tied to the conversation */ - return NULL; - } - /* Get the pair of RC4 state structures. One is used for to decrypt the - payload. The other is used to re-encrypt the payload to represent - the peer */ - if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { - rc4_state = get_encrypted_state(pinfo, 1); - rc4_state_peer = get_encrypted_state(pinfo, 0); - } else { - rc4_state = get_encrypted_state(pinfo, 0); - rc4_state_peer = get_encrypted_state(pinfo, 1); - } - - if (rc4_state == NULL || rc4_state_peer == NULL) { - /* There is no encryption state, so we cannot decrypt */ - return NULL; - } - - /* Store the decrypted contents in the packet state struct - (of course at this point, they aren't decrypted yet) */ - packet_ntlmssp_info->decrypted_payload = tvb_memdup(wmem_file_scope(), data_tvb, offset, - encrypted_block_length); - decrypted_payloads = g_slist_prepend(decrypted_payloads, - packet_ntlmssp_info->decrypted_payload); - - /* Do the decryption of the payload */ - crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload, - encrypted_block_length); - - /* We setup a temporary buffer so we can re-encrypt the payload after - decryption. This is to update the opposite peer's RC4 state */ - peer_block = wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length); - crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length); - - packet_ntlmssp_info->payload_decrypted = TRUE; - } - - /* Show the decrypted buffer in a new window */ - decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload, - encrypted_block_length, - encrypted_block_length); - - offset += encrypted_block_length; - - return decr_tvb; -} -#endif - static guint header_hash(gconstpointer pointer) { |