packet-dcerpc: pass down header/trailer for hdr_signing

Change-Id: I1d14ffe928e1b303eee7e95a45a9617ffcfb151b
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-on: https://code.wireshark.org/review/35707
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Stefan Metzmacher 2019-11-07 00:23:39 +01:00 committed by Anders Broman
parent 560f120946
commit 6afa37bb1a
6 changed files with 143 additions and 25 deletions

View File

@ -7923,15 +7923,24 @@ dissect_packet_data(tvbuff_t *tvb ,tvbuff_t *auth_tvb _U_,
return(buf); return(buf);
} }
static tvbuff_t* dissect_request_data( tvbuff_t *tvb ,tvbuff_t *auth_tvb , static tvbuff_t* dissect_request_data(tvbuff_t *header_tvb _U_,
int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info ) tvbuff_t *payload_tvb,
tvbuff_t *trailer_tvb _U_,
tvbuff_t *auth_tvb,
packet_info *pinfo,
dcerpc_auth_info *auth_info)
{ {
return dissect_packet_data(tvb,auth_tvb,offset,pinfo,auth_info,0); return dissect_packet_data(payload_tvb,auth_tvb,0,pinfo,auth_info,0);
} }
static tvbuff_t* dissect_response_data( tvbuff_t *tvb ,tvbuff_t *auth_tvb ,
int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info ) static tvbuff_t* dissect_response_data(tvbuff_t *header_tvb _U_,
tvbuff_t *payload_tvb,
tvbuff_t *trailer_tvb _U_,
tvbuff_t *auth_tvb,
packet_info *pinfo,
dcerpc_auth_info *auth_info)
{ {
return dissect_packet_data(tvb,auth_tvb,offset,pinfo,auth_info,1); return dissect_packet_data(payload_tvb,auth_tvb,0,pinfo,auth_info,1);
} }
/* MS-NRPC 2.2.1.3.2 */ /* MS-NRPC 2.2.1.3.2 */

View File

