From 38810b763bf66ee6a8ac469d984f7996f28c99c0 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Sun, 20 Jun 2021 22:28:36 +0300 Subject: [PATCH] credssp: fully dissect TSRemoteGuardCreds struct --- epan/dissectors/asn1/credssp/credssp.cnf | 31 +++- .../asn1/credssp/packet-credssp-template.c | 15 +- .../asn1/kerberos/packet-kerberos-template.c | 130 +++++++++++++++ .../asn1/kerberos/packet-kerberos-template.h | 3 + epan/dissectors/packet-credssp.c | 73 +++++++-- epan/dissectors/packet-kerberos.c | 142 ++++++++++++++++- epan/dissectors/packet-kerberos.h | 5 +- epan/dissectors/packet-ntlmssp.c | 150 ++++++++++++++++++ epan/dissectors/packet-ntlmssp.h | 3 + 9 files changed, 533 insertions(+), 19 deletions(-) diff --git a/epan/dissectors/asn1/credssp/credssp.cnf b/epan/dissectors/asn1/credssp/credssp.cnf index efa30c6f67..c7006415d3 100644 --- a/epan/dissectors/asn1/credssp/credssp.cnf +++ b/epan/dissectors/asn1/credssp/credssp.cnf @@ -94,8 +94,37 @@ TSRemoteGuardPackageCred/packageName TYPE = FT_STRING DISPLAY = STR_UNICODE STRI offset = dissect_ber_octet_string(implicit_tag, actx, NULL, tvb, offset, hf_index, &pname); - if(pname != NULL) + if(pname != NULL) { + gint nlen = tvb_captured_length(pname); + + if (nlen == sizeof(kerberos_pname) && memcmp(tvb_get_ptr(pname, 0, nlen), kerberos_pname, nlen) == 0) { + credssp_TS_RGC_package = TS_RGC_KERBEROS; + } else if (nlen == sizeof(ntlm_pname) && memcmp(tvb_get_ptr(pname, 0, nlen), ntlm_pname, nlen) == 0) { + credssp_TS_RGC_package = TS_RGC_NTLM; + } proto_tree_add_item(tree, hf_index, pname, 0, -1, ENC_UTF_16|ENC_LITTLE_ENDIAN); + } + +#.FN_BODY TSRemoteGuardPackageCred/credBuffer VAL_PTR = &creds + tvbuff_t *creds= NULL; + proto_tree *subtree; + + %(DEFAULT_BODY)s + + if (!creds) + return offset; + + switch(credssp_TS_RGC_package) { + case TS_RGC_KERBEROS: + subtree = proto_item_add_subtree(actx->created_item, ett_credssp_RGC_CredBuffer); + dissect_kerberos_KERB_TICKET_LOGON(creds, 0, actx, subtree); + break; + case TS_RGC_NTLM: + subtree = proto_item_add_subtree(actx->created_item, ett_credssp_RGC_CredBuffer); + dissect_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL(creds, 0, subtree); + break; + } + #.END diff --git a/epan/dissectors/asn1/credssp/packet-credssp-template.c b/epan/dissectors/asn1/credssp/packet-credssp-template.c index e62a8d3b3a..1a9b9c2717 100644 --- a/epan/dissectors/asn1/credssp/packet-credssp-template.c +++ b/epan/dissectors/asn1/credssp/packet-credssp-template.c @@ -19,9 +19,10 @@ #include "packet-ber.h" #include "packet-dcerpc.h" #include "packet-gssapi.h" +#include "packet-kerberos.h" +#include "packet-ntlmssp.h" #include "packet-credssp.h" - #define PNAME "Credential Security Support Provider" #define PSNAME "CredSSP" #define PFNAME "credssp" @@ -33,6 +34,15 @@ static gint creds_type; static gint credssp_ver; +static char kerberos_pname[] = "K\0e\0r\0b\0e\0r\0o\0s"; +static char ntlm_pname[] = "N\0T\0L\0M"; + +#define TS_RGC_UNKNOWN 0 +#define TS_RGC_KERBEROS 1 +#define TS_RGC_NTLM 2 + +static gint credssp_TS_RGC_package; + static gint exported_pdu_tap = -1; /* Initialize the protocol and registered fields */ @@ -53,6 +63,8 @@ static int hf_credssp_decr_PublicKeyAuth = -1;/* decr_PublicKeyAuth */ /* Initialize the subtree pointers */ static gint ett_credssp = -1; +static gint ett_credssp_RGC_CredBuffer = -1; + #include "packet-credssp-ett.c" #include "packet-credssp-fn.c" @@ -157,6 +169,7 @@ void proto_register_credssp(void) { /* List of subtrees */ static gint *ett[] = { &ett_credssp, + &ett_credssp_RGC_CredBuffer, #include "packet-credssp-ettarr.c" }; diff --git a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c index bfe3ebc57f..7348e7c20e 100644 --- a/epan/dissectors/asn1/kerberos/packet-kerberos-template.c +++ b/epan/dissectors/asn1/kerberos/packet-kerberos-template.c @@ -280,6 +280,15 @@ static gint hf_kerberos_FastOptions_spare_bit13 = -1; static gint hf_kerberos_FastOptions_spare_bit14 = -1; static gint hf_kerberos_FastOptions_spare_bit15 = -1; static gint hf_kerberos_FastOptions_kdc_follow_referrals = -1; +static gint hf_kerberos_KERB_TICKET_LOGON = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_MessageType = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_Flags = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicket = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED = -1; #endif #include "packet-kerberos-hf.c" @@ -300,6 +309,7 @@ static gint ett_krb_pac_privsvr_checksum = -1; static gint ett_krb_pac_client_info_type = -1; static gint ett_krb_pa_supported_enctypes = -1; static gint ett_krb_ad_ap_options = -1; +static gint ett_kerberos_KERB_TICKET_LOGON = -1; #ifdef HAVE_KERBEROS static gint ett_krb_pa_enc_ts_enc = -1; static gint ett_kerberos_KrbFastFinished = -1; @@ -4043,6 +4053,89 @@ kerberos_display_key(gpointer data _U_, gpointer userdata _U_) #endif /* HAVE_KERBEROS */ } +static const value_string KERB_LOGON_SUBMIT_TYPE[] = { + { 2, "KerbInteractiveLogon" }, + { 6, "KerbSmartCardLogon" }, + { 7, "KerbWorkstationUnlockLogon" }, + { 8, "KerbSmartCardUnlockLogon" }, + { 9, "KerbProxyLogon" }, + { 10, "KerbTicketLogon" }, + { 11, "KerbTicketUnlockLogon" }, + { 12, "KerbS4ULogon" }, + { 13, "KerbCertificateLogon" }, + { 14, "KerbCertificateS4ULogon" }, + { 15, "KerbCertificateUnlockLogon" }, + { 0, NULL } +}; + + +#define KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET 0x1 +#define KERB_LOGON_FLAG_REDIRECTED 0x2 + +static int* const ktl_flags_bits[] = { + &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET, + &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED, + NULL +}; + +int +dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree) +{ + proto_item *item; + proto_tree *subtree; + guint32 ServiceTicketLength; + guint32 TicketGrantingTicketLength; + int orig_offset; + + if (tvb_captured_length(tvb) < 32) + return offset; + + item = proto_tree_add_item(tree, hf_kerberos_KERB_TICKET_LOGON, tvb, offset, -1, ENC_NA); + subtree = proto_item_add_subtree(item, ett_kerberos_KERB_TICKET_LOGON); + + proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_MessageType, tvb, offset, 4, + ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_bitmask(subtree, tvb, offset, hf_kerberos_KERB_TICKET_LOGON_Flags, + ett_kerberos, ktl_flags_bits, ENC_LITTLE_ENDIAN); + offset+=4; + + ServiceTicketLength = tvb_get_letohl(tvb, offset); + proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength, tvb, + offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + TicketGrantingTicketLength = tvb_get_letohl(tvb, offset); + proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength, + tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + /* Skip two PUCHAR of ServiceTicket and TicketGrantingTicket */ + offset+=16; + + if (ServiceTicketLength == 0) + return offset; + + orig_offset = offset; + offset = dissect_kerberos_Ticket(FALSE, tvb, offset, actx, subtree, + hf_kerberos_KERB_TICKET_LOGON_ServiceTicket); + + if ((unsigned)(offset-orig_offset) != ServiceTicketLength) + return offset; + + if (TicketGrantingTicketLength == 0) + return offset; + + offset = dissect_kerberos_KRB_CRED(FALSE, tvb, offset, actx, subtree, + hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket); + + if ((unsigned)(offset-orig_offset) != ServiceTicketLength + TicketGrantingTicketLength) + return offset; + + return offset; +} + static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean dci, gboolean do_col_protocol, gboolean have_rm, @@ -4505,6 +4598,42 @@ void proto_register_kerberos(void) { { &hf_krb_key_hidden_item, { "KeyHiddenItem", "krb5.key_hidden_item", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON, + { "KERB_TICKET_LOGON", "kerberos.KERB_TICKET_LOGON", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_MessageType, + { "MessageType", "kerberos.KERB_TICKET_LOGON.MessageType", + FT_UINT32, BASE_DEC, VALS(KERB_LOGON_SUBMIT_TYPE), 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_Flags, + { "Flags", "kerberos.KERB_TICKET_LOGON.Flags", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength, + { "ServiceTicketLength", "kerberos.KERB_TICKET_LOGON.ServiceTicketLength", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength, + { "TicketGrantingTicketLength", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicketLength", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicket, + { "ServiceTicket", "kerberos.KERB_TICKET_LOGON.ServiceTicket", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket, + { "TicketGrantingTicket", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicket", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET, + { "allow_expired_ticket", "kerberos.KERB_TICKET_LOGON.FLAG_ALLOW_EXPIRED_TICKET", + FT_BOOLEAN, 32, NULL, KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED, + { "redirected", "kerberos.KERB_TICKET_LOGON.FLAG_REDIRECTED", + FT_BOOLEAN, 32, NULL, KERB_LOGON_FLAG_REDIRECTED, + NULL, HFILL }}, #ifdef HAVE_KERBEROS { &hf_kerberos_KrbFastResponse, { "KrbFastResponse", "kerberos.KrbFastResponse_element", @@ -4621,6 +4750,7 @@ void proto_register_kerberos(void) { &ett_krb_pac_client_info_type, &ett_krb_pa_supported_enctypes, &ett_krb_ad_ap_options, + &ett_kerberos_KERB_TICKET_LOGON, #ifdef HAVE_KERBEROS &ett_krb_pa_enc_ts_enc, &ett_kerberos_KrbFastFinished, diff --git a/epan/dissectors/asn1/kerberos/packet-kerberos-template.h b/epan/dissectors/asn1/kerberos/packet-kerberos-template.h index 7032d60d7f..4f776ae91c 100644 --- a/epan/dissectors/asn1/kerberos/packet-kerberos-template.h +++ b/epan/dissectors/asn1/kerberos/packet-kerberos-template.h @@ -71,6 +71,9 @@ gint kerberos_rm_to_reclen(guint krb_rm); void show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm); +int +dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree); + #ifdef HAVE_KERBEROS #define KRB_MAX_ORIG_LEN 256 #define KRB_MAX_KEY_LENGTH 32 diff --git a/epan/dissectors/packet-credssp.c b/epan/dissectors/packet-credssp.c index 98e0860e9b..d91a96d396 100644 --- a/epan/dissectors/packet-credssp.c +++ b/epan/dissectors/packet-credssp.c @@ -27,9 +27,10 @@ #include "packet-ber.h" #include "packet-dcerpc.h" #include "packet-gssapi.h" +#include "packet-kerberos.h" +#include "packet-ntlmssp.h" #include "packet-credssp.h" - #define PNAME "Credential Security Support Provider" #define PSNAME "CredSSP" #define PFNAME "credssp" @@ -41,6 +42,15 @@ static gint creds_type; static gint credssp_ver; +static char kerberos_pname[] = "K\0e\0r\0b\0e\0r\0o\0s"; +static char ntlm_pname[] = "N\0T\0L\0M"; + +#define TS_RGC_UNKNOWN 0 +#define TS_RGC_KERBEROS 1 +#define TS_RGC_NTLM 2 + +static gint credssp_TS_RGC_package; + static gint exported_pdu_tap = -1; /* Initialize the protocol and registered fields */ @@ -76,7 +86,7 @@ static int hf_credssp_cspData = -1; /* TSCspDataDetail */ static int hf_credssp_userHint = -1; /* OCTET_STRING */ static int hf_credssp_domainHint = -1; /* OCTET_STRING */ static int hf_credssp_packageName = -1; /* T_packageName */ -static int hf_credssp_credBuffer = -1; /* OCTET_STRING */ +static int hf_credssp_credBuffer = -1; /* T_credBuffer */ static int hf_credssp_logonCred = -1; /* TSRemoteGuardPackageCred */ static int hf_credssp_supplementalCreds = -1; /* SEQUENCE_OF_TSRemoteGuardPackageCred */ static int hf_credssp_supplementalCreds_item = -1; /* TSRemoteGuardPackageCred */ @@ -90,10 +100,12 @@ static int hf_credssp_errorCode = -1; /* T_errorCode */ static int hf_credssp_clientNonce = -1; /* T_clientNonce */ /*--- End of included file: packet-credssp-hf.c ---*/ -#line 53 "./asn1/credssp/packet-credssp-template.c" +#line 63 "./asn1/credssp/packet-credssp-template.c" /* Initialize the subtree pointers */ static gint ett_credssp = -1; +static gint ett_credssp_RGC_CredBuffer = -1; + /*--- Included file: packet-credssp-ett.c ---*/ #line 1 "./asn1/credssp/packet-credssp-ett.c" @@ -109,7 +121,7 @@ static gint ett_credssp_TSCredentials = -1; static gint ett_credssp_TSRequest = -1; /*--- End of included file: packet-credssp-ett.c ---*/ -#line 57 "./asn1/credssp/packet-credssp-template.c" +#line 69 "./asn1/credssp/packet-credssp-template.c" /*--- Included file: packet-credssp-fn.c ---*/ @@ -241,8 +253,48 @@ dissect_credssp_T_packageName(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset = dissect_ber_octet_string(implicit_tag, actx, NULL, tvb, offset, hf_index, &pname); - if(pname != NULL) + if(pname != NULL) { + gint nlen = tvb_captured_length(pname); + + if (nlen == sizeof(kerberos_pname) && memcmp(tvb_get_ptr(pname, 0, nlen), kerberos_pname, nlen) == 0) { + credssp_TS_RGC_package = TS_RGC_KERBEROS; + } else if (nlen == sizeof(ntlm_pname) && memcmp(tvb_get_ptr(pname, 0, nlen), ntlm_pname, nlen) == 0) { + credssp_TS_RGC_package = TS_RGC_NTLM; + } proto_tree_add_item(tree, hf_index, pname, 0, -1, ENC_UTF_16|ENC_LITTLE_ENDIAN); + } + + + + return offset; +} + + + +static int +dissect_credssp_T_credBuffer(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { +#line 109 "./asn1/credssp/credssp.cnf" + tvbuff_t *creds= NULL; + proto_tree *subtree; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, + &creds); + + + if (!creds) + return offset; + + switch(credssp_TS_RGC_package) { + case TS_RGC_KERBEROS: + subtree = proto_item_add_subtree(actx->created_item, ett_credssp_RGC_CredBuffer); + dissect_kerberos_KERB_TICKET_LOGON(creds, 0, actx, subtree); + break; + case TS_RGC_NTLM: + subtree = proto_item_add_subtree(actx->created_item, ett_credssp_RGC_CredBuffer); + dissect_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL(creds, 0, subtree); + break; + } + return offset; @@ -251,7 +303,7 @@ dissect_credssp_T_packageName(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int static const ber_sequence_t TSRemoteGuardPackageCred_sequence[] = { { &hf_credssp_packageName , BER_CLASS_CON, 0, 0, dissect_credssp_T_packageName }, - { &hf_credssp_credBuffer , BER_CLASS_CON, 1, 0, dissect_credssp_OCTET_STRING }, + { &hf_credssp_credBuffer , BER_CLASS_CON, 1, 0, dissect_credssp_T_credBuffer }, { NULL, 0, 0, 0, NULL } }; @@ -478,7 +530,7 @@ static int dissect_TSRequest_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, prot /*--- End of included file: packet-credssp-fn.c ---*/ -#line 59 "./asn1/credssp/packet-credssp-template.c" +#line 71 "./asn1/credssp/packet-credssp-template.c" /* * Dissect CredSSP PDUs @@ -644,7 +696,7 @@ void proto_register_credssp(void) { { &hf_credssp_credBuffer, { "credBuffer", "credssp.credBuffer", FT_BYTES, BASE_NONE, NULL, 0, - "OCTET_STRING", HFILL }}, + NULL, HFILL }}, { &hf_credssp_logonCred, { "logonCred", "credssp.logonCred_element", FT_NONE, BASE_NONE, NULL, 0, @@ -691,12 +743,13 @@ void proto_register_credssp(void) { NULL, HFILL }}, /*--- End of included file: packet-credssp-hfarr.c ---*/ -#line 155 "./asn1/credssp/packet-credssp-template.c" +#line 167 "./asn1/credssp/packet-credssp-template.c" }; /* List of subtrees */ static gint *ett[] = { &ett_credssp, + &ett_credssp_RGC_CredBuffer, /*--- Included file: packet-credssp-ettarr.c ---*/ #line 1 "./asn1/credssp/packet-credssp-ettarr.c" @@ -712,7 +765,7 @@ void proto_register_credssp(void) { &ett_credssp_TSRequest, /*--- End of included file: packet-credssp-ettarr.c ---*/ -#line 161 "./asn1/credssp/packet-credssp-template.c" +#line 174 "./asn1/credssp/packet-credssp-template.c" }; diff --git a/epan/dissectors/packet-kerberos.c b/epan/dissectors/packet-kerberos.c index ba29ac0d1d..141bb78439 100644 --- a/epan/dissectors/packet-kerberos.c +++ b/epan/dissectors/packet-kerberos.c @@ -288,6 +288,15 @@ static gint hf_kerberos_FastOptions_spare_bit13 = -1; static gint hf_kerberos_FastOptions_spare_bit14 = -1; static gint hf_kerberos_FastOptions_spare_bit15 = -1; static gint hf_kerberos_FastOptions_kdc_follow_referrals = -1; +static gint hf_kerberos_KERB_TICKET_LOGON = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_MessageType = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_Flags = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_ServiceTicket = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET = -1; +static gint hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED = -1; #endif @@ -524,7 +533,7 @@ static int hf_kerberos_PAC_OPTIONS_FLAGS_forward_to_full_dc = -1; static int hf_kerberos_PAC_OPTIONS_FLAGS_resource_based_constrained_delegation = -1; /*--- End of included file: packet-kerberos-hf.c ---*/ -#line 286 "./asn1/kerberos/packet-kerberos-template.c" +#line 295 "./asn1/kerberos/packet-kerberos-template.c" /* Initialize the subtree pointers */ static gint ett_kerberos = -1; @@ -542,6 +551,7 @@ static gint ett_krb_pac_privsvr_checksum = -1; static gint ett_krb_pac_client_info_type = -1; static gint ett_krb_pa_supported_enctypes = -1; static gint ett_krb_ad_ap_options = -1; +static gint ett_kerberos_KERB_TICKET_LOGON = -1; #ifdef HAVE_KERBEROS static gint ett_krb_pa_enc_ts_enc = -1; static gint ett_kerberos_KrbFastFinished = -1; @@ -639,7 +649,7 @@ static gint ett_kerberos_SPAKEResponse = -1; static gint ett_kerberos_PA_SPAKE = -1; /*--- End of included file: packet-kerberos-ett.c ---*/ -#line 311 "./asn1/kerberos/packet-kerberos-template.c" +#line 321 "./asn1/kerberos/packet-kerberos-template.c" static expert_field ei_kerberos_missing_keytype = EI_INIT; static expert_field ei_kerberos_decrypted_keytype = EI_INIT; @@ -770,7 +780,7 @@ typedef enum _KERBEROS_KRBFASTARMORTYPES_enum { } KERBEROS_KRBFASTARMORTYPES_enum; /*--- End of included file: packet-kerberos-val.h ---*/ -#line 325 "./asn1/kerberos/packet-kerberos-template.c" +#line 335 "./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) @@ -7374,7 +7384,7 @@ dissect_kerberos_PA_SPAKE(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offs /*--- End of included file: packet-kerberos-fn.c ---*/ -#line 3834 "./asn1/kerberos/packet-kerberos-template.c" +#line 3844 "./asn1/kerberos/packet-kerberos-template.c" #ifdef HAVE_KERBEROS static const ber_sequence_t PA_ENC_TS_ENC_sequence[] = { @@ -7587,6 +7597,89 @@ kerberos_display_key(gpointer data _U_, gpointer userdata _U_) #endif /* HAVE_KERBEROS */ } +static const value_string KERB_LOGON_SUBMIT_TYPE[] = { + { 2, "KerbInteractiveLogon" }, + { 6, "KerbSmartCardLogon" }, + { 7, "KerbWorkstationUnlockLogon" }, + { 8, "KerbSmartCardUnlockLogon" }, + { 9, "KerbProxyLogon" }, + { 10, "KerbTicketLogon" }, + { 11, "KerbTicketUnlockLogon" }, + { 12, "KerbS4ULogon" }, + { 13, "KerbCertificateLogon" }, + { 14, "KerbCertificateS4ULogon" }, + { 15, "KerbCertificateUnlockLogon" }, + { 0, NULL } +}; + + +#define KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET 0x1 +#define KERB_LOGON_FLAG_REDIRECTED 0x2 + +static int* const ktl_flags_bits[] = { + &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET, + &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED, + NULL +}; + +int +dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree) +{ + proto_item *item; + proto_tree *subtree; + guint32 ServiceTicketLength; + guint32 TicketGrantingTicketLength; + int orig_offset; + + if (tvb_captured_length(tvb) < 32) + return offset; + + item = proto_tree_add_item(tree, hf_kerberos_KERB_TICKET_LOGON, tvb, offset, -1, ENC_NA); + subtree = proto_item_add_subtree(item, ett_kerberos_KERB_TICKET_LOGON); + + proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_MessageType, tvb, offset, 4, + ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_bitmask(subtree, tvb, offset, hf_kerberos_KERB_TICKET_LOGON_Flags, + ett_kerberos, ktl_flags_bits, ENC_LITTLE_ENDIAN); + offset+=4; + + ServiceTicketLength = tvb_get_letohl(tvb, offset); + proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength, tvb, + offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + TicketGrantingTicketLength = tvb_get_letohl(tvb, offset); + proto_tree_add_item(subtree, hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength, + tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + /* Skip two PUCHAR of ServiceTicket and TicketGrantingTicket */ + offset+=16; + + if (ServiceTicketLength == 0) + return offset; + + orig_offset = offset; + offset = dissect_kerberos_Ticket(FALSE, tvb, offset, actx, subtree, + hf_kerberos_KERB_TICKET_LOGON_ServiceTicket); + + if ((unsigned)(offset-orig_offset) != ServiceTicketLength) + return offset; + + if (TicketGrantingTicketLength == 0) + return offset; + + offset = dissect_kerberos_KRB_CRED(FALSE, tvb, offset, actx, subtree, + hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket); + + if ((unsigned)(offset-orig_offset) != ServiceTicketLength + TicketGrantingTicketLength) + return offset; + + return offset; +} + static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean dci, gboolean do_col_protocol, gboolean have_rm, @@ -8049,6 +8142,42 @@ void proto_register_kerberos(void) { { &hf_krb_key_hidden_item, { "KeyHiddenItem", "krb5.key_hidden_item", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON, + { "KERB_TICKET_LOGON", "kerberos.KERB_TICKET_LOGON", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_MessageType, + { "MessageType", "kerberos.KERB_TICKET_LOGON.MessageType", + FT_UINT32, BASE_DEC, VALS(KERB_LOGON_SUBMIT_TYPE), 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_Flags, + { "Flags", "kerberos.KERB_TICKET_LOGON.Flags", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicketLength, + { "ServiceTicketLength", "kerberos.KERB_TICKET_LOGON.ServiceTicketLength", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicketLength, + { "TicketGrantingTicketLength", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicketLength", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_ServiceTicket, + { "ServiceTicket", "kerberos.KERB_TICKET_LOGON.ServiceTicket", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_TicketGrantingTicket, + { "TicketGrantingTicket", "kerberos.KERB_TICKET_LOGON.TicketGrantingTicket", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_FLAG_ALLOW_EXPIRED_TICKET, + { "allow_expired_ticket", "kerberos.KERB_TICKET_LOGON.FLAG_ALLOW_EXPIRED_TICKET", + FT_BOOLEAN, 32, NULL, KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET, + NULL, HFILL }}, + { &hf_kerberos_KERB_TICKET_LOGON_FLAG_REDIRECTED, + { "redirected", "kerberos.KERB_TICKET_LOGON.FLAG_REDIRECTED", + FT_BOOLEAN, 32, NULL, KERB_LOGON_FLAG_REDIRECTED, + NULL, HFILL }}, #ifdef HAVE_KERBEROS { &hf_kerberos_KrbFastResponse, { "KrbFastResponse", "kerberos.KrbFastResponse_element", @@ -9062,7 +9191,7 @@ void proto_register_kerberos(void) { NULL, HFILL }}, /*--- End of included file: packet-kerberos-hfarr.c ---*/ -#line 4605 "./asn1/kerberos/packet-kerberos-template.c" +#line 4734 "./asn1/kerberos/packet-kerberos-template.c" }; /* List of subtrees */ @@ -9082,6 +9211,7 @@ void proto_register_kerberos(void) { &ett_krb_pac_client_info_type, &ett_krb_pa_supported_enctypes, &ett_krb_ad_ap_options, + &ett_kerberos_KERB_TICKET_LOGON, #ifdef HAVE_KERBEROS &ett_krb_pa_enc_ts_enc, &ett_kerberos_KrbFastFinished, @@ -9179,7 +9309,7 @@ void proto_register_kerberos(void) { &ett_kerberos_PA_SPAKE, /*--- End of included file: packet-kerberos-ettarr.c ---*/ -#line 4632 "./asn1/kerberos/packet-kerberos-template.c" +#line 4762 "./asn1/kerberos/packet-kerberos-template.c" }; static ei_register_info ei[] = { diff --git a/epan/dissectors/packet-kerberos.h b/epan/dissectors/packet-kerberos.h index b5d32fcd85..64162ad83b 100644 --- a/epan/dissectors/packet-kerberos.h +++ b/epan/dissectors/packet-kerberos.h @@ -79,6 +79,9 @@ gint kerberos_rm_to_reclen(guint krb_rm); void show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm); +int +dissect_kerberos_KERB_TICKET_LOGON(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree); + #ifdef HAVE_KERBEROS #define KRB_MAX_ORIG_LEN 256 #define KRB_MAX_KEY_LENGTH 32 @@ -162,6 +165,6 @@ int dissect_kerberos_TGT_REP(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int o int dissect_kerberos_ChangePasswdData(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_); /*--- End of included file: packet-kerberos-exp.h ---*/ -#line 130 "./asn1/kerberos/packet-kerberos-template.h" +#line 133 "./asn1/kerberos/packet-kerberos-template.h" #endif /* __PACKET_KERBEROS_H */ diff --git a/epan/dissectors/packet-ntlmssp.c b/epan/dissectors/packet-ntlmssp.c index 316943c60e..3018cf4c0b 100644 --- a/epan/dissectors/packet-ntlmssp.c +++ b/epan/dissectors/packet-ntlmssp.c @@ -251,6 +251,19 @@ static int hf_ntlmssp_ntlmv2_response_pad = -1; static int hf_ntlmssp_ntlmv2_response_time = -1; static int hf_ntlmssp_ntlmv2_response_chal = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Version = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Flags = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_LM_PRESENT = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_NT_PRESENT = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_REMOVED = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_CREDKEY_PRESENT = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_SHA_PRESENT = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKey = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKeyType = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCredsSize = -1; +static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCreds = -1; + static gint ett_ntlmssp = -1; static gint ett_ntlmssp_negotiate_flags = -1; static gint ett_ntlmssp_string = -1; @@ -260,6 +273,7 @@ static gint ett_ntlmssp_challenge_target_info = -1; static gint ett_ntlmssp_challenge_target_info_item = -1; static gint ett_ntlmssp_ntlmv2_response = -1; static gint ett_ntlmssp_ntlmv2_response_item = -1; +static gint ett_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL = -1; static expert_field ei_ntlmssp_v2_key_too_long = EI_INIT; static expert_field ei_ntlmssp_blob_len_too_long = EI_INIT; @@ -2821,6 +2835,93 @@ static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = { wrap_dissect_ntlmssp_payload_only /* Response data */ }; +static const value_string MSV1_0_CRED_VERSION[] = { + { 0x00000000, "MSV1_0_CRED_VERSION" }, + { 0x00000002, "MSV1_0_CRED_VERSION_V2" }, + { 0x00000004, "MSV1_0_CRED_VERSION_V3" }, + { 0xffff0001, "MSV1_0_CRED_VERSION_IUM" }, + { 0xffff0002, "MSV1_0_CRED_VERSION_REMOTE" }, + { 0xfffffffe, "MSV1_0_CRED_VERSION_RESERVED_1" }, + { 0xffffffff, "MSV1_0_CRED_VERSION_INVALID" }, + { 0, NULL } +}; + +#define MSV1_0_CRED_LM_PRESENT 0x0001 +#define MSV1_0_CRED_NT_PRESENT 0x0002 +#define MSV1_0_CRED_REMOVED 0x0004 +#define MSV1_0_CRED_CREDKEY_PRESENT 0x0008 +#define MSV1_0_CRED_SHA_PRESENT 0x0010 + +static int* const MSV1_0_CRED_FLAGS_bits[] = { + &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_LM_PRESENT, + &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_NT_PRESENT, + &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_REMOVED, + &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_CREDKEY_PRESENT, + &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_SHA_PRESENT, + NULL +}; + +static const value_string MSV1_0_CREDENTIAL_KEY_TYPE[] = { + { 0, "InvalidCredKey" }, + { 1, "IUMCredKey" }, + { 2, "DomainUserCredKey" }, + { 3, "LocalUserCredKey" }, + { 4, "ExternallySuppliedCredKey" }, + { 0, NULL } +}; + +#define MSV1_0_CREDENTIAL_KEY_LENGTH 20 + +int +dissect_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL(tvbuff_t *tvb, int offset, proto_tree *tree) +{ + proto_item *item; + proto_tree *subtree; + guint32 EncryptedCredsSize; + + if (tvb_captured_length(tvb) < 36) + return offset; + + item = proto_tree_add_item(tree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL, tvb, + offset, -1, ENC_NA); + subtree = proto_item_add_subtree(item, ett_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL); + + proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Version, tvb, + offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_bitmask(subtree, tvb, offset, + hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Flags, + ett_ntlmssp, MSV1_0_CRED_FLAGS_bits, ENC_LITTLE_ENDIAN); + offset+=4; + + proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKey, + tvb, offset, MSV1_0_CREDENTIAL_KEY_LENGTH, ENC_NA); + offset+=MSV1_0_CREDENTIAL_KEY_LENGTH; + + proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKeyType, + tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + EncryptedCredsSize = tvb_get_letohl(tvb, offset); + proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCredsSize, + tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset+=4; + + if (EncryptedCredsSize == 0) + return offset; + + if (tvb_captured_length(tvb) < (36 + EncryptedCredsSize)) + return offset; + + proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCreds, + tvb, offset, EncryptedCredsSize, ENC_NA); + offset+=EncryptedCredsSize; + + return offset; +} + + void proto_register_ntlmssp(void) { @@ -3406,6 +3507,54 @@ proto_register_ntlmssp(void) FT_BYTES, BASE_NONE, NULL, 0x0, "The 8-byte NTLMv2 challenge message generated by the client", HFILL } }, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL, + { "NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Version, + { "Version", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.Version", + FT_UINT32, BASE_HEX, VALS(MSV1_0_CRED_VERSION), 0, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Flags, + { "Flags", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.Flags", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_LM_PRESENT, + { "lm_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.LM_PRESENT", + FT_BOOLEAN, 32, NULL, MSV1_0_CRED_LM_PRESENT, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_NT_PRESENT, + { "nt_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.NT_PRESENT", + FT_BOOLEAN, 32, NULL, MSV1_0_CRED_NT_PRESENT, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_REMOVED, + { "removed", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.REMOVED", + FT_BOOLEAN, 32, NULL, MSV1_0_CRED_REMOVED, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_CREDKEY_PRESENT, + { "credkey_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.CREDKEY_PRESENT", + FT_BOOLEAN, 32, NULL, MSV1_0_CRED_CREDKEY_PRESENT, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_SHA_PRESENT, + { "sha_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.SHA_PRESENT", + FT_BOOLEAN, 32, NULL, MSV1_0_CRED_SHA_PRESENT, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKey, + { "CredentialKey", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.CredentialKey", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKeyType, + { "CredentialKeyType", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.CredentialKeyType", + FT_UINT32, BASE_DEC, VALS(MSV1_0_CREDENTIAL_KEY_TYPE), 0, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCredsSize, + { "EncryptedCredsSize", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.EncryptedCredsSize", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCreds, + { "EncryptedCreds", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.EncryptedCreds", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, }; @@ -3419,6 +3568,7 @@ proto_register_ntlmssp(void) &ett_ntlmssp_challenge_target_info_item, &ett_ntlmssp_ntlmv2_response, &ett_ntlmssp_ntlmv2_response_item, + &ett_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL, }; static ei_register_info ei[] = { { &ei_ntlmssp_v2_key_too_long, { "ntlmssp.v2_key_too_long", PI_UNDECODED, PI_WARN, "NTLM v2 key is too long", EXPFILL }}, diff --git a/epan/dissectors/packet-ntlmssp.h b/epan/dissectors/packet-ntlmssp.h index a25b9fdfbe..99a43cde47 100644 --- a/epan/dissectors/packet-ntlmssp.h +++ b/epan/dissectors/packet-ntlmssp.h @@ -61,4 +61,7 @@ ntlmssp_create_session_key(packet_info *pinfo, const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response); +int +dissect_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL(tvbuff_t *tvb, int offset, proto_tree *tree); + #endif