#include <epan/crypt/crypt-des.h>
#include "packet-dcerpc.h"
#include "packet-gssapi.h"
-#include <epan/crc32.h>
+#include <wsutil/crc32.h>
#include "packet-ntlmssp.h"
static void
create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge , const guint8 *clientchallenge ,
guint8 *sessionkey ,const guint8 *encryptedsessionkey , int flags ,
- ntlmssp_blob ntlm_response, ntlmssp_blob lm_response _U_, ntlmssp_header_t *ntlmssph )
+ const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response _U_, ntlmssp_header_t *ntlmssph )
{
char domain_name_unicode[256];
char user_uppercase[256];
/* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
memset(buf,0,512);
memcpy(buf,serverchallenge,8);
- memcpy(buf+8,ntlm_response.contents+NTLMSSP_KEY_LEN,ntlm_response.length-NTLMSSP_KEY_LEN);
- md5_hmac(buf,ntlm_response.length-8,ntowf,NTLMSSP_KEY_LEN,nt_proof);
+ memcpy(buf+8,ntlm_response->contents+NTLMSSP_KEY_LEN,ntlm_response->length-NTLMSSP_KEY_LEN);
+ md5_hmac(buf,ntlm_response->length-8,ntowf,NTLMSSP_KEY_LEN,nt_proof);
printnbyte(nt_proof,NTLMSSP_KEY_LEN,"NT proof: ","\n");
- if( !memcmp(nt_proof,ntlm_response.contents,NTLMSSP_KEY_LEN) ) {
+ if( !memcmp(nt_proof,ntlm_response->contents,NTLMSSP_KEY_LEN) ) {
found = 1;
break;
}
clientsealkey[7]=0xb0;
}
}
- serversealkey = memcpy(serversealkey,clientsealkey,*keylen);
+ memcpy(serversealkey,clientsealkey,*keylen);
}
}
/* Create an NTLMSSP version 1 key.
if (blob_length < MAX_BLOB_SIZE)
{
tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
- if (blob_hf == hf_ntlmssp_auth_lmresponse && !(memcmp(tvb->real_data+blob_offset+8,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",NTLMSSP_KEY_LEN)))
+ if (blob_hf == hf_ntlmssp_auth_lmresponse && !(tvb_memeql(tvb, blob_offset+8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NTLMSSP_KEY_LEN)))
{
proto_tree_add_item (ntlmssp_tree,
hf_ntlmssp_ntlm_client_challenge,
- tvb, blob_offset, 8, FALSE);
+ tvb, blob_offset, 8, ENC_NA);
}
}
}
{
proto_tree_add_item (ntlmssp_tree,
hf_ntlmssp_ntlm_client_challenge,
- tvb, blob_offset+32, 8, FALSE);
+ tvb, blob_offset+32, 8, ENC_NA);
dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
}
if (tree) {
ntlmv2_item = proto_tree_add_item(
tree, hf_ntlmssp_ntlmv2_response, tvb,
- offset, len, TRUE);
+ offset, len, ENC_NA);
ntlmv2_tree = proto_item_add_subtree(
ntlmv2_item, ett_ntlmssp_ntlmv2_response);
}
proto_tree_add_item(
ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
- offset, 16, TRUE);
+ offset, 16, ENC_NA);
offset += 16;
proto_tree_add_item(
ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
- offset, 4, TRUE);
+ offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
proto_tree_add_item(
ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
- offset, 4, TRUE);
+ offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
proto_tree_add_item(
ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
- offset, 8, TRUE);
+ offset, 8, ENC_NA);
offset += 8;
proto_tree_add_item(
ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
- offset, 4, TRUE);
+ offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
data_start = MIN(data_start, item_start);
data_end = MAX(data_end, item_end);
- /* If there are more bytes before the data block dissect a version field */
+ /* If there are more bytes before the data block dissect a version field
+ if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
if (offset < data_start) {
- offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
+ if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
+ offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
}
return data_end;
}
if (ntlmssp_tree) {
tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb,
- challenge_target_info_offset, challenge_target_info_length, FALSE);
+ challenge_target_info_offset, challenge_target_info_length, ENC_NA);
challenge_target_info_tree = proto_item_add_subtree(tf, ett_ntlmssp_challenge_target_info);
}
proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_len,
/* NTLMSSP NT Lan Manager Challenge */
proto_tree_add_item (ntlmssp_tree,
hf_ntlmssp_ntlm_server_challenge,
- tvb, offset, 8, FALSE);
+ tvb, offset, 8, ENC_NA);
/*
* Store the flags and the RC4 state information with the conversation,
* It also says that that information may be omitted.
*/
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
- tvb, offset, 8, FALSE);
+ tvb, offset, 8, ENC_NA);
offset += 8;
/*
data_end = MAX(data_end, item_end);
}
- /* If there are more bytes before the data block dissect a version field */
+ /* If there are more bytes before the data block dissect a version field
+ if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
if (offset < data_start) {
- offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
+ if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
+ offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
}
return MAX(offset, data_end);
data_start = MIN(data_start, item_start);
data_end = MAX(data_end, item_end);
- if (check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s",
- ntlmssph->domain_name, ntlmssph->acct_name);
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "User: %s\\%s",
+ ntlmssph->domain_name, ntlmssph->acct_name);
/* hostname */
item_start = tvb_get_letohl(tvb, offset+4);
if ((conv_ntlmssp_info != NULL) && (conv_ntlmssp_info->flags == 0)) {
conv_ntlmssp_info->flags = negotiate_flags;
}
- }
+ } else
+ negotiate_flags = 0;
- /* If there are more bytes before the data block dissect a version field */
+ /* If there are more bytes before the data block dissect a version field
+ if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
if (offset < data_start) {
- offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
+ if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
+ offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
}
/* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */
{
conv_ntlmssp_info->rc4_state_initialized = 0;
if( conv_ntlmssp_info->is_auth_ntlm_v2 ) {
- create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response,conv_ntlmssp_info->lm_response,ntlmssph);
+ create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,&conv_ntlmssp_info->ntlm_response,&conv_ntlmssp_info->lm_response,ntlmssph);
}
else
{
guint32 ntlm_magic_size = 4;
guint32 ntlm_signature_size = 8;
guint32 ntlm_seq_size = 4;
+ void *pd_save;
+
length = tvb_length (tvb);
/* signature + seq + real payload */
encrypted_block_length = length - ntlm_magic_size;
if (tree) {
tf = proto_tree_add_item (tree,
hf_ntlmssp_verf,
- tvb, offset, -1, FALSE);
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
ett_ntlmssp);
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* Version number */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
/* Encrypted body */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
- tvb, offset, ntlm_signature_size + ntlm_seq_size, TRUE);
+ tvb, offset, ntlm_signature_size + ntlm_seq_size, ENC_NA);
tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
/* Try to decrypt */
decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree,key);
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
proto_tree *volatile ntlmssp_tree = NULL;
proto_item *tf = NULL;
ntlmssp_header_t *ntlmssph;
+ void *pd_save;
ntlmssph=ep_alloc(sizeof(ntlmssp_header_t));
ntlmssph->type=0;
if (tree) {
tf = proto_tree_add_item (tree,
proto_ntlmssp,
- tvb, offset, -1, FALSE);
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
ett_ntlmssp);
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* NTLMSSP constant */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
- tvb, offset, 8, FALSE);
+ tvb, offset, 8, ENC_ASCII|ENC_NA);
offset += 8;
/* NTLMSSP Message Type */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
ntlmssph->type = tvb_get_letohl (tvb, offset);
offset += 4;
- if (check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
- val_to_str(ntlmssph->type,
- ntlmssp_message_types,
- "Unknown message type"));
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ","%s",
+ val_to_str(ntlmssph->type,
+ ntlmssp_message_types,
+ "Unknown message type"));
/* Call the appropriate dissector based on the Message Type */
switch (ntlmssph->type) {
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
/*tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);*/
}
+static gboolean
+dissect_ntlmssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
+{
+
+ if(tvb_memeql(tvb, 0, "NTLMSSP", 8) == 0) {
+
+ dissect_ntlmssp(tvb, pinfo, parent_tree);
+ return TRUE;
+ }
+
+ return FALSE;
+}
/*
if(( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
- decr_tvb, decrypted_offset, 8,TRUE);
+ decr_tvb, decrypted_offset, 8,ENC_NA);
decrypted_offset += 8;
/* Incrementing sequence number of DCE conversation */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_NA);
decrypted_offset += 4;
}
else {
/* RANDOM PAD usually it's 0 */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
decrypted_offset += 4;
/* CRC32 of the DCE fragment data */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
decrypted_offset += 4;
/* Incrementing sequence number of DCE conversation */
proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
- decr_tvb, decrypted_offset, 4, TRUE);
+ decr_tvb, decrypted_offset, 4, ENC_NA);
decrypted_offset += 4;
}
}
volatile int offset = 0;
proto_tree *volatile ntlmssp_tree = NULL;
guint32 encrypted_block_length;
+ void *pd_save;
+
/* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
*/
encrypted_block_length = tvb_length (tvb);
if (tree) {
tf = proto_tree_add_item (tree,
hf_ntlmssp_verf,
- tvb, offset, -1, FALSE);
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
ett_ntlmssp);
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* Version number */
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
proto_item *tf = NULL;
guint32 verifier_length;
guint32 encrypted_block_length;
+ void *pd_save;
verifier_length = tvb_length (tvb);
encrypted_block_length = verifier_length - 4;
if (tree) {
tf = proto_tree_add_item (tree,
hf_ntlmssp_verf,
- tvb, offset, -1, FALSE);
+ tvb, offset, -1, ENC_NA);
ntlmssp_tree = proto_item_add_subtree (tf,
ett_ntlmssp);
* in the packet after our blob to see, so we just re-throw the
* exception.
*/
+ pd_save = pinfo->private_data;
TRY {
/* Version number */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
- tvb, offset, 4, TRUE);
+ tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
/* Encrypted body */
proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
- tvb, offset, encrypted_block_length, TRUE);
+ tvb, offset, encrypted_block_length, ENC_NA);
/* Try to decrypt */
decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
} CATCH(BoundsError) {
RETHROW;
} CATCH(ReportedBoundsError) {
+ /* Restore the private_data structure in case one of the
+ * called dissectors modified it (and, due to the exception,
+ * was unable to restore it).
+ */
+ pinfo->private_data = pd_save;
show_reported_bounds_error(tvb, pinfo, tree);
} ENDTRY;
{ &hf_ntlmssp_version_minor,
{ "Minor Version", "ntlmssp.version.minor", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_version_build_number,
- { "Major Version", "ntlmssp.version.build_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
+ { "Build Number", "ntlmssp.version.build_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{ &hf_ntlmssp_version_ntlm_current_revision,
{ "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
&ntlmssp_seal_fns);
ntlmssp_tap = register_tap("ntlmssp");
+
+ heur_dissector_add("credssp", dissect_ntlmssp_heur, proto_ntlmssp);
+
}
/*
* indent-tabs-mode: nil
* End:
*
- * vi: set shiftwidth=2 tabstop=8 expandtab
+ * vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/