@ -179,6 +179,7 @@ static const value_string authn_level_vals[] = {
#define PFC_FIRST_FRAG 0x01 /* First fragment */ #define PFC_FIRST_FRAG 0x01 /* First fragment */
#define PFC_LAST_FRAG 0x02 /* Last fragment */ #define PFC_LAST_FRAG 0x02 /* Last fragment */
#define PFC_PENDING_CANCEL 0x04 /* Cancel was pending at sender */ #define PFC_PENDING_CANCEL 0x04 /* Cancel was pending at sender */
#define PFC_HDR_SIGNING PFC_PENDING_CANCEL /* on bind and alter req */
#define PFC_RESERVED_1 0x08 #define PFC_RESERVED_1 0x08
#define PFC_CONC_MPX 0x10 /* supports concurrent multiplexing #define PFC_CONC_MPX 0x10 /* supports concurrent multiplexing
* of a single connection. */ * of a single connection. */
@ -704,6 +705,18 @@ typedef struct _dcerpc_bind_value {
e_guid_t transport; e_guid_t transport;
} dcerpc_bind_value; } dcerpc_bind_value;
static wmem_map_t *dcerpc_auths = NULL;
typedef struct _dcerpc_auth_context {
conversation_t *conv;
guint64 transport_salt;
guint8 auth_type;
guint8 auth_level;
guint32 auth_context_id;
guint32 first_frame;
gboolean hdr_signing;
} dcerpc_auth_context;
/* Extra data for DCERPC handling and tracking of context ids */ /* Extra data for DCERPC handling and tracking of context ids */
typedef struct _dcerpc_decode_as_data { typedef struct _dcerpc_decode_as_data {
guint16 dcectxid; /**< Context ID (DCERPC-specific) */ guint16 dcectxid; /**< Context ID (DCERPC-specific) */
@ -1278,7 +1291,9 @@ proto_tree_add_dcerpc_drep(proto_tree *tree, tvbuff_t *tvb, int offset, guint8 d
/* Hand off payload data to a registered dissector */ /* Hand off payload data to a registered dissector */
static tvbuff_t *decode_encrypted_data(tvbuff_t *data_tvb, static tvbuff_t *decode_encrypted_data(tvbuff_t *header_tvb,
tvbuff_t *payload_tvb,
tvbuff_t *trailer_tvb,
packet_info *pinfo, packet_info *pinfo,
e_dce_cn_common_hdr_t *hdr, e_dce_cn_common_hdr_t *hdr,
dcerpc_auth_info *auth_info) dcerpc_auth_info *auth_info)
@ -1302,7 +1317,7 @@ static tvbuff_t *decode_encrypted_data(tvbuff_t *data_tvb,
} }
if (fn) if (fn)
return fn(data_tvb, auth_info->auth_tvb, 0, pinfo, auth_info); return fn(header_tvb, payload_tvb, trailer_tvb, auth_info->auth_tvb, pinfo, auth_info);
return NULL; return NULL;
} }
@ -1790,6 +1805,31 @@ dcerpc_bind_hash(gconstpointer k)
return hash; return hash;
} }
static gint
dcerpc_auth_context_equal(gconstpointer k1, gconstpointer k2)
{
const dcerpc_auth_context *key1 = (const dcerpc_auth_context *)k1;
const dcerpc_auth_context *key2 = (const dcerpc_auth_context *)k2;
return ((key1->conv == key2->conv)
&& (key1->auth_context_id == key2->auth_context_id)
&& (key1->transport_salt == key2->transport_salt));
}
static guint
dcerpc_auth_context_hash(gconstpointer k)
{
const dcerpc_auth_context *key = (const dcerpc_auth_context *)k;
guint hash;
hash = GPOINTER_TO_UINT(key->conv);
hash += key->auth_context_id;
/* sizeof(guint) might be smaller than sizeof(guint64) */
hash += (guint)key->transport_salt;
hash += (guint)(key->transport_salt << sizeof(guint));
return hash;
}
/* /*
* To keep track of callid mappings. Should really use some generic * To keep track of callid mappings. Should really use some generic
* conversation support instead. * conversation support instead.
@ -3743,6 +3783,39 @@ dissect_dcerpc_cn_auth_move(dcerpc_auth_info *auth_info, proto_tree *dcerpc_tree
} }
} }
static dcerpc_auth_context *find_or_create_dcerpc_auth_context(packet_info *pinfo,
dcerpc_auth_info *auth_info)
{
dcerpc_auth_context auth_key = {
.conv = find_or_create_conversation(pinfo),
.transport_salt = dcerpc_get_transport_salt(pinfo),
.auth_type = auth_info->auth_type,
.auth_level = auth_info->auth_level,
.auth_context_id = auth_info->auth_context_id,
.first_frame = G_MAXUINT32,
};
dcerpc_auth_context *auth_value = NULL;
auth_value = (dcerpc_auth_context *)wmem_map_lookup(dcerpc_auths, &auth_key);
if (auth_value != NULL) {
goto return_value;
}
auth_value = (dcerpc_auth_context *)wmem_alloc(wmem_file_scope(), sizeof (dcerpc_auth_context));
if (auth_value == NULL) {
return NULL;
}
*auth_value = auth_key;
wmem_map_insert(dcerpc_auths, auth_value, auth_value);
return_value:
if (pinfo->fd->num < auth_value->first_frame) {
auth_value->first_frame = pinfo->fd->num;
}
return auth_value;
}
static void static void
dissect_dcerpc_cn_auth(tvbuff_t *tvb, int stub_offset, packet_info *pinfo, dissect_dcerpc_cn_auth(tvbuff_t *tvb, int stub_offset, packet_info *pinfo,
proto_tree *dcerpc_tree, e_dce_cn_common_hdr_t *hdr, proto_tree *dcerpc_tree, e_dce_cn_common_hdr_t *hdr,
@ -3754,6 +3827,7 @@ dissect_dcerpc_cn_auth(tvbuff_t *tvb, int stub_offset, packet_info *pinfo,
* Initially set auth_level and auth_type to zero to indicate that we * Initially set auth_level and auth_type to zero to indicate that we
* haven't yet seen any authentication level information. * haven't yet seen any authentication level information.
*/ */
auth_info->hdr_signing = FALSE;
auth_info->auth_type = 0; auth_info->auth_type = 0;
auth_info->auth_level = 0; auth_info->auth_level = 0;
auth_info->auth_context_id = 0; auth_info->auth_context_id = 0;
@ -3788,6 +3862,9 @@ dissect_dcerpc_cn_auth(tvbuff_t *tvb, int stub_offset, packet_info *pinfo,
*/ */
offset = hdr->frag_len - (hdr->auth_len + 8); offset = hdr->frag_len - (hdr->auth_len + 8);
if (offset == 0 || tvb_offset_exists(tvb, offset - 1)) { if (offset == 0 || tvb_offset_exists(tvb, offset - 1)) {
dcerpc_auth_context *auth_context = NULL;
int auth_offset = offset;
/* Compute the size of the auth block. Note that this should not /* Compute the size of the auth block. Note that this should not
include auth padding, since when NTLMSSP encryption is used, the include auth padding, since when NTLMSSP encryption is used, the
padding is actually inside the encrypted stub */ padding is actually inside the encrypted stub */
@ -3837,10 +3914,22 @@ dissect_dcerpc_cn_auth(tvbuff_t *tvb, int stub_offset, packet_info *pinfo,
/* /*
* Dissect the authentication data. * Dissect the authentication data.
*/ */
auth_info->auth_hdr_tvb = tvb_new_subset_length_caplen(tvb, auth_offset, 8, 8);
auth_info->auth_tvb = tvb_new_subset_length_caplen(tvb, offset, auth_info->auth_tvb = tvb_new_subset_length_caplen(tvb, offset,
MIN(hdr->auth_len,tvb_reported_length_remaining(tvb, offset)), MIN(hdr->auth_len,tvb_reported_length_remaining(tvb, offset)),
hdr->auth_len); hdr->auth_len);
auth_context = find_or_create_dcerpc_auth_context(pinfo, auth_info);
if (auth_context != NULL) {
if (hdr->ptype == PDU_BIND || hdr->ptype == PDU_ALTER) {
if (auth_context->first_frame == pinfo->fd->num) {
auth_context->hdr_signing = (hdr->flags & PFC_HDR_SIGNING);
}
}
auth_info->hdr_signing = auth_context->hdr_signing;
}
auth_info->auth_fns = get_auth_subdissector_fns(auth_info->auth_level, auth_info->auth_fns = get_auth_subdissector_fns(auth_info->auth_level,
auth_info->auth_type); auth_info->auth_type);
if (auth_info->auth_fns != NULL) if (auth_info->auth_fns != NULL)
@ -4266,6 +4355,7 @@ dissect_dcerpc_cn_stub(tvbuff_t *tvb, int offset, packet_info *pinfo,
gboolean save_fragmented; gboolean save_fragmented;
fragment_head *fd_head = NULL; fragment_head *fd_head = NULL;
tvbuff_t *header_tvb = NULL, *trailer_tvb = NULL;
tvbuff_t *payload_tvb, *decrypted_tvb = NULL; tvbuff_t *payload_tvb, *decrypted_tvb = NULL;
proto_item *pi; proto_item *pi;
proto_item *parent_pi; proto_item *parent_pi;
@ -4284,7 +4374,9 @@ dissect_dcerpc_cn_stub(tvbuff_t *tvb, int offset, packet_info *pinfo,
reported_length -= auth_info->auth_size; reported_length -= auth_info->auth_size;
if (length > reported_length) if (length > reported_length)
length = reported_length; length = reported_length;
header_tvb = tvb_new_subset_length_caplen(tvb, 0, offset, offset);
payload_tvb = tvb_new_subset_length_caplen(tvb, offset, length, reported_length); payload_tvb = tvb_new_subset_length_caplen(tvb, offset, length, reported_length);
trailer_tvb = auth_info->auth_hdr_tvb;
/* Decrypt the PDU if it is encrypted */ /* Decrypt the PDU if it is encrypted */
@ -4296,7 +4388,8 @@ dissect_dcerpc_cn_stub(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (auth_info->auth_fns != NULL) { if (auth_info->auth_fns != NULL) {
tvbuff_t *result; tvbuff_t *result;
result = decode_encrypted_data(payload_tvb, pinfo, hdr, auth_info); result = decode_encrypted_data(header_tvb, payload_tvb, trailer_tvb,
pinfo, hdr, auth_info);
if (result) { if (result) {
proto_tree_add_item(dcerpc_tree, hf_dcerpc_encrypted_stub_data, payload_tvb, 0, -1, ENC_NA); proto_tree_add_item(dcerpc_tree, hf_dcerpc_encrypted_stub_data, payload_tvb, 0, -1, ENC_NA);
@ -7060,6 +7153,11 @@ proto_register_dcerpc(void)
/* structures and data for BIND */ /* structures and data for BIND */
dcerpc_binds = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dcerpc_bind_hash, dcerpc_bind_equal); dcerpc_binds = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dcerpc_bind_hash, dcerpc_bind_equal);
dcerpc_auths = wmem_map_new_autoreset(wmem_epan_scope(),
wmem_file_scope(),
dcerpc_auth_context_hash,
dcerpc_auth_context_equal);
/* structures and data for CALL */ /* structures and data for CALL */
dcerpc_cn_calls = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dcerpc_cn_call_hash, dcerpc_cn_call_equal); dcerpc_cn_calls = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dcerpc_cn_call_hash, dcerpc_cn_call_equal);
dcerpc_dg_calls = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dcerpc_dg_call_hash, dcerpc_dg_call_equal); dcerpc_dg_calls = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), dcerpc_dg_call_hash, dcerpc_dg_call_equal);

View File

@ -91,12 +91,14 @@ typedef struct _e_dce_dg_common_hdr_t {
struct _dcerpc_auth_subdissector_fns; struct _dcerpc_auth_subdissector_fns;
typedef struct _dcerpc_auth_info { typedef struct _dcerpc_auth_info {
gboolean hdr_signing;
guint8 auth_type; guint8 auth_type;
guint8 auth_level; guint8 auth_level;
guint32 auth_context_id; guint32 auth_context_id;
guint8 auth_pad_len; guint8 auth_pad_len;
guint32 auth_size; guint32 auth_size;
struct _dcerpc_auth_subdissector_fns *auth_fns; struct _dcerpc_auth_subdissector_fns *auth_fns;
tvbuff_t *auth_hdr_tvb;
tvbuff_t *auth_tvb; tvbuff_t *auth_tvb;
proto_item *auth_item; proto_item *auth_item;
proto_tree *auth_tree; proto_tree *auth_tree;
@ -425,9 +427,10 @@ typedef struct _dcerpc_uuid_value {
/* Authenticated pipe registration functions and miscellanea */ /* Authenticated pipe registration functions and miscellanea */
typedef tvbuff_t *(dcerpc_decode_data_fnct_t)(tvbuff_t *data_tvb, typedef tvbuff_t *(dcerpc_decode_data_fnct_t)(tvbuff_t *header_tvb,
tvbuff_t *payload_tvb,
tvbuff_t *trailer_tvb,
tvbuff_t *auth_tvb, tvbuff_t *auth_tvb,
int offset,
packet_info *pinfo, packet_info *pinfo,
dcerpc_auth_info *auth_info); dcerpc_auth_info *auth_info);

View File

@ -670,8 +670,11 @@ wrap_dissect_gssapi_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
} }
tvbuff_t * tvbuff_t *
wrap_dissect_gssapi_payload(tvbuff_t *data_tvb, tvbuff_t *auth_tvb, wrap_dissect_gssapi_payload(tvbuff_t *header_tvb _U_,
int offset _U_, packet_info *pinfo, tvbuff_t *payload_tvb,
tvbuff_t *trailer_tvb _U_,
tvbuff_t *auth_tvb,
packet_info *pinfo,
dcerpc_auth_info *auth_info _U_) dcerpc_auth_info *auth_info _U_)
{ {
tvbuff_t *result; tvbuff_t *result;
@ -682,12 +685,12 @@ wrap_dissect_gssapi_payload(tvbuff_t *data_tvb, tvbuff_t *auth_tvb,
/* we need a full auth and a full data tvb or else we can't /* we need a full auth and a full data tvb or else we can't
decrypt anything decrypt anything
*/ */
if((!auth_tvb)||(!data_tvb)){ if((!auth_tvb)||(!payload_tvb)){
return NULL; return NULL;
} }
gssapi_encrypt.decrypt_gssapi_tvb=DECRYPT_GSSAPI_DCE; gssapi_encrypt.decrypt_gssapi_tvb=DECRYPT_GSSAPI_DCE;
gssapi_encrypt.gssapi_encrypted_tvb=data_tvb; gssapi_encrypt.gssapi_encrypted_tvb=payload_tvb;
dissect_gssapi(auth_tvb, pinfo, NULL, &gssapi_encrypt); dissect_gssapi(auth_tvb, pinfo, NULL, &gssapi_encrypt);
result=gssapi_encrypt.gssapi_decrypted_tvb; result=gssapi_encrypt.gssapi_decrypted_tvb;

View File

@ -57,10 +57,12 @@ int wrap_dissect_gssapi_verf(tvbuff_t *tvb, int offset,
packet_info *pinfo, packet_info *pinfo,
proto_tree *tree, dcerpc_info *di, guint8 *drep); proto_tree *tree, dcerpc_info *di, guint8 *drep);
tvbuff_t *wrap_dissect_gssapi_payload(tvbuff_t *data_tvb, tvbuff_t *
tvbuff_t *auth_tvb, wrap_dissect_gssapi_payload(tvbuff_t *header_tvb _U_,
int offset, tvbuff_t *payload_tvb,
packet_info *pinfo, tvbuff_t *trailer_tvb _U_,
dcerpc_auth_info *auth_info); tvbuff_t *auth_tvb,
packet_info *pinfo,
dcerpc_auth_info *auth_info _U_);
#endif /* __PACKET_GSSAPI_H */ #endif /* __PACKET_GSSAPI_H */

View File

@ -2618,13 +2618,16 @@ dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
} }
static tvbuff_t * static tvbuff_t *
wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb, tvbuff_t *auth_tvb _U_, wrap_dissect_ntlmssp_payload_only(tvbuff_t *header_tvb _U_,
int offset, packet_info *pinfo, dcerpc_auth_info *auth_info _U_) tvbuff_t *payload_tvb,
tvbuff_t *trailer_tvb _U_,
tvbuff_t *auth_tvb _U_,
packet_info *pinfo,
dcerpc_auth_info *auth_info _U_)
{ {
tvbuff_t *data_tvb, *decrypted_tvb; tvbuff_t *decrypted_tvb;
data_tvb = tvb_new_subset_remaining(tvb, offset); dissect_ntlmssp_payload_only(payload_tvb, pinfo, NULL, &decrypted_tvb);
dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL, &decrypted_tvb);
return decrypted_tvb; return decrypted_tvb;
} }