packet-kerberos: add dissection of PAC_DEVICE_INFO

Change-Id: I81a3d76e445fa59580f0e95e451092dc526f017d
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-on: https://code.wireshark.org/review/37268
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Stefan Metzmacher 2016-06-20 08:00:20 +02:00 committed by Anders Broman
parent 36ca304359
commit a9634ab5a0
4 changed files with 258 additions and 24 deletions

View File

@ -213,6 +213,7 @@ static gint ett_krb_pac_logon_info = -1;
static gint ett_krb_pac_credential_info = -1;
static gint ett_krb_pac_s4u_delegation_info = -1;
static gint ett_krb_pac_upn_dns_info = -1;
static gint ett_krb_pac_device_info = -1;
static gint ett_krb_pac_server_checksum = -1;
static gint ett_krb_pac_privsvr_checksum = -1;
static gint ett_krb_pac_client_info_type = -1;
@ -2287,6 +2288,12 @@ dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset
static int
dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
int length = tvb_captured_length_remaining(tvb, offset);
if (length == 0) {
return offset;
}
proto_tree_add_item(parent_tree, hf_krb_pac_client_claims_info, tvb, offset, -1, ENC_NA);
return offset;
@ -2295,7 +2302,29 @@ dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int
static int
dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
proto_item *item;
proto_tree *tree;
guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
static dcerpc_info di; /* fake dcerpc_info struct */
static dcerpc_call_value call_data;
item = proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_device_info);
/* skip the first 16 bytes, they are some magic created by the idl
* compiler the first 4 bytes might be flags?
*/
offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
/* the PAC_DEVICE_INFO blob */
/* fake whatever state the dcerpc runtime support needs */
di.conformant_run=0;
/* we need di->call_data->flags.NDR64 == 0 */
di.call_data=&call_data;
init_ndr_pointer_list(&di);
offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
netlogon_dissect_PAC_DEVICE_INFO, NDR_POINTER_UNIQUE,
"PAC_DEVICE_INFO:", -1);
return offset;
}
@ -2303,6 +2332,12 @@ dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
static int
dissect_krb5_PAC_DEVICE_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
int length = tvb_captured_length_remaining(tvb, offset);
if (length == 0) {
return offset;
}
proto_tree_add_item(parent_tree, hf_krb_pac_device_claims_info, tvb, offset, -1, ENC_NA);
return offset;
@ -2949,6 +2984,7 @@ void proto_register_kerberos(void) {
&ett_krb_pac_credential_info,
&ett_krb_pac_s4u_delegation_info,
&ett_krb_pac_upn_dns_info,
&ett_krb_pac_device_info,
&ett_krb_pac_server_checksum,
&ett_krb_pac_privsvr_checksum,
&ett_krb_pac_client_info_type,

View File

@ -263,6 +263,9 @@ static int hf_netlogon_logon_srv = -1;
/* static int hf_netlogon_principal = -1; */
static int hf_netlogon_logon_dom = -1;
static int hf_netlogon_resourcegroupcount = -1;
static int hf_netlogon_accountdomaingroupcount = -1;
static int hf_netlogon_domaingroupcount = -1;
static int hf_netlogon_membership_domains_count = -1;
static int hf_netlogon_downlevel_domain_name = -1;
static int hf_netlogon_dns_domain_name = -1;
static int hf_netlogon_ad_client_dns_name = -1;
@ -433,6 +436,8 @@ static gint ett_trust_attribs = -1;
static gint ett_get_dcname_request_flags = -1;
static gint ett_dc_flags = -1;
static gint ett_wstr_LOGON_IDENTITY_INFO_string = -1;
static gint ett_domain_group_memberships = -1;
static gint ett_domains_group_memberships = -1;
static expert_field ei_netlogon_auth_nthash = EI_INIT;
static expert_field ei_netlogon_session_key = EI_INIT;
@ -1587,6 +1592,104 @@ netlogon_dissect_USER_FLAGS(tvbuff_t *tvb, int offset,
return offset;
}
static int
netlogon_dissect_GROUP_MEMBERSHIPS(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep,
int hf_count, const char *array_name)
{
guint32 rgc;
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_count, &rgc);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
array_name, -1);
return offset;
}
static int
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *parent_tree,
dcerpc_info *di, guint8 *drep,
int hf_count, const char *name)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
int old_offset=offset;
if(parent_tree){
tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
ett_domain_group_memberships,
&item, name);
}
offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
offset = netlogon_dissect_GROUP_MEMBERSHIPS(tvb, offset,
pinfo, tree,
di, drep,
hf_count,
"GroupIDs");
proto_item_set_len(item, offset-old_offset);
return offset;
}
static int
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS_WRAPPER(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep)
{
return netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvb, offset,
pinfo, tree,
di, drep,
hf_netlogon_domaingroupcount,
"DomainGroupIDs");
}
static int
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIP_ARRAY(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep)
{
offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS_WRAPPER);
return offset;
}
static int
netlogon_dissect_DOMAINS_GROUP_MEMBERSHIPS(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *parent_tree,
dcerpc_info *di, guint8 *drep,
int hf_count, const char *name)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
int old_offset=offset;
guint32 rgc;
if(parent_tree){
tree = proto_tree_add_subtree(parent_tree, tvb, offset, 0,
ett_domains_group_memberships,
&item, name);
}
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_count, &rgc);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
netlogon_dissect_DOMAIN_GROUP_MEMBERSHIP_ARRAY,
NDR_POINTER_UNIQUE,
name, -1);
proto_item_set_len(item, offset-old_offset);
return offset;
}
/*
* IDL typedef struct {
* IDL uint64 LogonTime;
@ -1671,12 +1774,10 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_group_rid, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_num_rids, NULL);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
"GROUP_MEMBERSHIP_ARRAY", -1);
offset = netlogon_dissect_GROUP_MEMBERSHIPS(tvb, offset,
pinfo, tree, di, drep,
hf_netlogon_num_rids,
"GroupIDs");
offset = netlogon_dissect_USER_FLAGS(tvb, offset,
pinfo, tree, di, drep);
@ -1904,6 +2005,7 @@ netlogon_dissect_VALIDATION_SAM_INFO4(tvbuff_t *tvb, int offset,
hf_netlogon_dummy_string10, 0);
return offset;
}
/*
* IDL typedef struct {
* IDL uint64 LogonTime;
@ -1944,7 +2046,6 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep)
{
guint32 rgc;
offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,di, drep);
#if 0
int i;
@ -2038,15 +2139,10 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
"SID_AND_ATTRIBUTES_ARRAY:", -1);
offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_resourcegroupcount, &rgc);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
"ResourceGroupIDs", -1);
offset = netlogon_dissect_DOMAIN_GROUP_MEMBERSHIPS(tvb, offset,
pinfo, tree, di, drep,
hf_netlogon_resourcegroupcount,
"ResourceGroupIDs");
return offset;
}
@ -2091,6 +2187,52 @@ netlogon_dissect_PAC_S4U_DELEGATION_INFO(tvbuff_t *tvb, int offset,
return offset;
}
/*
* IDL typedef struct {
* IDL long UserId;
* IDL long PrimaryGroupId;
* IDL SID AccountDomainId;
* IDL long AccountGroupCount;
* IDL [size_is(AccountGroupCount)] PGROUP_MEMBERSHIP AccountGroupIds;
* IDL ULONG SidCount;
* IDL [size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
* IDL ULONG DomainGroupCount;
* IDL [size_is(DomainGroupCount)] PDOMAIN_GROUP_MEMBERSHIP DomainGroup;
* IDL } PAC_DEVICE_INFO;
*/
int
netlogon_dissect_PAC_DEVICE_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep)
{
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_user_rid, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_group_rid, NULL);
offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, di, drep);
offset = netlogon_dissect_GROUP_MEMBERSHIPS(tvb, offset,
pinfo, tree, di, drep,
hf_netlogon_accountdomaingroupcount,
"AccountDomainGroupIds");
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_num_sid, NULL);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
"ExtraSids:SID_AND_ATTRIBUTES_ARRAY:", -1);
offset = netlogon_dissect_DOMAINS_GROUP_MEMBERSHIPS(tvb, offset,
pinfo, tree, di, drep,
hf_netlogon_membership_domains_count,
"ExtraDomain Membership Array");
return offset;
}
#if 0
static int
netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
@ -8513,6 +8655,18 @@ proto_register_dcerpc_netlogon(void)
{ "ResourceGroup count", "netlogon.resourcegroupcount", FT_UINT32, BASE_DEC,
NULL, 0, "Number of Resource Groups", HFILL }},
{ &hf_netlogon_accountdomaingroupcount,
{ "AccountDomainGroup count", "netlogon.accountdomaingroupcount", FT_UINT32, BASE_DEC,
NULL, 0, "Number of Account Domain Groups", HFILL }},
{ &hf_netlogon_domaingroupcount,
{ "DomainGroup count", "netlogon.domaingroupcount", FT_UINT32, BASE_DEC,
NULL, 0, "Number of Domain Groups", HFILL }},
{ &hf_netlogon_membership_domains_count,
{ "Membership Domains count", "netlogon.membershipsdomainscount", FT_UINT32, BASE_DEC,
NULL, 0, "Number of ExtraDomain Membership Arrays", HFILL }},
{ &hf_netlogon_computer_name,
{ "Computer Name", "netlogon.computer_name", FT_STRING, BASE_NONE,
NULL, 0, NULL, HFILL }},
@ -9522,7 +9676,9 @@ proto_register_dcerpc_netlogon(void)
&ett_user_flags,
&ett_nt_counted_longs_as_string,
&ett_user_account_control,
&ett_wstr_LOGON_IDENTITY_INFO_string
&ett_wstr_LOGON_IDENTITY_INFO_string,
&ett_domain_group_memberships,
&ett_domains_group_memberships,
};
static ei_register_info ei[] = {
{ &ei_netlogon_auth_nthash, {

View File

@ -79,4 +79,10 @@ netlogon_dissect_PAC_S4U_DELEGATION_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep);
/* needed to decrypt PAC_DEVICE_INFO in kerberos */
int
netlogon_dissect_PAC_DEVICE_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
dcerpc_info *di, guint8 *drep);
#endif /* packet-dcerpc-netlogon.h */

View File

@ -434,6 +434,7 @@ static gint ett_krb_pac_logon_info = -1;
static gint ett_krb_pac_credential_info = -1;
static gint ett_krb_pac_s4u_delegation_info = -1;
static gint ett_krb_pac_upn_dns_info = -1;
static gint ett_krb_pac_device_info = -1;
static gint ett_krb_pac_server_checksum = -1;
static gint ett_krb_pac_privsvr_checksum = -1;
static gint ett_krb_pac_client_info_type = -1;
@ -518,7 +519,7 @@ static gint ett_kerberos_PA_FX_FAST_REPLY = -1;
static gint ett_kerberos_KrbFastArmoredRep = -1;
/*--- End of included file: packet-kerberos-ett.c ---*/
#line 225 "./asn1/kerberos/packet-kerberos-template.c"
#line 226 "./asn1/kerberos/packet-kerberos-template.c"
static expert_field ei_kerberos_decrypted_keytype = EI_INIT;
static expert_field ei_kerberos_address = EI_INIT;
@ -639,7 +640,7 @@ typedef enum _KERBEROS_PADATA_TYPE_enum {
} KERBEROS_PADATA_TYPE_enum;
/*--- End of included file: packet-kerberos-val.h ---*/
#line 237 "./asn1/kerberos/packet-kerberos-template.c"
#line 238 "./asn1/kerberos/packet-kerberos-template.c"
static void
call_kerberos_callbacks(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int tag, kerberos_callbacks *cb)
@ -2693,6 +2694,12 @@ dissect_krb5_PAC_UPN_DNS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset
static int
dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
int length = tvb_captured_length_remaining(tvb, offset);
if (length == 0) {
return offset;
}
proto_tree_add_item(parent_tree, hf_krb_pac_client_claims_info, tvb, offset, -1, ENC_NA);
return offset;
@ -2701,7 +2708,29 @@ dissect_krb5_PAC_CLIENT_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int
static int
dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
proto_item *item;
proto_tree *tree;
guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
static dcerpc_info di; /* fake dcerpc_info struct */
static dcerpc_call_value call_data;
item = proto_tree_add_item(parent_tree, hf_krb_pac_device_info, tvb, offset, -1, ENC_NA);
tree = proto_item_add_subtree(item, ett_krb_pac_device_info);
/* skip the first 16 bytes, they are some magic created by the idl
* compiler the first 4 bytes might be flags?
*/
offset = dissect_krb5_PAC_NDRHEADERBLOB(tree, tvb, offset, &drep[0], actx);
/* the PAC_DEVICE_INFO blob */
/* fake whatever state the dcerpc runtime support needs */
di.conformant_run=0;
/* we need di->call_data->flags.NDR64 == 0 */
di.call_data=&call_data;
init_ndr_pointer_list(&di);
offset = dissect_ndr_pointer(tvb, offset, actx->pinfo, tree, &di, drep,
netlogon_dissect_PAC_DEVICE_INFO, NDR_POINTER_UNIQUE,
"PAC_DEVICE_INFO:", -1);
return offset;
}
@ -2709,6 +2738,12 @@ dissect_krb5_PAC_DEVICE_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
static int
dissect_krb5_PAC_DEVICE_CLAIMS_INFO(proto_tree *parent_tree, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_)
{
int length = tvb_captured_length_remaining(tvb, offset);
if (length == 0) {
return offset;
}
proto_tree_add_item(parent_tree, hf_krb_pac_device_claims_info, tvb, offset, -1, ENC_NA);
return offset;
@ -5403,7 +5438,7 @@ dissect_kerberos_EncryptedChallenge(gboolean implicit_tag _U_, tvbuff_t *tvb _U_
/*--- End of included file: packet-kerberos-fn.c ---*/
#line 2469 "./asn1/kerberos/packet-kerberos-template.c"
#line 2504 "./asn1/kerberos/packet-kerberos-template.c"
#ifdef HAVE_KERBEROS
static const ber_sequence_t PA_ENC_TS_ENC_sequence[] = {
@ -6706,7 +6741,7 @@ void proto_register_kerberos(void) {
NULL, HFILL }},
/*--- End of included file: packet-kerberos-hfarr.c ---*/
#line 2939 "./asn1/kerberos/packet-kerberos-template.c"
#line 2974 "./asn1/kerberos/packet-kerberos-template.c"
};
/* List of subtrees */
@ -6720,6 +6755,7 @@ void proto_register_kerberos(void) {
&ett_krb_pac_credential_info,
&ett_krb_pac_s4u_delegation_info,
&ett_krb_pac_upn_dns_info,
&ett_krb_pac_device_info,
&ett_krb_pac_server_checksum,
&ett_krb_pac_privsvr_checksum,
&ett_krb_pac_client_info_type,
@ -6804,7 +6840,7 @@ void proto_register_kerberos(void) {
&ett_kerberos_KrbFastArmoredRep,
/*--- End of included file: packet-kerberos-ettarr.c ---*/
#line 2961 "./asn1/kerberos/packet-kerberos-template.c"
#line 2997 "./asn1/kerberos/packet-kerberos-template.c"
};
static ei_register_info ei[] = {