aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorsahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>2009-10-20 08:44:26 +0000
committersahlberg <sahlberg@f5534014-38df-0310-8fa8-9805f1628bb7>2009-10-20 08:44:26 +0000
commitf325bcb8a5e0abb1ef6949594a3b94c6f282cd11 (patch)
treeff5d95b4855708903aacf0feb8c3f28b1fcc3b49 /epan
parentc154217435c14440c6f239a755aba366749d22e6 (diff)
From Matthieu Patou
schannel decryption git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@30631 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-dcerpc-netlogon.c2132
-rw-r--r--epan/dissectors/packet-dcerpc-nt.c4
-rw-r--r--epan/dissectors/packet-dcerpc-nt.h3
-rw-r--r--epan/dissectors/packet-dcerpc.c6
4 files changed, 1871 insertions, 274 deletions
diff --git a/epan/dissectors/packet-dcerpc-netlogon.c b/epan/dissectors/packet-dcerpc-netlogon.c
index 6049a41a42..a86a012f0a 100644
--- a/epan/dissectors/packet-dcerpc-netlogon.c
+++ b/epan/dissectors/packet-dcerpc-netlogon.c
@@ -28,7 +28,9 @@
#include "config.h"
#endif
+
#include <glib.h>
+#include <string.h>
#include <epan/packet.h>
#include "packet-dcerpc.h"
#include "packet-dcerpc-nt.h"
@@ -36,12 +38,93 @@
#include "packet-windows-common.h"
#include "packet-ntlmssp.h"
#include "packet-dcerpc-lsa.h"
+/* for keytab format */
+#include <epan/asn1.h>
+#include "packet-kerberos.h"
+/* for decoding */
+#include <epan/crypt/crypt-rc4.h>
+#include <epan/crypt/crypt-md4.h>
+#include <epan/crypt/crypt-md5.h>
+#include <epan/crypt/crypt-des.h>
+
+#ifdef DEBUG_NETLOGON
+#include <stdio.h>
+#define debugfprintf(...) fprintf(stderr,__VA_ARGS__)
+static void printnbyte(const guint8* tab,int nb,char* txt,char* txt2)
+{
+ int i=0;
+ debugprintf("%s ",txt);
+ for(i=0;i<nb;i++)
+ {
+ debugprintf("%02hhX ",*(tab+i));
+ }
+ debugprintf("%s",txt2);
+}
+#else
+#define debugprintf(...)
+static void printnbyte(const guint8* tab _U_,int nb _U_,char* txt _U_,char* txt2 _U_) {}
+#endif
+#define NETLOGON_FLAG_80000000 0x80000000
+#define NETLOGON_FLAG_40000000 0x40000000
+#define NETLOGON_FLAG_20000000 0x20000000
+#define NETLOGON_FLAG_10000000 0x10000000
+#define NETLOGON_FLAG_8000000 0x8000000
+#define NETLOGON_FLAG_4000000 0x4000000
+#define NETLOGON_FLAG_2000000 0x2000000
+#define NETLOGON_FLAG_1000000 0x1000000
+#define NETLOGON_FLAG_800000 0x800000
+#define NETLOGON_FLAG_USEAES 0x400000
+#define NETLOGON_FLAG_200000 0x200000
+#define NETLOGON_FLAG_100000 0x100000
+#define NETLOGON_FLAG_80000 0x80000
+#define NETLOGON_FLAG_40000 0x40000
+#define NETLOGON_FLAG_20000 0x20000
+#define NETLOGON_FLAG_10000 0x10000
+#define NETLOGON_FLAG_8000 0x8000
+#define NETLOGON_FLAG_STRONGKEY 0x4000
+#define NETLOGON_FLAG_2000 0x2000
+#define NETLOGON_FLAG_1000 0x1000
+#define NETLOGON_FLAG_800 0x800
+#define NETLOGON_FLAG_400 0x400
+#define NETLOGON_FLAG_200 0x200
+#define NETLOGON_FLAG_100 0x100
+#define NETLOGON_FLAG_80 0x80
+#define NETLOGON_FLAG_40 0x40
+#define NETLOGON_FLAG_20 0x20
+#define NETLOGON_FLAG_10 0x10
+#define NETLOGON_FLAG_8 0x8
+#define NETLOGON_FLAG_4 0x4
+#define NETLOGON_FLAG_2 0x2
+#define NETLOGON_FLAG_1 0x1
+static GHashTable *netlogon_auths=NULL;
+static GHashTable *schannel_auths;
+
+static gint DomainInfo_sid = -1;
+static gint DnsDomainInfo_sid = -1;
+static gint DnsDomainInfo_domain_guid = -1;
+static gint DnsDomainInfo_dns_domain = -1;
+static gint DnsDomainInfo_dns_forest = -1;
+static gint DnsDomainInfo_name = -1;
+static int hf_client_challenge = -1;
+static int hf_server_rid = -1;
+static int hf_server_challenge = -1;
+static int hf_client_credential = -1;
+static int hf_server_credential = -1;
static int proto_dcerpc_netlogon = -1;
+static int hf_netlogon_logon_dnslogondomainname = -1;
+static int hf_netlogon_logon_upn = -1;
static int hf_netlogon_group_attrs_mandatory = -1;
static int hf_netlogon_group_attrs_enabled_by_default = -1;
static int hf_netlogon_group_attrs_enabled = -1;
static int hf_netlogon_opnum = -1;
+static int hf_netlogon_data_length = -1;
+static int hf_netlogon_extraflags = -1;
+static int hf_netlogon_extra_flags_root_forest = -1;
+static int hf_netlogon_trust_flags_dc_firsthop = -1;
+static int hf_netlogon_trust_flags_rodc_to_dc = -1;
+static int hf_netlogon_trust_flags_rodc_ntlm = -1;
+static int hf_netlogon_package_name = -1;
static int hf_netlogon_rc = -1;
static int hf_netlogon_dos_rc = -1;
static int hf_netlogon_werr_rc = -1;
@@ -52,6 +135,38 @@ static int hf_netlogon_sensitive_data = -1;
static int hf_netlogon_security_information = -1;
static int hf_netlogon_dummy = -1;
static int hf_netlogon_neg_flags = -1;
+static int hf_netlogon_neg_flags_80000000 = -1;
+static int hf_netlogon_neg_flags_40000000 = -1;
+static int hf_netlogon_neg_flags_20000000 = -1;
+static int hf_netlogon_neg_flags_10000000 = -1;
+static int hf_netlogon_neg_flags_8000000 = -1;
+static int hf_netlogon_neg_flags_4000000 = -1;
+static int hf_netlogon_neg_flags_2000000 = -1;
+static int hf_netlogon_neg_flags_1000000 = -1;
+static int hf_netlogon_neg_flags_800000 = -1;
+static int hf_netlogon_neg_flags_400000 = -1;
+static int hf_netlogon_neg_flags_200000 = -1;
+static int hf_netlogon_neg_flags_100000 = -1;
+static int hf_netlogon_neg_flags_80000 = -1;
+static int hf_netlogon_neg_flags_40000 = -1;
+static int hf_netlogon_neg_flags_20000 = -1;
+static int hf_netlogon_neg_flags_10000 = -1;
+static int hf_netlogon_neg_flags_8000 = -1;
+static int hf_netlogon_neg_flags_4000 = -1;
+static int hf_netlogon_neg_flags_2000 = -1;
+static int hf_netlogon_neg_flags_1000 = -1;
+static int hf_netlogon_neg_flags_800 = -1;
+static int hf_netlogon_neg_flags_400 = -1;
+static int hf_netlogon_neg_flags_200 = -1;
+static int hf_netlogon_neg_flags_100 = -1;
+static int hf_netlogon_neg_flags_80 = -1;
+static int hf_netlogon_neg_flags_40 = -1;
+static int hf_netlogon_neg_flags_20 = -1;
+static int hf_netlogon_neg_flags_10 = -1;
+static int hf_netlogon_neg_flags_8 = -1;
+static int hf_netlogon_neg_flags_4 = -1;
+static int hf_netlogon_neg_flags_2 = -1;
+static int hf_netlogon_neg_flags_1 = -1;
static int hf_netlogon_minworkingsetsize = -1;
static int hf_netlogon_maxworkingsetsize = -1;
static int hf_netlogon_pagedpoollimit = -1;
@@ -77,6 +192,9 @@ static int hf_netlogon_pdc_connection_status = -1;
static int hf_netlogon_tc_connection_status = -1;
static int hf_netlogon_restart_state = -1;
static int hf_netlogon_attrs = -1;
+static int hf_netlogon_lsapolicy_len = -1;
+static int hf_netlogon_lsapolicy_referentid = -1;
+static int hf_netlogon_lsapolicy_pointer = -1;
static int hf_netlogon_count = -1;
static int hf_netlogon_entries = -1;
static int hf_netlogon_minpasswdlen = -1;
@@ -94,8 +212,32 @@ static int hf_netlogon_auditing_mode = -1;
static int hf_netlogon_max_audit_event_count = -1;
static int hf_netlogon_event_audit_option = -1;
static int hf_netlogon_unknown_string = -1;
-static int hf_netlogon_unknown_long = -1;
+static int hf_netlogon_trust_extention = -1;
+static int hf_netlogon_trust_max = -1;
+static int hf_netlogon_trust_offset = -1;
+static int hf_netlogon_trust_len = -1;
+static int hf_netlogon_dummy_string = -1;
+static int hf_netlogon_dummy_string2 = -1;
+static int hf_netlogon_dummy_string3 = -1;
+static int hf_netlogon_dummy_string4 = -1;
+static int hf_netlogon_dummy_string5 = -1;
+static int hf_netlogon_dummy_string6 = -1;
+static int hf_netlogon_dummy_string7 = -1;
+static int hf_netlogon_dummy_string8 = -1;
+static int hf_netlogon_dummy_string9 = -1;
+static int hf_netlogon_dummy_string10 = -1;
static int hf_netlogon_unknown_short = -1;
+static int hf_netlogon_unknown_long = -1;
+static int hf_netlogon_dummy1_long = -1;
+static int hf_netlogon_dummy2_long = -1;
+static int hf_netlogon_dummy3_long = -1;
+static int hf_netlogon_dummy4_long = -1;
+static int hf_netlogon_dummy5_long = -1;
+static int hf_netlogon_dummy6_long = -1;
+static int hf_netlogon_dummy7_long = -1;
+static int hf_netlogon_dummy8_long = -1;
+static int hf_netlogon_dummy9_long = -1;
+static int hf_netlogon_dummy10_long = -1;
static int hf_netlogon_unknown_char = -1;
static int hf_netlogon_logon_time = -1;
static int hf_netlogon_logoff_time = -1;
@@ -131,6 +273,7 @@ static int hf_netlogon_logon_dom = -1;
static int hf_netlogon_resourcegroupcount = -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;
static int hf_netlogon_domain_name = -1;
static int hf_netlogon_domain_create_time = -1;
static int hf_netlogon_domain_modify_time = -1;
@@ -142,7 +285,7 @@ static int hf_netlogon_serial_number = -1;
static int hf_netlogon_num_rids = -1;
static int hf_netlogon_num_trusts = -1;
static int hf_netlogon_num_controllers = -1;
-static int hf_netlogon_num_other_groups = -1;
+static int hf_netlogon_num_sid = -1;
static int hf_netlogon_computer_name = -1;
static int hf_netlogon_site_name = -1;
static int hf_netlogon_trusted_dc_name = -1;
@@ -154,7 +297,11 @@ static int hf_netlogon_dc_address_type = -1;
static int hf_netlogon_client_site_name = -1;
static int hf_netlogon_workstation = -1;
static int hf_netlogon_workstation_site_name = -1;
+static int hf_netlogon_os_version = -1;
static int hf_netlogon_workstation_os = -1;
+static int hf_netlogon_workstation_flags = -1;
+static int hf_netlogon_supportedenctypes = -1;
+
static int hf_netlogon_workstations = -1;
static int hf_netlogon_workstation_fqdn = -1;
static int hf_netlogon_group_name = -1;
@@ -259,6 +406,7 @@ static int hf_netlogon_dc_flags_dns_domain_flag = -1;
static int hf_netlogon_dc_flags_dns_forest_flag = -1;
static int hf_netlogon_dnsdomaininfo = -1;
+static gint ett_nt_counted_longs_as_string = -1;
static gint ett_dcerpc_netlogon = -1;
static gint ett_group_attrs = -1;
static gint ett_user_flags = -1;
@@ -266,6 +414,7 @@ static gint ett_user_account_control = -1;
static gint ett_QUOTA_LIMITS = -1;
static gint ett_IDENTITY_INFO = -1;
static gint ett_DELTA_ENUM = -1;
+static gint ett_authenticate_flags = -1;
static gint ett_CYPHER_VALUE = -1;
static gint ett_UNICODE_MULTI = -1;
static gint ett_DOMAIN_CONTROLLER_INFO = -1;
@@ -280,12 +429,43 @@ static gint ett_NT_OWF_PASSWORD = -1;
static gint ett_GROUP_MEMBERSHIP = -1;
static gint ett_BLOB = -1;
static gint ett_DS_DOMAIN_TRUSTS = -1;
+static gint ett_LSA_POLICY_INFO = -1;
static gint ett_DOMAIN_TRUST_INFO = -1;
static gint ett_trust_flags = -1;
static gint ett_trust_attribs = -1;
static gint ett_get_dcname_request_flags = -1;
static gint ett_dc_flags = -1;
+typedef struct _netlogon_auth_vars {
+ guint64 client_challenge;
+ guint64 server_challenge;
+ guint8 session_key[16];
+ guint8 encryption_key[16];
+ guint8 sequence[16];
+ guint32 flags;
+ guint64 seq;
+ guint64 confounder;
+ guint8 private_type;
+ gboolean can_decrypt;
+ void* private;
+ char* client_name;
+ int start;
+ int next_start;
+ struct _netlogon_auth_vars *next;
+} netlogon_auth_vars;
+
+typedef struct _md4_pass {
+ guint8 md4[16];
+} md4_pass;
+
+typedef struct _seen_packet {
+ gboolean isseen;
+ guint32 num;
+} seen_packet;
+
+static seen_packet seen;
+guint
+netlogon_auth_hash (gconstpointer k);
static e_uuid_t uuid_dcerpc_netlogon = {
0x12345678, 0x1234, 0xabcd,
{ 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0xcf, 0xfb }
@@ -293,6 +473,23 @@ static e_uuid_t uuid_dcerpc_netlogon = {
static guint16 ver_dcerpc_netlogon = 1;
+static gint dissect_dcerpc_8bytes (tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
+ proto_tree *tree, guint8 *drep,
+ int hfindex, guint64 *pdata)
+{
+ guint64 data;
+
+ data = ((drep[0] & 0x10)
+ ? tvb_get_letoh64 (tvb, offset)
+ : tvb_get_ntoh64 (tvb, offset));
+
+ if (tree) {
+ proto_tree_add_item(tree, hfindex, tvb, offset, 8, (drep[0] & 0x10));
+ }
+ if (pdata)
+ *pdata = data;
+ return offset+8;
+}
static const true_false_string user_account_control_dont_require_preauth= {
"This account DOESN'T_REQUIRE_PREAUTHENTICATION",
@@ -362,6 +559,143 @@ static const true_false_string user_account_control_account_disabled= {
"This account is DISABLED",
"This account is NOT disabled",
};
+
+typedef struct _netlogon_auth_key {
+ address src;
+ address dst;
+ guint32 dstport;
+ char * name;
+} netlogon_auth_key;
+
+static gint
+netlogon_auth_equal (gconstpointer k1, gconstpointer k2)
+{
+ const netlogon_auth_key *key1 = (const netlogon_auth_key *)k1;
+ const netlogon_auth_key *key2 = (const netlogon_auth_key *)k2;
+ if(key1->name == NULL || key2->name ==NULL)
+ return ((key1->dstport == key2->dstport) && ADDRESSES_EQUAL(&key1->src,&key2->src) &&
+ ADDRESSES_EQUAL(&key1->dst,&key2->dst));
+ else
+ return ((strcmp(key1->name,key2->name)==0) && ADDRESSES_EQUAL(&key1->src,&key2->src) &&
+ ADDRESSES_EQUAL(&key1->dst,&key2->dst));
+}
+
+guint
+netlogon_auth_hash (gconstpointer k)
+{
+ const netlogon_auth_key *key1 = (const netlogon_auth_key *)k;
+ guint hash_val1;
+ if(key1->name == NULL) {
+ hash_val1 = key1->dstport;
+ }
+ else {
+ unsigned int i = 0;
+ hash_val1 = 0;
+ for(i=0; i<strlen(key1->name);i++) {
+ hash_val1 += key1->name[i];
+ }
+ }
+
+ ADD_ADDRESS_TO_HASH(hash_val1, &key1->src);
+ ADD_ADDRESS_TO_HASH(hash_val1, &key1->dst);
+ return hash_val1;
+}
+static int
+netlogon_dissect_EXTRA_FLAGS(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
+{
+ guint32 mask;
+ proto_item *item = NULL;
+ proto_tree *tree = NULL;
+ dcerpc_info *di;
+
+ di=pinfo->private_data;
+ if(di->conformant_run){
+ /*just a run to handle conformant arrays, nothing to dissect */
+ return offset;
+ }
+
+ offset=dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
+ hf_netlogon_extraflags, &mask);
+
+ if(parent_tree){
+ item = proto_tree_add_uint(parent_tree, hf_netlogon_extraflags,
+ tvb, offset-4, 4, mask);
+ tree = proto_item_add_subtree(item, ett_trust_flags);
+ }
+
+ proto_tree_add_boolean(tree, hf_netlogon_extra_flags_root_forest,
+ tvb, offset-4, 4, mask);
+ proto_tree_add_boolean(tree, hf_netlogon_trust_flags_dc_firsthop,
+ tvb, offset-4, 4, mask);
+ proto_tree_add_boolean(tree, hf_netlogon_trust_flags_rodc_to_dc,
+ tvb, offset-4, 4, mask);
+ proto_tree_add_boolean(tree, hf_netlogon_trust_flags_rodc_ntlm,
+ tvb, offset-4, 4, mask);
+
+ return offset;
+}
+int
+dissect_ndr_lm_nt_hash_cb(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep, int hf_index,
+ dcerpc_callback_fnct_t *callback,
+ void *callback_args)
+{
+ dcerpc_info *di = pinfo->private_data;
+ guint16 len, size;
+
+ /* Structure starts with short, but is aligned for longs */
+
+ ALIGN_TO_4_BYTES;
+
+ if (di->conformant_run)
+ return offset;
+
+ /*
+ struct {
+ short len;
+ short size;
+ [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
+ } HASH;
+
+ */
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_nt_cs_len, &len);
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_nt_cs_size, &size);
+
+ offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, tree, drep,
+ dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
+ "Bytes Array", hf_index, callback, callback_args);
+
+ return offset;
+}
+static int
+dissect_ndr_lm_nt_hash_helper(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep, int hf_index, int levels _U_,
+ gboolean add_subtree)
+{
+ proto_item *item;
+ proto_tree *subtree = tree;
+
+ if (add_subtree) {
+
+ item = proto_tree_add_text(
+ tree, tvb, offset, 0, "%s",
+ proto_registrar_get_name(hf_index));
+
+ subtree = proto_item_add_subtree(item,ett_LM_OWF_PASSWORD);
+ }
+
+ return dissect_ndr_lm_nt_hash_cb(
+ tvb, offset, pinfo, subtree, drep, hf_index,
+ NULL, NULL);
+ /*cb_wstr_postprocess, GINT_TO_POINTER(2 + levels));*/
+}
static int
netlogon_dissect_USER_ACCOUNT_CONTROL(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
@@ -620,6 +954,28 @@ netlogon_dissect_netrlogonuaslogoff_reply(tvbuff_t *tvb, int offset,
return offset;
}
+static int
+netlogon_dissect_BYTE_byte(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep)
+{
+ offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_unknown_char, NULL);
+
+ return offset;
+}
+
+static int
+netlogon_dissect_BYTE_array(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep)
+{
+ offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_BYTE_byte);
+
+ return offset;
+}
+
@@ -659,8 +1015,8 @@ netlogon_dissect_LOGON_IDENTITY_INFO(tvbuff_t *tvb, int offset,
offset = dissect_ndr_duint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_logon_id, NULL);
- offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_acct_name, CB_STR_COL_INFO|3);
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_acct_name, 1);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
hf_netlogon_workstation, 0);
@@ -804,49 +1160,91 @@ netlogon_dissect_CHALLENGE(tvbuff_t *tvb, int offset,
* IDL STRING lmchallengeresponse;
* IDL } NETWORK_INFO;
*/
-
+/*
static void dissect_nt_chal_resp_cb(packet_info *pinfo _U_, proto_tree *tree,
proto_item *item _U_, tvbuff_t *tvb,
int start_offset, int end_offset,
- void *callback_args _U_)
+ void *callback_args )
{
int len;
+ gint options = GPOINTER_TO_INT(callback_args);
+ gint levels = CB_STR_ITEM_LEVELS(options);
+ char *s;
- /* Skip over 3 guint32's in NDR format */
+
+ / * Skip over 3 guint32's in NDR format * /
if (start_offset % 4)
start_offset += 4 - (start_offset % 4);
start_offset += 12;
len = end_offset - start_offset;
-
- /* Call ntlmv2 response dissector */
+
+ s = tvb_bytes_to_str(
+ tvb, start_offset , len );
+
+ / * Append string to upper-level proto_items * /
+
+ if (levels > 0 && item && s && s[0]) {
+ proto_item_append_text(item, ": %s", s);
+ item = item->parent;
+ levels--;
+ if (levels > 0) {
+ proto_item_append_text(item, ": %s", s);
+ item = item->parent;
+ levels--;
+ while (levels > 0) {
+ proto_item_append_text(item, " %s", s);
+ item = item->parent;
+ levels--;
+ }
+ }
+ }
+ / * Call ntlmv2 response dissector * /
if (len > 24)
dissect_ntlmv2_response(tvb, tree, start_offset, len);
}
-
+*/
static int
netlogon_dissect_NETWORK_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
+
offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
pinfo, tree, drep);
-
offset = netlogon_dissect_CHALLENGE(tvb, offset,
pinfo, tree, drep);
+/*
+ offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+ NDR_POINTER_UNIQUE, "NT ",
+ hf_netlogon_nt_owf_password, 0);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_data_length, NULL);*/
+ offset = dissect_ndr_lm_nt_hash_helper(tvb,offset,pinfo, tree, drep, hf_netlogon_lm_chal_resp, 0,TRUE);
+ offset = dissect_ndr_lm_nt_hash_helper(tvb,offset,pinfo, tree, drep, hf_netlogon_lm_chal_resp, 0,TRUE);
+ /* Not really sure that it really works with NTLM v2 ....*/
+ /*
+ offset = netlogon_dissect_LM_OWF_PASSWORD(tvb, offset,
+ pinfo, tree, drep);
- offset = dissect_ndr_counted_byte_array_cb(
+ offset = netlogon_dissect_NT_OWF_PASSWORD(tvb, offset,
+ pinfo, tree, drep);
+*/
+ return offset;
+ /*offset = dissect_ndr_counted_byte_array_cb(
tvb, offset, pinfo, tree, drep, hf_netlogon_nt_chal_resp,
- dissect_nt_chal_resp_cb, NULL);
+ dissect_nt_chal_resp_cb,GINT_TO_POINTER(2));
+ hf_netlogon_nt_chal_resp, 0);
offset = dissect_ndr_counted_byte_array(tvb, offset, pinfo, tree, drep,
hf_netlogon_lm_chal_resp, 0);
- return offset;
+ return offset;*/
}
+
/*
* IDL typedef struct {
* IDL LOGON_IDENTITY_INFO logon_info;
@@ -870,7 +1268,30 @@ netlogon_dissect_SERVICE_INFO(tvbuff_t *tvb, int offset,
return offset;
}
+static int
+netlogon_dissect_GENERIC_INFO(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep)
+{
+ dcerpc_info *di;
+ dcerpc_call_value *dcv;
+ di=pinfo->private_data;
+ dcv = (dcerpc_call_value *)di->call_data;
+
+ offset = netlogon_dissect_LOGON_IDENTITY_INFO(tvb, offset,
+ pinfo, tree, drep);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_package_name, 0|CB_STR_SAVE);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_data_length, NULL);
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_BYTE_array, NDR_POINTER_REF,
+ "Logon Data", -1);
+ return offset;
+}
/*
* IDL typedef [switch_type(short)] union {
* IDL [case(1)][unique] INTERACTIVE_INFO *iinfo;
@@ -887,7 +1308,6 @@ netlogon_dissect_LEVEL(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
hf_netlogon_level16, &level);
-
ALIGN_TO_4_BYTES;
switch(level){
case 1:
@@ -904,9 +1324,27 @@ netlogon_dissect_LEVEL(tvbuff_t *tvb, int offset,
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
"SERVICE_INFO:", -1);
+ case 4:
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_GENERIC_INFO, NDR_POINTER_UNIQUE,
+ "GENERIC_INFO:", -1);
+ break;
+ case 5:
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_INTERACTIVE_INFO, NDR_POINTER_UNIQUE,
+ "INTERACTIVE_TRANSITIVE_INFO:", -1);
+ break;
+ case 6:
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_NETWORK_INFO, NDR_POINTER_UNIQUE,
+ "NETWORK_TRANSITIVE_INFO", -1);
+ break;
+ case 7:
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_SERVICE_INFO, NDR_POINTER_UNIQUE,
+ "SERVICE_TRANSITIVE_INFO", -1);
break;
}
-
return offset;
}
@@ -1164,7 +1602,6 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
- int i;
offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
hf_netlogon_logon_time);
@@ -1217,7 +1654,7 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_num_rids, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
"GROUP_MEMBERSHIP_ARRAY", -1);
@@ -1235,17 +1672,35 @@ netlogon_dissect_VALIDATION_SAM_INFO(tvbuff_t *tvb, int offset,
offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep);
- for(i=0;i<2;i++){
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
- }
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy1_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy2_long, NULL);
+
offset = netlogon_dissect_USER_ACCOUNT_CONTROL(tvb, offset,
pinfo, tree, drep);
- for(i=0;i<7;i++){
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
- }
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy4_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy5_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy6_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy7_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy8_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy9_long, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy10_long, NULL);
return offset;
}
@@ -1289,6 +1744,8 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
+ offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,drep);
+ /*
int i;
offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
@@ -1342,7 +1799,7 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_num_rids, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
"GROUP_MEMBERSHIP_ARRAY", -1);
@@ -1371,11 +1828,11 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_unknown_long, NULL);
}
-
+*/
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_num_other_groups, NULL);
+ hf_netlogon_num_sid, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
"SID_AND_ATTRIBUTES_ARRAY:", -1);
@@ -1383,9 +1840,50 @@ netlogon_dissect_VALIDATION_SAM_INFO2(tvbuff_t *tvb, int offset,
}
+static int
+netlogon_dissect_VALIDATION_SAM_INFO4(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep)
+{
+ offset = netlogon_dissect_VALIDATION_SAM_INFO2(tvb,offset,pinfo,tree,drep);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_logon_dnslogondomainname, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_logon_upn, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string, 0);
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string2, 0);
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string3, 0);
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string4, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string5, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string6, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string7, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string8, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string9, 0);
+
+ offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_dummy_string10, 0);
+ return offset;
+}
/*
* IDL typedef struct {
* IDL uint64 LogonTime;
@@ -1426,8 +1924,9 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
- int i;
guint32 rgc;
+ offset = netlogon_dissect_VALIDATION_SAM_INFO(tvb,offset,pinfo,tree,drep);
+ /*int i;
offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, tree, drep,
hf_netlogon_logon_time);
@@ -1480,7 +1979,7 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_num_rids, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_GROUP_MEMBERSHIP_ARRAY, NDR_POINTER_UNIQUE,
"GROUP_MEMBERSHIP_ARRAY", -1);
@@ -1508,14 +2007,15 @@ netlogon_dissect_PAC_LOGON_INFO(tvbuff_t *tvb, int offset,
for(i=0;i<7;i++){
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_unknown_long, NULL);
- }
+ }*/
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_num_other_groups, NULL);
+ hf_netlogon_num_sid, NULL);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
dissect_ndr_nt_SID_AND_ATTRIBUTES_ARRAY, NDR_POINTER_UNIQUE,
"SID_AND_ATTRIBUTES_ARRAY:", -1);
+
offset = dissect_ndr_nt_PSID(tvb, offset, pinfo, tree, drep);
@@ -1568,7 +2068,7 @@ netlogon_dissect_PAC_CONSTRAINED_DELEGATION(tvbuff_t *tvb, int offset,
return offset;
}
-
+/*
static int
netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
@@ -1579,7 +2079,6 @@ netlogon_dissect_PAC(tvbuff_t *tvb, int offset,
di=pinfo->private_data;
if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect */
return offset;
}
@@ -1603,7 +2102,6 @@ netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
di=pinfo->private_data;
if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect */
return offset;
}
@@ -1616,8 +2114,21 @@ netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
return offset;
}
+*/
+static int
+netlogon_dissect_VALIDATION_GENERIC_INFO2 (tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep)
+{
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_data_length, NULL);
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_BYTE_array, NDR_POINTER_REF,
+ "Validation Data", -1);
+ return offset;
+}
/*
* IDL typedef struct {
* IDL long pac_size
@@ -1637,6 +2148,7 @@ netlogon_dissect_AUTH(tvbuff_t *tvb, int offset,
* IDL UNICODESTRING dummy4;
* IDL } VALIDATION_PAC_INFO;
*/
+/* Not used (anymore ?)
static int
netlogon_dissect_VALIDATION_PAC_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
@@ -1694,14 +2206,16 @@ netlogon_dissect_VALIDATION_PAC_INFO(tvbuff_t *tvb, int offset,
return offset;
}
-
-
+*/
/*
* IDL typedef [switch_type(short)] union {
+ * IDL [case(1)][unique] VALIDATION_UAS *uas;
* IDL [case(2)][unique] VALIDATION_SAM_INFO *sam;
* IDL [case(3)][unique] VALIDATION_SAM_INFO2 *sam2;
- * IDL [case(4)][unique] VALIDATION_PAC_INFO *pac;
- * IDL [case(5)][unique] VALIDATION_PAC_INFO *pac2;
+ * IDL [case(4)][unique] VALIDATION_GENERIC_INFO *generic;
+ * IDL [case(5)][unique] VALIDATION_GENERIC_INFO *generic2;
+ * IDL [case(5)][unique] VALIDATION_GENERIC_INFO *generic2;
+ * IDL [case(6)][unique] VALIDATION_SAM_INFO4 *sam4;
* IDL } VALIDATION;
*/
static int
@@ -1716,6 +2230,11 @@ netlogon_dissect_VALIDATION(tvbuff_t *tvb, int offset,
ALIGN_TO_4_BYTES;
switch(level){
+ case 1:
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_VALIDATION_UAS_INFO, NDR_POINTER_UNIQUE,
+ "VALIDATION_UAS_INFO:", -1);
+ break;
case 2:
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_VALIDATION_SAM_INFO, NDR_POINTER_UNIQUE,
@@ -1728,19 +2247,94 @@ netlogon_dissect_VALIDATION(tvbuff_t *tvb, int offset,
break;
case 4:
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_VALIDATION_PAC_INFO, NDR_POINTER_UNIQUE,
- "VALIDATION_PAC_INFO:", -1);
+ netlogon_dissect_VALIDATION_GENERIC_INFO2, NDR_POINTER_UNIQUE,
+ "VALIDATION_INFO:", -1);
break;
case 5:
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_VALIDATION_PAC_INFO, NDR_POINTER_UNIQUE,
- "VALIDATION_PAC_INFO:", -1);
+ netlogon_dissect_VALIDATION_GENERIC_INFO2, NDR_POINTER_UNIQUE,
+ "VALIDATION_INFO2:", -1);
+ break;
+ case 6:
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_VALIDATION_SAM_INFO4, NDR_POINTER_UNIQUE,
+ "VALIDATION_SAM_INFO4:", -1);
break;
}
+ return offset;
+}
+/*
+ * IDL long NetrLogonSamLogonWithFlags(
+ * IDL [in][unique][string] wchar_t *ServerName,
+ * IDL [in][unique][string] wchar_t *Workstation,
+ * IDL [in][unique] AUTHENTICATOR *credential,
+ * IDL [in][out][unique] AUTHENTICATOR *returnauthenticator,
+ * IDL [in] short LogonLevel,
+ * IDL [in][ref] LOGON_LEVEL *logonlevel,
+ * IDL [in] short ValidationLevel,
+ * IDL [out][ref] VALIDATION *validation,
+ * IDL [out][ref] boolean Authorative
+ * IDL [in][out] unsigned long ExtraFlags
+ * IDL );
+ */
+static int
+netlogon_dissect_netrlogonsamlogonflags_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
+ pinfo, tree, drep);
+
+ offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+ NDR_POINTER_UNIQUE, "Computer Name",
+ hf_netlogon_computer_name, 0);
+
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
+ "AUTHENTICATOR: credential", -1);
+
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
+ "AUTHENTICATOR: return_authenticator", -1);
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_level16, NULL);
+
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_LEVEL, NDR_POINTER_REF,
+ "LEVEL: LogonLevel", -1);
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_validation_level, NULL);
+
+ offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
return offset;
}
+static int
+netlogon_dissect_netrlogonsamlogonflags_reply(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_AUTHENTICATOR, NDR_POINTER_UNIQUE,
+ "AUTHENTICATOR: return_authenticator", -1);
+
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_VALIDATION, NDR_POINTER_REF,
+ "VALIDATION:", -1);
+
+ offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_authoritative, NULL);
+
+ offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_rc, NULL);
+
+ return offset;
+}
+
+
/*
* IDL long NetrLogonSamLogon(
@@ -1862,6 +2456,24 @@ netlogon_dissect_netrlogonsamlogoff_reply(tvbuff_t *tvb, int offset,
return offset;
}
+static void generate_hash_key(packet_info *pinfo,unsigned char is_server,netlogon_auth_key *key,char* name)
+{
+ if(is_server) {
+ key->dstport = pinfo->srcport;
+ COPY_ADDRESS(&key->dst,&pinfo->src);
+ COPY_ADDRESS(&key->src,&pinfo->dst);
+ /* name has been durably allocated */
+ key->name = name;
+ }
+ else {
+ COPY_ADDRESS(&key->dst,&pinfo->dst);
+ COPY_ADDRESS(&key->src,&pinfo->src);
+ key->dstport = pinfo->destport;
+ /* name has been durably allocated */
+ key->name = name;
+ }
+
+}
/*
* IDL long NetrServerReqChallenge(
@@ -1875,33 +2487,126 @@ static int
netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
+ /*int oldoffset = offset;*/
+ int txt_len = 0;
+ netlogon_auth_vars *vars;
+ netlogon_auth_vars *existing_vars;
+ netlogon_auth_key *key = se_alloc(sizeof(netlogon_auth_key));
+ guint8 tab[8] = { 0,0,0,0,0,0,0,0};
+ dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
+ dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
+
+ /* As we are not always keeping this it could be more intelligent to g_malloc it
+ and if we decide to keep it then transform it into se_alloc */
+ vars = se_alloc(sizeof(netlogon_auth_vars));
offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
pinfo, tree, drep);
-
offset = dissect_ndr_pointer_cb(
tvb, offset, pinfo, tree, drep,
dissect_ndr_wchar_cvstring, NDR_POINTER_REF,
"Computer Name", hf_netlogon_computer_name,
cb_wstr_postprocess,
- GINT_TO_POINTER(CB_STR_COL_INFO | 1));
-
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
- "CREDENTIAL: client challenge", -1);
-
+ GINT_TO_POINTER(CB_STR_COL_INFO |CB_STR_SAVE | 1));
+
+ txt_len = strlen(dcv->private_data);
+ debugprintf("1)Len %d offset %d txt %s\n",txt_len,offset,(char*)dcv->private_data);
+ vars->client_name = se_alloc(txt_len+1);
+ memcpy(vars->client_name,dcv->private_data,txt_len+1);
+ vars->client_name[txt_len] = '\0';
+ debugprintf("2)Len %d offset %d txt %s\n",txt_len,offset,vars->client_name);
+
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
+ hf_client_challenge,&vars->client_challenge);
+ memcpy(tab,&vars->client_challenge,8);
+
+ vars->start = pinfo->fd->num;
+ vars->next_start = -1;
+ vars->next = NULL;
+
+ generate_hash_key(pinfo,0,key,NULL);
+ existing_vars = NULL;
+ existing_vars = g_hash_table_lookup(netlogon_auths, key);
+ if (!existing_vars) {
+ g_hash_table_insert(netlogon_auths,(gconstpointer*) key,vars);
+ }
+ else {
+ while(existing_vars->next != NULL && existing_vars->start <= vars->start) {
+ existing_vars = existing_vars->next;
+ }
+ if(existing_vars->next != NULL || existing_vars == vars) {
+ debugprintf("It seems that I already record this vars %d\n",vars->start);
+ }
+ else {
+ existing_vars->next_start = pinfo->fd->num;
+ existing_vars->next = vars;
+ }
+ }
+ /* used by other rpc that use schannel ie lsa */
+ /*
+ generate_hash_key(pinfo,0,key,vars->client_name);
+ existing_vars = NULL;
+ existing_vars = g_hash_table_lookup(schannel_auths, key);
+ if (!existing_vars)
+ {
+ g_hash_table_insert(schannel_auths,(gconstpointer*) key,vars);
+ }
+ else
+ {
+ while(existing_vars->next != NULL && existing_vars->start <= vars->start) {
+ existing_vars = existing_vars->next;
+ }
+ if(existing_vars->next != NULL || existing_vars == vars) {
+ debugprintf("It seems that I already record this vars (schannel hash)%d\n",vars->start);
+ }
+ else {
+ existing_vars->next_start = pinfo->fd->num;
+ existing_vars->next = vars;
+ }
+ }
+ */
return offset;
}
+
static int
netlogon_dissect_netrserverreqchallenge_reply(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_auth_vars *vars;
+ netlogon_auth_key key;
+ guint64 server_challenge;
+
+ generate_hash_key(pinfo,1,&key,NULL);
+ vars = g_hash_table_lookup(netlogon_auths,(gconstpointer*) &key);
+
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
+ hf_server_challenge, &server_challenge);
+ /*offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
- "CREDENTIAL: server credential", -1);
+ "CREDENTIAL: server credential", -1);*/
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
hf_netlogon_rc, NULL);
-
+ if(vars != NULL) {
+ while(vars !=NULL && vars->next_start != -1 && vars->next_start < (int)pinfo->fd->num )
+ {
+ vars = vars->next;
+ debugprintf("looping challenge reply... %d %d \n",vars->next_start,pinfo->fd->num);
+ }
+ if(vars == NULL)
+ {
+ debugprintf("Something strange happened while searching for challenge_reply\n");
+ }
+ else
+ {
+ vars->server_challenge = server_challenge;
+ }
+ }
+/*
+ else
+ {
+ debugprintf("Vars not found in challenge reply\n");
+ }
+*/
return offset;
}
@@ -3765,28 +4470,6 @@ netlogon_dissect_UAS_INFO_0(tvbuff_t *tvb, int offset,
}
-static int
-netlogon_dissect_BYTE_byte(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- guint8 *drep)
-{
- offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_char, NULL);
-
- return offset;
-}
-
-static int
-netlogon_dissect_BYTE_array(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- guint8 *drep)
-{
- offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_BYTE_byte);
-
- return offset;
-}
-
/*
* IDL long NetrAccountDeltas(
* IDL [in][string][unique] wchar_t *logonserver,
@@ -4510,10 +5193,10 @@ netlogon_dissect_netrlogoncontrol2ex_reply(tvbuff_t *tvb, int offset,
static const value_string trust_type_vals[] = {
- { 1, "DOWNLEVEL" },
- { 2, "UPLEVEL" },
- { 3, "MIT" },
- { 4, "DCE" },
+ { 1, "NT4 Domain" },
+ { 2, "AD Domain" },
+ { 3, "MIT Kerberos realm" },
+ { 4, "DCE realm" },
{ 0, NULL }
};
@@ -4526,6 +5209,11 @@ static const value_string dc_address_types[] = {
};
+#define RQ_ROOT_FOREST 0x0001
+#define RQ_DC_XFOREST 0x0002
+#define RQ_RODC_DIF_DOMAIN 0x0004
+#define RQ_NTLM_FROM_RODC 0x0008
+
#define DS_DOMAIN_IN_FOREST 0x0001
#define DS_DOMAIN_DIRECT_OUTBOUND 0x0002
#define DS_DOMAIN_TREE_ROOT 0x0004
@@ -4556,6 +5244,8 @@ static const true_false_string trust_tree_root = {
"The domain is the ROOT of a domain TREE",
"The domain is NOT a root of a domain tree"
};
+
+
static int
netlogon_dissect_DOMAIN_TRUST_FLAGS(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *parent_tree, guint8 *drep)
@@ -4953,7 +5643,7 @@ netlogon_dissect_pointer_long(tvbuff_t *tvb, int offset,
di->hf_index, NULL);
return offset;
}
-
+/*
static int
netlogon_dissect_pointer_char(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
@@ -4966,7 +5656,7 @@ netlogon_dissect_pointer_char(tvbuff_t *tvb, int offset,
di->hf_index, NULL);
return offset;
}
-
+*/
static int
netlogon_dissect_UNICODE_MULTI_byte(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
@@ -5061,6 +5751,45 @@ netlogon_dissect_DOMAIN_CONTROLLER_INFO(tvbuff_t *tvb, int offset,
return offset;
}
+
+
+static int
+dissect_ndr_trust_extension(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep)
+{
+ guint32 len,max;
+ dcerpc_info *di;
+
+ di=pinfo->private_data;
+ if(di->conformant_run){
+ return offset;
+ }
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_trust_max, &max);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_trust_offset, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_trust_len, &len);
+
+ if( max * 2 == 16 ) {
+ offset = netlogon_dissect_DOMAIN_TRUST_FLAGS(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_trust_parent_index, NULL);
+
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_trust_type, NULL);
+
+ offset = netlogon_dissect_DOMAIN_TRUST_ATTRIBS(tvb, offset, pinfo, tree, drep);
+ }
+ /* else do something scream shout .... */
+
+ return offset;
+}
+
static int
netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
@@ -5071,7 +5800,6 @@ netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
di=pinfo->private_data;
if(di->conformant_run){
- /*just a run to handle conformant arrays, nothing to dissect.*/
return offset;
}
@@ -5084,33 +5812,96 @@ netlogon_dissect_BLOB_array(tvbuff_t *tvb, int offset,
return offset;
}
+int
+dissect_ndr_ulongs_as_counted_string(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree,
+ guint8 *drep, int hf_index)
+{
+ dcerpc_info *di = pinfo->private_data;
+ guint16 len, size;
+ gboolean add_subtree = TRUE; /* Manage room for evolution*/
+ proto_item *item;
+ proto_tree *subtree = tree;
+
+ if (add_subtree) {
+
+ item = proto_tree_add_text(
+ tree, tvb, offset, 0, "%s",
+ proto_registrar_get_name(hf_index));
+
+ subtree = proto_item_add_subtree(item, ett_nt_counted_longs_as_string);
+ }
+ /* Structure starts with short, but is aligned for longs */
+ ALIGN_TO_4_BYTES;
+
+ if (di->conformant_run)
+ return offset;
+
+ /*
+ struct {
+ short len;
+ short size;
+ [size_is(size/2), length_is(len/2), ptr] unsigned short *string;
+ } UNICODE_STRING;
+
+ */
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, drep,
+ hf_nt_cs_len, &len);
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, drep,
+ hf_nt_cs_size, &size);
+ offset = dissect_ndr_pointer_cb(tvb, offset, pinfo, subtree, drep,
+ dissect_ndr_trust_extension, NDR_POINTER_UNIQUE,
+ "Buffer", hf_index,NULL,NULL);
+ return offset;
+}
+
+extern int
+lsarpc_dissect_struct_dom_sid2(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_, int unused1 _U_, int unused2 _U_);
static int
-netlogon_dissect_BLOB(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *parent_tree,
- guint8 *drep)
+DomainInfo_sid_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)
{
- proto_item *item=NULL;
- proto_tree *tree=NULL;
+ offset = lsarpc_dissect_struct_dom_sid2(tvb,offset,pinfo,tree,drep,DomainInfo_sid,0);
- if(parent_tree){
- item = proto_tree_add_text(parent_tree, tvb, offset, 0,
- "BLOB:");
- tree = proto_item_add_subtree(item, ett_BLOB);
- }
+ return offset;
+}
+static int
+dissect_element_lsa_DnsDomainInfo_sid(tvbuff_t *tvb , int offset , packet_info *pinfo , proto_tree *tree , guint8 *drep )
+{
+ offset = dissect_ndr_embedded_pointer(tvb, offset, pinfo, tree, drep, DomainInfo_sid_, NDR_POINTER_UNIQUE, "Pointer to Sid (dom_sid2)",DnsDomainInfo_sid);
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_blob_size, NULL);
+ return offset;
+}
+static int
+dissect_element_lsa_DnsDomainInfo_domain_guid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep )
+{
+ offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, drep, DnsDomainInfo_domain_guid, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_BLOB_array, NDR_POINTER_UNIQUE,
- "BLOB:", -1);
+ return offset;
+}
- return offset;
+
+static int dissect_part_DnsDomainInfo(tvbuff_t *tvb , int offset, packet_info *pinfo, proto_tree *tree , guint8 *drep, int hf_index _U_, guint32 param _U_)
+{
+
+ offset = lsarpc_dissect_struct_lsa_StringLarge(tvb,offset,pinfo,tree,drep,DnsDomainInfo_name,0);
+
+ offset = lsarpc_dissect_struct_lsa_StringLarge(tvb,offset,pinfo,tree,drep,DnsDomainInfo_dns_domain,0);
+
+ offset = lsarpc_dissect_struct_lsa_StringLarge(tvb,offset,pinfo,tree,drep,DnsDomainInfo_dns_forest,0);
+
+ offset = dissect_element_lsa_DnsDomainInfo_domain_guid(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_element_lsa_DnsDomainInfo_sid(tvb, offset, pinfo, tree, drep);
+
+
+ return offset;
}
+
static int
-netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
+netlogon_dissect_ONE_DOMAIN_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *parent_tree,
guint8 *drep)
{
@@ -5120,62 +5911,100 @@ netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
if(parent_tree){
item = proto_tree_add_text(parent_tree, tvb, offset, 0,
- "DOMAIN_TRUST_INFO:");
+ "ONE_DOMAIN_INFO");
tree = proto_item_add_subtree(item, ett_DOMAIN_TRUST_INFO);
}
+/*hf_netlogon_dnsdomaininfo*/
+ offset = dissect_part_DnsDomainInfo(tvb, offset, pinfo, tree, drep, 0, 0);
- offset = lsarpc_dissect_struct_lsa_DnsDomainInfo(tvb, offset, pinfo, tree, drep, hf_netlogon_dnsdomaininfo, 0);
-
-
- /* Guesses at best. */
- offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ /* It is structed as a string but it's not ... it's 4 ulong */
+ offset = dissect_ndr_ulongs_as_counted_string(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_trust_extention);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string2, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string3, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string4, 0);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy1_long, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy2_long, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy3_long, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy4_long, NULL);
proto_item_set_len(item, offset-old_offset);
return offset;
}
static int
-netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY(tvbuff_t *tvb, int offset,
+netlogon_dissect_DOMAIN_TRUST_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_TRUST_INFO);
+ netlogon_dissect_ONE_DOMAIN_INFO);
return offset;
}
+
static int
-netlogon_dissect_DOMAIN_QUERY_1(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- guint8 *drep)
+netlogon_dissect_LSA_POLICY_INFO(tvbuff_t *tvb _U_, int offset,
+ packet_info *pinfo _U_, proto_tree *tree _U_,
+ guint8 *drep _U_ )
{
- offset = netlogon_dissect_BLOB(tvb, offset,
- pinfo, tree, drep);
+ proto_item *item=NULL;
+ proto_tree *subtree=NULL;
+ guint32 len;
+ dcerpc_info *di;
+
+ di=pinfo->private_data;
+ if(di->conformant_run){
+ return offset;
+ }
+ if(tree){
+ item = proto_tree_add_text(tree, tvb, offset, 0,
+ "LSA Policy");
+ subtree = proto_item_add_subtree(item, ett_LSA_POLICY_INFO);
+ }
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, drep,
+ hf_netlogon_lsapolicy_len, &len);
+
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, subtree, drep,
+ netlogon_dissect_BLOB_array, NDR_POINTER_UNIQUE,
+ "Pointer:", -1);
+
+ return offset;
+}
+
+
+
+
+static int
+netlogon_dissect_WORKSTATION_INFO(tvbuff_t *tvb , int offset ,
+ packet_info *pinfo , proto_tree *tree ,
+ guint8 *drep )
+{
+ /* This is not the good way to do it ... it stinks ...
+ * but after half of a day fighting against wireshark and ndr ...
+ * I decided to keep this hack ...
+ * At least data are correctly displayed without invented ints ...
+ */
+ offset = netlogon_dissect_LSA_POLICY_INFO(tvb, offset,
+ pinfo, tree, drep);
+
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
NDR_POINTER_UNIQUE, "Workstation FQDN",
hf_netlogon_workstation_fqdn, 0);
@@ -5185,96 +6014,106 @@ netlogon_dissect_DOMAIN_QUERY_1(tvbuff_t *tvb, int offset,
hf_netlogon_workstation_site_name, 0);
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
- NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
-
- offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
- NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
+ NDR_POINTER_UNIQUE, "Dummy 1", hf_netlogon_dummy_string, 0);
+
+ offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+ NDR_POINTER_UNIQUE, "Dummy 2", hf_netlogon_dummy_string2, 0);
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
- NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
+ NDR_POINTER_UNIQUE, "Dummy 3", hf_netlogon_dummy_string3, 0);
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
- NDR_POINTER_UNIQUE, "unknown", hf_netlogon_unknown_string, 0);
+ NDR_POINTER_UNIQUE, "Dummy 4", hf_netlogon_dummy_string4, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_os_version, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
hf_netlogon_workstation_os, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string3, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string4, 0);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_workstation_flags, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy2_long, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy3_long, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
-
- return offset;
+ hf_netlogon_dummy4_long, NULL);
+ return offset;
}
+static int
+netlogon_dissect_WORKSTATION_INFORMATION(tvbuff_t *tvb , int offset ,
+ packet_info *pinfo , proto_tree *tree ,
+ guint8 *drep ) {
+
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_WORKSTATION_INFO, NDR_POINTER_UNIQUE,
+ "WORKSTATION INFO", -1);
+ return offset;
+}
static int
-netlogon_dissect_DOMAIN_INFO_1(tvbuff_t *tvb, int offset,
+netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
- offset = netlogon_dissect_DOMAIN_TRUST_INFO(tvb, offset, pinfo, tree, drep);
+ offset = netlogon_dissect_ONE_DOMAIN_INFO(tvb, offset, pinfo, tree, drep);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_num_trusts, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY, NDR_POINTER_UNIQUE,
- "DOMAIN_TRUST_ARRAY: Trusts", -1);
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_DOMAIN_TRUST_INFO, NDR_POINTER_UNIQUE,
+ "DOMAIN_TRUST_ARRAY: Trusted domains", -1);
+
+ offset = netlogon_dissect_LSA_POLICY_INFO(tvb,offset,pinfo, tree,drep);
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+/* offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_num_trusts, NULL);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_TRUST_INFO_ARRAY, NDR_POINTER_UNIQUE,
- "DOMAIN_TRUST_ARRAY:", -1);
-
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_DOMAIN_TRUST_INFO, NDR_POINTER_UNIQUE,
+ "LSA Policy", -1);
+*/
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_dns_domain_name, 0);
+ hf_netlogon_ad_client_dns_name, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string2, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string3, 0);
offset = dissect_ndr_counted_string(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_string, 0);
+ hf_netlogon_dummy_string4, 0);
- /* These four integers appear to mirror the last four in the query. */
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_workstation_flags, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_supportedenctypes, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy3_long, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ hf_netlogon_dummy4_long, NULL);
return offset;
}
static int
-netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
+netlogon_dissect_DOMAIN_INFORMATION(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
@@ -5287,8 +6126,8 @@ netlogon_dissect_DOMAIN_INFO(tvbuff_t *tvb, int offset,
switch(level){
case 1:
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_INFO_1, NDR_POINTER_UNIQUE,
- "DOMAIN_INFO_1:", -1);
+ netlogon_dissect_DOMAIN_INFO, NDR_POINTER_UNIQUE,
+ "DOMAIN_INFO", -1);
break;
}
@@ -5556,8 +6395,8 @@ netlogon_dissect_TYPE_44(tvbuff_t *tvb, int offset,
return offset;
}
-static int
-netlogon_dissect_DOMAIN_QUERY(tvbuff_t *tvb, int offset,
+ static int
+netlogon_dissect_WORKSTATION_BUFFER(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree,
guint8 *drep)
{
@@ -5565,21 +6404,22 @@ netlogon_dissect_DOMAIN_QUERY(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_netlogon_level, &level);
-
- ALIGN_TO_4_BYTES;
- switch(level){
- case 1:
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_QUERY_1, NDR_POINTER_UNIQUE,
- "DOMAIN_QUERY_1:", -1);
- break;
- case 2:
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_QUERY_1, NDR_POINTER_UNIQUE,
- "DOMAIN_QUERY_1:", -1);
- break;
- }
-
+ if( level == 2 ) {
+ /* Specs are not very clear (as usual ...) it seems that the
+ * structure in both case is a NETLOGON_WORKSTATION_INFO
+ * but in this case only the LSA POLICY INFO will contain
+ * something
+ */
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_WORKSTATION_INFORMATION, NDR_POINTER_UNIQUE,
+ "LSA POLICY INFO", -1);
+ }
+ else {
+ if ( level == 1) {
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_WORKSTATION_INFORMATION, NDR_POINTER_UNIQUE,
+ "WORKSTATION INFORMATION", -1);}
+ }
return offset;
}
@@ -5832,14 +6672,123 @@ netlogon_dissect_netrlogoncomputeclientdigest_reply(tvbuff_t *tvb, int offset,
return offset;
}
-
+static int netlogon_dissect_neg_options(tvbuff_t *tvb,proto_tree *tree,guint32 flags,int offset)
+{
+ if (tree) {
+ proto_tree *negotiate_flags_tree = NULL;
+ proto_item *tf = NULL;
+ tf = proto_tree_add_uint (tree,
+ hf_netlogon_neg_flags,
+ tvb, offset, 4,flags);
+ negotiate_flags_tree = proto_item_add_subtree (tf,ett_authenticate_flags);
+
+ /*proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_80000000,
+ tvb, offset, 4, flags);*/
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_40000000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_20000000,
+ tvb, offset, 4, flags);
+ /*
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_10000000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_8000000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_4000000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_2000000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_1000000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_800000,
+ tvb, offset, 4, flags);*/
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_400000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_200000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_100000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_80000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_40000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_20000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_10000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_8000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_4000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_2000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_1000,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_800,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_400,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_200,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_100,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_80,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_40,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_20,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_10,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_8,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_4,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_2,
+ tvb, offset, 4, flags);
+ proto_tree_add_boolean (negotiate_flags_tree,
+ hf_netlogon_neg_flags_1,
+ tvb, offset, 4, flags);
+ }
+ return 0;
+}
static int
netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
+ guint32 flags;
offset = netlogon_dissect_LOGONSRV_HANDLE(tvb, offset,
pinfo, tree, drep);
-
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
NDR_POINTER_REF, "Acct Name", hf_netlogon_acct_name, 0);
@@ -5849,35 +6798,151 @@ netlogon_dissect_netrserverauthenticate3_rqst(tvbuff_t *tvb, int offset,
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
NDR_POINTER_REF, "Computer Name", hf_netlogon_computer_name, 0);
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
+ hf_client_credential, NULL);
+ /*
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
- "CREDENTIAL: authenticator", -1);
+ "Client Challenge", -1);*/
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_neg_flags, NULL);
+ /*offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_neg_flags, NULL);*/
+ ALIGN_TO_4_BYTES;
+ flags = tvb_get_letohl (tvb, offset);
+ netlogon_dissect_neg_options(tvb,tree,flags,offset);
+ seen.isseen = FALSE;
+ seen.num = 0;
+ offset +=4;
return offset;
}
+static guint32 get_keytab_as_list(md4_pass **p_pass_list)
+{
+ enc_key_t *ek;
+ md4_pass* pass_list;
+ int i = 0;
+ guint32 nb_pass = 0;
+
+ if(!krb_decrypt){
+ pass_list=NULL;
+ return 0;
+ }
+ read_keytab_file_from_preferences();
+
+ for(ek=enc_key_list;ek;ek=ek->next){
+ if( ek->keylength == 16 ) {
+ nb_pass++;
+ }
+ }
+ *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
+ pass_list=*p_pass_list;
+
+ for(ek=enc_key_list;ek;ek=ek->next){
+ /*debugprintf("Type %x, len %d, orig: %s\n",ek->keytype,ek->keylength,ek->key_origin);*/
+ if( ek->keylength == 16 ) {
+ memcpy(pass_list[i].md4,ek->keyvalue,16);
+ i++;
+ }
+ }
+ return nb_pass;
+
+}
static int
netlogon_dissect_netrserverauthenticate3_reply(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_CREDENTIAL, NDR_POINTER_REF,
- "CREDENTIAL pointer: unknown_NETLOGON_CREDENTIAL", -1);
+ guint32 flags;
+ netlogon_auth_vars *vars;
+ netlogon_auth_key key;
+ guint64 server_cred;
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_neg_flags, NULL);
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
+ hf_server_credential, &server_cred);
- offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_pointer_long, NDR_POINTER_REF,
- "ULONG: unknown_ULONG", hf_netlogon_unknown_long);
+ flags = tvb_get_letohl (tvb, offset);
+ netlogon_dissect_neg_options(tvb,tree,flags,offset);
+ offset +=4;
+
+ ALIGN_TO_4_BYTES;
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_server_rid, NULL);
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
hf_netlogon_rc, NULL);
+ generate_hash_key(pinfo,1,&key,NULL);
+
+ vars = g_hash_table_lookup(netlogon_auths, &key);
+ if(vars != NULL) {
+ while(vars != NULL && vars->next_start != -1 && vars->next_start < (int) pinfo->fd->num ) {
+ debugprintf("looping auth reply...\n");
+ vars = vars->next;
+ }
+ if(vars == NULL ) {
+ debugprintf("Something strange happened while searching for authenticate_reply\n");
+ }
+ else {
+ md4_pass *pass_list=NULL;
+ guint32 list_size = 0;
+ guint8 session_key[16];
+ md4_pass password;
+ int found = 0;
+ unsigned int i = 0;
+
+ vars->flags = flags;
+ vars->can_decrypt = FALSE;
+ list_size = get_keytab_as_list(&pass_list);
+ debugprintf("Found %d passwords \n",list_size);
+ if( flags & NETLOGON_FLAG_STRONGKEY ) {
+ guint8 zeros[4];
+ guint8 md5[16];
+ md5_state_t md5state;
+ guint8 buf[8];
+ guint64 calculated_cred;
+
+
+ memset(zeros,0,4);
+ md5_init(&md5state);
+ md5_append(&md5state,zeros,4);
+ md5_append(&md5state,(unsigned char*)&vars->client_challenge,8);
+ md5_append(&md5state,(unsigned char*)&vars->server_challenge,8);
+ md5_finish(&md5state,md5);
+ /*printnbyte(md5,8,"MD5:","\n");*/
+ printnbyte((guint8*)&server_cred,8,"Server creds:","\n");
+ for(i=0;i<list_size;i++)
+ {
+ password = pass_list[i];
+ md5_hmac(md5,16,(guint8*) &password,16,session_key);
+ crypt_des_ecb(buf,(unsigned char*)&vars->server_challenge,session_key,1);
+ crypt_des_ecb((unsigned char*)&calculated_cred,buf,session_key+7,1);
+ /*printnbyte((guint8*)&calculated_cred,8,"Calculated creds:","\n");*/
+ if(calculated_cred==server_cred) {
+ found = 1;
+ break;
+ }
+ }
+ }
+ else if( flags&NETLOGON_FLAG_USEAES)
+ {
+ /*Not implemented*/
+ memset(session_key,0,16);
+ }
+ else
+ {
+ /*Not implemented*/
+ memset(session_key,0,16);
+ }
+ if(found) {
+ memcpy(&vars->session_key,session_key,16);
+ debugprintf("Found the good session key !\n");
+ }
+ else {
+ memset(&vars->session_key,0,16);
+ }
+ }
+ }
return offset;
}
@@ -5953,28 +7018,22 @@ netlogon_dissect_netrlogongetdomaininfo_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
/* Unlike the other NETLOGON RPCs, this is not a unique pointer. */
- offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
- NDR_POINTER_REF, "Server Handle", hf_netlogon_computer_name, 0);
-
+ offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+ NDR_POINTER_REF, "Server Handle", hf_netlogon_computer_name, 0);
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
NDR_POINTER_UNIQUE, "Computer Name",
hf_netlogon_computer_name, 0);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
- "AUTHENTICATOR: credential", -1);
-
- offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
- hf_netlogon_unknown_long, NULL);
+ "AUTHENTICATOR: client", -1);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_AUTHENTICATOR, NDR_POINTER_REF,
"AUTHENTICATOR: return_authenticator", -1);
-
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_QUERY, NDR_POINTER_REF,
- "DOMAIN_QUERY: ", -1);
-
+ netlogon_dissect_WORKSTATION_BUFFER, NDR_POINTER_REF,
+ "WORKSTATION_BUFFER", -1);
return offset;
}
@@ -5988,8 +7047,8 @@ netlogon_dissect_netrlogongetdomaininfo_reply(tvbuff_t *tvb, int offset,
"AUTHENTICATOR: return_authenticator", -1);
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
- netlogon_dissect_DOMAIN_INFO, NDR_POINTER_REF,
- "DOMAIN_INFO: ", -1);
+ netlogon_dissect_DOMAIN_INFORMATION, NDR_POINTER_REF,
+ "DOMAIN_INFORMATION", -1);
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
hf_netlogon_rc, NULL);
@@ -6355,7 +7414,26 @@ static int
netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
+
offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+ NDR_POINTER_UNIQUE, "LogonServer",
+ hf_netlogon_computer_name, 0);
+ offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
+ NDR_POINTER_UNIQUE, "Computer Name",
+ hf_netlogon_computer_name, 0);
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_level16, NULL);
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_LEVEL, NDR_POINTER_REF,
+ "LEVEL: LogonLevel", -1);
+
+ offset = dissect_ndr_uint16(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_validation_level, NULL);
+
+ offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+/*
+ offset = dissect_ndr_str_pointer_item(tvb, offset, pinfo, tree, drep,
NDR_POINTER_UNIQUE, "unknown string",
hf_netlogon_unknown_string, 0);
@@ -6375,7 +7453,7 @@ netlogon_dissect_netrlogonsamlogonex_rqst(tvbuff_t *tvb, int offset,
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_pointer_long, NDR_POINTER_UNIQUE,
- "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);
+ "ULONG pointer: unknown_ULONG", hf_netlogon_unknown_long);*/
return offset;
}
@@ -6385,6 +7463,18 @@ netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t *tvb, int offset,
packet_info *pinfo, proto_tree *tree, guint8 *drep)
{
offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_VALIDATION, NDR_POINTER_REF,
+ "VALIDATION:", -1);
+
+ offset = dissect_ndr_uint8(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_authoritative, NULL);
+
+ offset = netlogon_dissect_EXTRA_FLAGS(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
+ hf_netlogon_rc, NULL);
+/*
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
netlogon_dissect_VALIDATION, NDR_POINTER_UNIQUE,
"VALIDATION: unknown_NETLOGON_VALIDATION", -1);
@@ -6398,7 +7488,7 @@ netlogon_dissect_netrlogonsamlogonex_reply(tvbuff_t *tvb, int offset,
offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
hf_netlogon_rc, NULL);
-
+*/
return offset;
}
@@ -6696,54 +7786,225 @@ static dcerpc_sub_dissector dcerpc_netlogon_dissectors[] = {
{ NETLOGON_NETRGETFORESTTRUSTINFORMATION, "NetrGetForestTrustInformation",
NULL, NULL },
{ NETLOGON_NETRLOGONSAMLOGONWITHFLAGS, "NetrLogonSamLogonWithFlags",
- NULL, NULL },
+ netlogon_dissect_netrlogonsamlogonflags_rqst,
+ netlogon_dissect_netrlogonsamlogonflags_reply },
{ NETLOGON_NETRSERVERGETTRUSTINFO, "NetrServerGetTrustInfo",
NULL, NULL },
{0, NULL, NULL, NULL }
};
static int hf_netlogon_secchan_verf = -1;
-static int hf_netlogon_secchan_verf_sig = -1;
+static int hf_netlogon_secchan_verf_sigalg = -1;
+static int hf_netlogon_secchan_verf_sealalg = -1;
+static int hf_netlogon_secchan_verf_pad = -1;
+static int hf_netlogon_secchan_verf_flag = -1;
static int hf_netlogon_secchan_verf_digest = -1;
static int hf_netlogon_secchan_verf_seq = -1;
static int hf_netlogon_secchan_verf_nonce = -1;
+static int get_seal_key(const guint8 *session_key,int key_len,guint64 sequence,guint8* seal_key)
+{
+ guint8 zeros[4];
+ guint8 *buf = g_malloc(key_len);
+ guint8 buf2[16];
+ guint8 zero_sk[16];
+ int i = 0;
+ memset(zero_sk,0,16);
+ memset(seal_key,0,16);
+ if(memcmp(session_key,zero_sk,16)) {
+ memset(zeros,0,4);
+ for(i=0;i<key_len;i++) {
+ buf[i] = session_key[i] ^ 0xF0;
+ }
+ md5_hmac(zeros,4,buf,key_len,buf2);
+ md5_hmac((guint8*)&sequence,8,buf2,16,seal_key);
+ g_free(buf);
+ return 1;
+ }
+ else {
+ g_free(buf);
+ return 0;
+ }
+
+}
+
+static guint64 uncrypt_sequence(guint8* session_key,guint64 checksum,guint64 enc_seq,unsigned char is_server _U_)
+{
+ guint8 zeros[4];
+ guint8 buf[16];
+ guint8 key[16];
+ rc4_state_struct rc4state;
+ guint8 *p_seq = (guint8*) &enc_seq;
+ /*guint32 temp;*/
+
+ memset(zeros,0,4);
+ md5_hmac(zeros,4,session_key,16,buf);
+ md5_hmac((guint8*)&checksum,8,buf,16,key);
+
+ crypt_rc4_init(&rc4state,key,16);
+ crypt_rc4(&rc4state,p_seq,8);
+ /*temp = *((guint32*)p_seq);
+ *((guint32*)p_seq) = *((guint32*)p_seq+1);
+ *((guint32*)p_seq+1) = temp;
+
+ if(!is_server) {
+ *p_seq = *p_seq & 0x7F;
+ }
+ */
+ return enc_seq;
+}
+
+static tvbuff_t *
+dissect_packet_data(tvbuff_t *tvb ,tvbuff_t *auth_tvb _U_,
+ int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info _U_,unsigned char is_server)
+{
+
+ tvbuff_t *buf = NULL;
+ guint8* decrypted;
+ netlogon_auth_vars *vars;
+ netlogon_auth_key key;
+ /*debugprintf("Dissection of request data offset %d len=%d on packet %d\n",offset,tvb_length_remaining(tvb,offset),pinfo->fd->num);*/
+
+ generate_hash_key(pinfo,is_server,&key,NULL);
+ vars = g_hash_table_lookup(netlogon_auths, &key);
+
+ if(vars != NULL ) {
+ while(vars != NULL && vars->next_start != -1 && vars->next_start < (int) pinfo->fd->num ) {
+ vars = vars->next;
+ }
+ if(vars == NULL ) {
+ debugprintf("Vars not found %d (packet_data)\n",g_hash_table_size(netlogon_auths));
+ return(buf);
+ }
+ else {
+ if(vars->can_decrypt == TRUE) {
+ rc4_state_struct rc4state;
+ int data_len = tvb_length_remaining(tvb,offset);
+ guint64 copyconfounder = vars->confounder;
+
+ crypt_rc4_init(&rc4state,vars->encryption_key,16);
+ crypt_rc4(&rc4state,(guint8*)&copyconfounder,8);
+ decrypted = tvb_memdup(tvb, offset,data_len);
+ crypt_rc4_init(&rc4state,vars->encryption_key,16);
+ crypt_rc4(&rc4state,decrypted,data_len);
+ buf = tvb_new_real_data(decrypted, data_len, data_len);
+ }
+ else {
+ debugprintf("Session key not found can't decrypt ...\n");
+ }
+ }
+ }
+ else {
+ debugprintf("Vars not found %d (packet_data)\n",g_hash_table_size(netlogon_auths));
+ return(buf);
+ }
+
+ return(buf);
+}
+
+static tvbuff_t* dissect_request_data( tvbuff_t *tvb ,tvbuff_t *auth_tvb ,
+ int offset , packet_info *pinfo ,dcerpc_auth_info *auth_info )
+{
+ return dissect_packet_data(tvb,auth_tvb,offset,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 )
+{
+ return dissect_packet_data(tvb,auth_tvb,offset,pinfo,auth_info,1);
+}
+
static int
dissect_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, guint8 *drep _U_)
-{
- proto_item *vf = NULL;
- proto_tree *subtree = NULL;
-
- /*
- * Create a new tree, and split into 4 components ...
- */
- vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
- offset, -1, FALSE);
- subtree = proto_item_add_subtree(vf, ett_secchan_verf);
-
- proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sig, tvb,
- offset, 8, FALSE);
- offset += 8;
-
- proto_tree_add_item(subtree, hf_netlogon_secchan_verf_digest, tvb,
- offset, 8, FALSE);
- offset += 8;
-
- proto_tree_add_item(subtree, hf_netlogon_secchan_verf_seq, tvb,
- offset, 8, FALSE);
- offset += 8;
-
- /* In some cases the nonce isn't present although it isn't clear
- why this is so. */
-
- if (tvb_bytes_exist(tvb, offset, 8)) {
- proto_tree_add_item(subtree, hf_netlogon_secchan_verf_nonce,
- tvb, offset, 8, FALSE);
- offset += 8;
- }
-
- return offset;
+ proto_tree *tree, guint8 *drep _U_, unsigned char is_server)
+{
+ netlogon_auth_vars *vars;
+ netlogon_auth_key key;
+ proto_item *vf = NULL;
+ proto_tree *subtree = NULL;
+ guint64 encrypted_seq;
+ guint64 digest;
+ guint64 confounder;
+ int update_vars = 0;
+
+ generate_hash_key(pinfo,is_server,&key,NULL);
+ vars = g_hash_table_lookup(netlogon_auths,(gconstpointer*) &key);
+ if( ! (seen.isseen && seen.num == pinfo->fd->num) ) {
+ /*
+ * Create a new tree, and split into x components ...
+ */
+ vf = proto_tree_add_item(tree, hf_netlogon_secchan_verf, tvb,
+ offset, -1, FALSE);
+ subtree = proto_item_add_subtree(vf, ett_secchan_verf);
+
+ proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sigalg, tvb,
+ offset, 2, TRUE);
+ proto_tree_add_item(subtree, hf_netlogon_secchan_verf_sealalg, tvb,
+ offset+2, 2, TRUE);
+ proto_tree_add_item(subtree, hf_netlogon_secchan_verf_pad, tvb,
+ offset+4, 2, FALSE);
+ proto_tree_add_item(subtree, hf_netlogon_secchan_verf_flag, tvb,
+ offset+6, 2, FALSE);
+ offset += 8;
+
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, subtree, drep,
+ hf_netlogon_secchan_verf_seq, &encrypted_seq);
+
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, subtree, drep,
+ hf_netlogon_secchan_verf_digest, &digest);
+
+ /* In some cases the nonce if the data/signture are encrypted ("integrity/seal in MS language")*/
+
+ if (tvb_bytes_exist(tvb, offset, 8)) {
+ offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, subtree, drep,
+ hf_netlogon_secchan_verf_nonce, &confounder);
+ }
+ update_vars = 1;
+ }
+ if( vars != NULL ) {
+ while(vars != NULL && vars->next_start != -1 && vars->next_start < (int)pinfo->fd->num ) {
+ vars = vars->next;
+ }
+ if(vars == NULL ) {
+ debugprintf("Vars not found %d (packet_data)\n",g_hash_table_size(netlogon_auths));
+ return(offset);
+ }
+ else {
+ if(update_vars) {
+ vars->confounder = confounder;
+ vars->seq = uncrypt_sequence(vars->session_key,digest,encrypted_seq,is_server);
+ }
+
+ if(get_seal_key(vars->session_key,16,vars->seq,vars->encryption_key))
+ {
+ vars->can_decrypt = TRUE;
+ }
+ else
+ {
+ debugprintf("get seal key returned 0\n");
+ }
+ }
+ }
+ else
+ {
+ debugprintf("Vars not found (is null %d) %d (dissect_verf)\n",vars==NULL,g_hash_table_size(netlogon_auths));
+ }
+ /*debugprintf("Setting isseen to true, old packet %d new %d\n",seen.num,pinfo->fd->num);*/
+ seen.isseen = TRUE;
+ seen.num = pinfo->fd->num;
+
+ return offset;
+}
+static int
+dissect_request_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo ,
+ proto_tree *tree, guint8 *drep )
+{
+ return dissect_secchan_verf(tvb,offset,pinfo,tree,drep,0);
+}
+static int
+dissect_response_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo ,
+ proto_tree *tree, guint8 *drep )
+{
+ return dissect_secchan_verf(tvb,offset,pinfo,tree,drep,1);
}
/* Secure channel types */
@@ -6754,6 +8015,19 @@ static const value_string sec_chan_type_vals[] = {
{ SEC_CHAN_BDC, "Backup domain controller" },
{ 0, NULL }
};
+static void
+netlogon_reassemble_init(void)
+{
+ if (netlogon_auths){
+ g_hash_table_destroy (netlogon_auths);
+ }
+ netlogon_auths = g_hash_table_new (netlogon_auth_hash, netlogon_auth_equal);
+ if (schannel_auths){
+ g_hash_table_destroy (schannel_auths);
+ }
+ schannel_auths = g_hash_table_new (netlogon_auth_hash, netlogon_auth_equal);
+
+}
void
proto_register_dcerpc_netlogon(void)
@@ -6860,12 +8134,131 @@ static hf_register_info hf[] = {
"Attributes", "netlogon.attrs", FT_UINT32, BASE_HEX,
NULL, 0, NULL, HFILL }},
+ { &hf_netlogon_lsapolicy_referentid,
+ { "Referent ID", "netlogon.lsapolicy.referentID", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Referent ID", HFILL }},
+
+ { &hf_netlogon_lsapolicy_len,
+ { "Length", "netlogon.lsapolicy.length", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "Length of the policy buffer", HFILL }},
+
+ { &hf_netlogon_lsapolicy_pointer,
+ { "Pointer", "netlogon.lsapolicy.pointer", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "Pointer to LSA POLICY", HFILL }},
+
{ &hf_netlogon_unknown_string,
{ "Unknown string", "netlogon.unknown_string", FT_STRING, BASE_NONE,
NULL, 0, "Unknown string. If you know what this is, contact wireshark developers.", HFILL }},
+
+ { &hf_netlogon_dummy_string,
+ { "Dummy String", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_trust_extention,
+ { "Trust extension", "netlogon.trust.extention", FT_STRING, BASE_NONE,
+ NULL, 0, "Trusts extension.", HFILL }},
+
+ { &hf_netlogon_trust_offset,
+ { "Offset", "netlogon.trust.extention_offset", FT_UINT32, BASE_DEC,
+ NULL, 0, "Trusts extension.", HFILL }},
+
+ { &hf_netlogon_trust_len,
+ { "Length", "netlogon.trust.extention_length", FT_UINT32, BASE_DEC,
+ NULL, 0, "Length", HFILL }},
+
+ { &hf_netlogon_trust_max,
+ { "Max Count", "netlogon.trust.extention.maxcount", FT_UINT32, BASE_DEC,
+ NULL, 0, "Max Count", HFILL }},
+
+ { &hf_netlogon_dummy_string2,
+ { "Dummy String2", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 2. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string3,
+ { "Dummy String3", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 3. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string4,
+ { "Dummy String4", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 4. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string5,
+ { "Dummy String5", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 5. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string6,
+ { "Dummy String6", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 6. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string7,
+ { "Dummy String7", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 7. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string8,
+ { "Dummy String8", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 8. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string9,
+ { "Dummy String9", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 9. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy_string10,
+ { "Dummy String10", "netlogon.dummy_string", FT_STRING, BASE_NONE,
+ NULL, 0, "Dummy String 10. Used is reserved for next evolutions.", HFILL }},
+
{ &hf_netlogon_unknown_long,
{ "Unknown long", "netlogon.unknown.long", FT_UINT32, BASE_HEX,
NULL, 0x0, "Unknown long. If you know what this is, contact wireshark developers.", HFILL }},
+
+ { &hf_netlogon_dummy1_long,
+ { "Dummy1 Long", "netlogon.dummy.long1", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 1. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy2_long,
+ { "Dummy2 Long", "netlogon.dummy.long2", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 2. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy3_long,
+ { "Dummy3 Long", "netlogon.dummy.long3", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 3. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy4_long,
+ { "Dummy4 Long", "netlogon.dummy.long4", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 4. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy5_long,
+ { "Dummy5 Long", "netlogon.dummy.long5", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 5. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy6_long,
+ { "Dummy6 Long", "netlogon.dummy.long6", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 6. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy7_long,
+ { "Dummy7 Long", "netlogon.dummy.long7", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 7. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy8_long,
+ { "Dummy8 Long", "netlogon.dummy.long8", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 8. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy9_long,
+ { "Dummy9 Long", "netlogon.dummy.long9", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 9. Used is reserved for next evolutions.", HFILL }},
+
+ { &hf_netlogon_dummy10_long,
+ { "Dummy10 Long", "netlogon.dummy.long10", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Dummy long 10. Used is reserved for next evolutions.", HFILL }},
+
+
+ { &hf_netlogon_supportedenctypes,
+ { "Supported Encryption Types", "netlogon.encryption.types", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Encryption types", HFILL }},
+
+ { &hf_netlogon_workstation_flags,
+ { "Workstation Flags", "netlogon.workstation.flags", FT_UINT32, BASE_HEX,
+ NULL, 0x0, "Flags", HFILL }},
+
{ &hf_netlogon_reserved,
{ "Reserved", "netlogon.reserved", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL }},
@@ -7049,6 +8442,10 @@ static hf_register_info hf[] = {
{ "Wkst Name", "netlogon.wkst.name", FT_STRING, BASE_NONE,
NULL, 0, "Workstation Name", HFILL }},
+ { &hf_netlogon_os_version,
+ { "OS version", "netlogon.os.version", FT_STRING, BASE_NONE,
+ NULL, 0, "OS Version", HFILL }},
+
{ &hf_netlogon_workstation_os,
{ "Wkst OS", "netlogon.wkst.os", FT_STRING, BASE_NONE,
NULL, 0, "Workstation OS", HFILL }},
@@ -7081,6 +8478,10 @@ static hf_register_info hf[] = {
{ "DNS Domain", "netlogon.dns_domain", FT_STRING, BASE_NONE,
NULL, 0, "DNS Domain Name", HFILL }},
+ { &hf_netlogon_ad_client_dns_name,
+ { "Client DNS Name", "netlogon.client_dns_name", FT_STRING, BASE_NONE,
+ NULL, 0, "Client DNS Name", HFILL }},
+
{ &hf_netlogon_domain_name,
{ "Domain", "netlogon.domain", FT_STRING, BASE_NONE,
NULL, 0, "Domain Name", HFILL }},
@@ -7093,6 +8494,14 @@ static hf_register_info hf[] = {
{ "Trusted DC", "netlogon.trusted_dc", FT_STRING, BASE_NONE,
NULL, 0, NULL, HFILL }},
+ { &hf_netlogon_logon_dnslogondomainname,
+ { "DNS Logon Domain name", "netlogon.logon.dnslogondomainname", FT_STRING, BASE_NONE,
+ NULL, 0, "DNS Name of the logon domain", HFILL }},
+
+ { &hf_netlogon_logon_upn,
+ { "UPN", "netlogon.logon.upn", FT_STRING, BASE_NONE,
+ NULL, 0, "User Principal Name", HFILL }},
+
{ &hf_netlogon_logonsrv_handle,
{ "Handle", "netlogon.handle", FT_STRING, BASE_NONE,
NULL, 0, "Logon Srv Handle", HFILL }},
@@ -7194,14 +8603,14 @@ static hf_register_info hf[] = {
NULL, 0x0, "Number of RIDs", HFILL }},
{ &hf_netlogon_num_controllers,
- { "Num DCs", "netlogon.num_dc", FT_UINT32, BASE_DEC,
- NULL, 0x0, "Number of domain controllers", HFILL }},
+ { "Num DCs", "netlogon.num_dc", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "Number of domain controllers", HFILL }},
- { &hf_netlogon_num_other_groups,
- { "Num Other Groups", "netlogon.num_other_groups", FT_UINT32, BASE_DEC,
- NULL, 0x0, NULL, HFILL }},
+ { &hf_netlogon_num_sid,
+ { "Num Extra SID", "netlogon.num_sid", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
- { &hf_netlogon_flags,
+ { &hf_netlogon_flags,
{ "Flags", "netlogon.flags", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL }},
@@ -7282,9 +8691,105 @@ static hf_register_info hf[] = {
NULL, 0x0, NULL, HFILL }},
{ &hf_netlogon_neg_flags,
- { "Neg Flags", "netlogon.neg_flags", FT_UINT32, BASE_HEX,
+ { "Negotiation options", "netlogon.neg_flags", FT_UINT32, BASE_HEX,
NULL, 0x0, "Negotiation Flags", HFILL }},
+ { &hf_netlogon_neg_flags_80000000,
+ { "Not used 80000000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80000000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_40000000,
+ { "Authenticated RPC supported", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40000000, "Authenticated RPC supported", HFILL }},
+
+ { &hf_netlogon_neg_flags_20000000,
+ { "Authenticated RPC via lsass supported", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20000000, "rpc via lsass", HFILL }},
+
+ { &hf_netlogon_neg_flags_10000000,
+ { "Not used 10000000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10000000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_8000000,
+ { "Not used 8000000", "ntlmssp.neg_flags.na800000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8000000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_4000000,
+ { "Not used 4000000", "ntlmssp.neg_flags.na400000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_4000000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_2000000,
+ { "Not used 2000000", "ntlmssp.neg_flags.na200000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2000000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_1000000,
+ { "Not used 1000000", "ntlmssp.neg_flags.na100000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1000000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_800000,
+ { "Not used 800000", "ntlmssp.neg_flags.na8000000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_800000, "Not used", HFILL }},
+
+ { &hf_netlogon_neg_flags_400000,
+ { "AES & SHA2 supported", "ntlmssp.neg_flags.na400000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_USEAES, "AES&SHA2", HFILL }},
+
+ { &hf_netlogon_neg_flags_200000,
+ { "RODC pass-through", "ntlmssp.neg_flags.na200000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_200000, "rodc pt", HFILL }},
+
+ { &hf_netlogon_neg_flags_100000,
+ { "NO NT4 emulation", "ntlmssp.neg_flags.na100000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_100000, "No NT4 emu", HFILL }},
+
+ { &hf_netlogon_neg_flags_80000,
+ { "Cross forest trust", "ntlmssp.neg_flags.na80000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80000, "Cross forest trust", HFILL }},
+
+ { &hf_netlogon_neg_flags_40000,
+ { "GetDomainInfo supported", "ntlmssp.neg_flags.na40000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40000, "GetDomainInfo", HFILL }},
+
+ { &hf_netlogon_neg_flags_20000,
+ { "ServerPasswordSet2 supported", "ntlmssp.neg_flags.na20000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20000, "PasswordSet2", HFILL }},
+
+ { &hf_netlogon_neg_flags_10000,
+ { "DNS trusts supported", "ntlmssp.neg_flags.na10000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10000, "DNS Trusts", HFILL }},
+
+ { &hf_netlogon_neg_flags_8000,
+ { "Transitive trusts", "ntlmssp.neg_flags.na8000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8000, "Transitive trust", HFILL }},
+
+ { &hf_netlogon_neg_flags_4000,
+ { "Strong key", "ntlmssp.neg_flags.na4000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_STRONGKEY, "Strong key", HFILL }},
+
+ { &hf_netlogon_neg_flags_2000,
+ { "Avoid replication Auth database", "ntlmssp.neg_flags.na2000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2000, "Avoid replication auth database", HFILL }},
+
+ { &hf_netlogon_neg_flags_1000,
+ { "Avoid replication account database", "ntlmssp.neg_flags.na1000", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1000, "Avoid replication account database", HFILL }},
+
+ { &hf_netlogon_neg_flags_800,
+ { "Concurent RPC", "ntlmssp.neg_flags.na800", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_800, "Concurent RPC", HFILL }},
+
+ { &hf_netlogon_neg_flags_400,
+ { "Generic pass-through", "ntlmssp.neg_flags.na400", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_400, "Generic pass-through", HFILL }},
+
+ { &hf_netlogon_neg_flags_200,
+ { "SendToSam", "ntlmssp.neg_flags.na200", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_200, "SendToSam", HFILL }},
+
+ { &hf_netlogon_neg_flags_100,
+ { "Refusal of password change", "ntlmssp.neg_flags.na100", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_100, "PWD change refusal", HFILL }},
+
+ { &hf_netlogon_neg_flags_80,
+ { "DatabaseRedo call", "ntlmssp.neg_flags.na80", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_80, "DatabaseRedo call", HFILL }},
+
+ { &hf_netlogon_neg_flags_40,
+ { "Handle multiple SIDs", "ntlmssp.neg_flags.na40", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_40, "Handle multiple SIDs", HFILL }},
+
+ { &hf_netlogon_neg_flags_20,
+ { "Restarting full DC sync", "ntlmssp.neg_flags.na20", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_20, "Restarting full DC sync", HFILL }},
+
+ { &hf_netlogon_neg_flags_10,
+ { "BDC handling Changelogs", "ntlmssp.neg_flags.na10", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_10, "BDC Changelog", HFILL }},
+
+ { &hf_netlogon_neg_flags_8,
+ { "Promotion count(deprecated)", "ntlmssp.neg_flags.na8", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_8, "Promotion count", HFILL }},
+
+ { &hf_netlogon_neg_flags_4,
+ { "RC4 encryption", "ntlmssp.neg_flags.na4", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_4, "RC4", HFILL }},
+
+ { &hf_netlogon_neg_flags_2,
+ { "NT3.5 BDC continious update", "ntlmssp.neg_flags.na2", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_2, "NT3.5", HFILL }},
+
+ { &hf_netlogon_neg_flags_1,
+ { "Account lockout", "ntlmssp.neg_flags.na1", FT_BOOLEAN, 32, TFS(&tfs_set_notset), NETLOGON_FLAG_1, "Account lockout", HFILL }},
+
{ &hf_netlogon_dc_flags,
{ "Domain Controller Flags", "netlogon.dc.flags", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL }},
@@ -7479,6 +8984,30 @@ static hf_register_info hf[] = {
{ "Trust Type", "netlogon.trust_type", FT_UINT32, BASE_DEC,
VALS(trust_type_vals), 0x0, NULL, HFILL }},
+ { &hf_netlogon_extraflags,
+ { "Extra Flags", "netlogon.extra_flags", FT_UINT32, BASE_HEX,
+ NULL, 0x0, NULL, HFILL }},
+
+ { &hf_netlogon_extra_flags_root_forest,
+ { "Request passed to DC of root forest", "netlogon.extra.flags.rootdc",
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_ROOT_FOREST,
+ NULL, HFILL }},
+
+ { &hf_netlogon_trust_flags_dc_firsthop,
+ { " DC at the end of the first hop of cross forest", "netlogon.extra.flags.dc_firsthop",
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_DC_XFOREST,
+ NULL, HFILL }},
+
+ { &hf_netlogon_trust_flags_rodc_to_dc,
+ { "Request from a RODC to a DC from another domain", "netlogon.extra.flags.rodc_to_dc",
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_RODC_DIF_DOMAIN,
+ NULL, HFILL }},
+
+ { &hf_netlogon_trust_flags_rodc_ntlm,
+ { "Request is a NTLM auth passed by a RODC", "netlogon.extra.flags.rodc_ntlm",
+ FT_BOOLEAN, 32, TFS(&tfs_set_notset), RQ_NTLM_FROM_RODC,
+ NULL, HFILL }},
+
{ &hf_netlogon_trust_flags,
{ "Trust Flags", "netlogon.trust_flags", FT_UINT32, BASE_HEX,
NULL, 0x0, NULL, HFILL }},
@@ -7581,7 +9110,26 @@ static hf_register_info hf[] = {
{ "Time Limit", "netlogon.time_limit", FT_RELATIVE_TIME, BASE_NONE,
NULL, 0, NULL, HFILL }},
- /* Secure channel dissection */
+
+ { &hf_client_credential,
+ { "Client Credential", "netlogon.clientcred", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+
+ { &hf_server_credential,
+ { "Server Credential", "netlogon.servercred", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+
+ { &hf_server_rid,
+ { "Account RID", "netlogon.serverrid", FT_UINT32, BASE_DEC,
+ NULL, 0x0, "", HFILL }},
+
+ { &hf_client_challenge,
+ { "Client Challenge", "netlogon.clientchallenge", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
+
+ { &hf_server_challenge,
+ { "Server Challenge", "netlogon.serverchallenge", FT_BYTES, BASE_NONE,
+ NULL, 0x0, "", HFILL }},
{ &hf_netlogon_secchan_bind_unknown1,
{ "Unknown1", "netlogon.secchan.bind.unknown1", FT_UINT32, BASE_HEX,
@@ -7599,6 +9147,14 @@ static hf_register_info hf[] = {
{ "Host", "netlogon.secchan.host", FT_STRING, BASE_NONE,
NULL, 0, NULL, HFILL }},
+ { &hf_netlogon_data_length,
+ { "Length of Data", "netlogon.data.length", FT_UINT32, BASE_DEC,
+ NULL, 0, "", HFILL }},
+
+ { &hf_netlogon_package_name,
+ { "SSP Package Name", "netlogon.data.package_name", FT_STRING, BASE_NONE,
+ NULL, 0, "", HFILL }},
+
{ &hf_netlogon_secchan_bind_ack_unknown1,
{ "Unknown1", "netlogon.secchan.bind_ack.unknown1", FT_UINT32,
BASE_HEX, NULL, 0x0, NULL, HFILL }},
@@ -7609,26 +9165,39 @@ static hf_register_info hf[] = {
{ &hf_netlogon_secchan_bind_ack_unknown3,
{ "Unknown3", "netlogon.secchan.bind_ack.unknown3", FT_UINT32,
- BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ BASE_HEX, NULL, 0x0, "", HFILL }},
- { &hf_netlogon_secchan_verf,
- { "Secure Channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE,
- NULL, 0x0, "Verifier", HFILL }},
+ { &hf_netlogon_secchan_verf,
+ { "Secure Channel Verifier", "netlogon.secchan.verifier", FT_NONE, BASE_NONE,
+ NULL, 0x0, "Verifier", HFILL }},
- { &hf_netlogon_secchan_verf_sig,
- { "Signature", "netlogon.secchan.sig", FT_BYTES, BASE_NONE, NULL,
- 0x0, NULL, HFILL }},
+ { &hf_netlogon_secchan_verf_sigalg,
+ { "Sign algorithm", "netlogon.secchan.sigalg", FT_UINT16, BASE_HEX, NULL,
+ 0x0, "Signature", HFILL }},
- { &hf_netlogon_secchan_verf_digest,
- { "Packet Digest", "netlogon.secchan.digest", FT_BYTES, BASE_NONE, NULL,
- 0x0, NULL, HFILL }},
+ { &hf_netlogon_secchan_verf_sealalg,
+ { "Sign algorithm", "netlogon.secchan.sigalg", FT_UINT16, BASE_HEX, NULL,
+ 0x0, "Signature", HFILL }},
+
+ { &hf_netlogon_secchan_verf_pad,
+ { "Padding", "netlogon.secchan.sigalg", FT_BYTES, BASE_NONE, NULL,
+ 0x0, "Signature", HFILL }},
+
+ { &hf_netlogon_secchan_verf_flag,
+ { "Flags", "netlogon.secchan.sigalg", FT_BYTES, BASE_NONE, NULL,
+ 0x0, "Signature", HFILL }},
+
+ { &hf_netlogon_secchan_verf_digest,
+ { "Packet Digest", "netlogon.secchan.digest", FT_BYTES, BASE_NONE, NULL,
+ 0x0, "Packet Digest", HFILL }},
- { &hf_netlogon_secchan_verf_seq,
- { "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_NONE, NULL,
- 0x0, NULL, HFILL }},
+ { &hf_netlogon_secchan_verf_seq,
+ { "Sequence No", "netlogon.secchan.seq", FT_BYTES, BASE_NONE, NULL,
+ 0x0, "Sequence No", HFILL }},
- { &hf_netlogon_secchan_verf_nonce,
- { "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_NONE, NULL,
+ { &hf_netlogon_secchan_verf_nonce,
+ { "Nonce", "netlogon.secchan.nonce", FT_BYTES, BASE_NONE, NULL,
0x0, NULL, HFILL }},
{ &hf_netlogon_group_attrs_mandatory,
@@ -7745,10 +9314,23 @@ static hf_register_info hf[] = {
{ "DnsDomainInfo", "netlogon.dnsdomaininfo", FT_NONE, BASE_NONE,
NULL, 0x0, NULL, HFILL }},
+ { &DnsDomainInfo_sid,
+ { "Sid", "lsarpc.lsa_DnsDomainInfo.sid", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &DomainInfo_sid,
+ { "Sid", "lsarpc.lsa_DomainInfo.sid", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &DnsDomainInfo_domain_guid,
+ { "Domain Guid", "lsarpc.lsa_DnsDomainInfo.domain_guid", FT_GUID, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &DnsDomainInfo_dns_forest,
+ { "Dns Forest", "lsarpc.lsa_DnsDomainInfo.dns_forest", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &DnsDomainInfo_dns_domain,
+ { "Dns Domain", "lsarpc.lsa_DnsDomainInfo.dns_domain", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
+ { &DnsDomainInfo_name,
+ { "Name", "lsarpc.lsa_DnsDomainInfo.name", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
};
static gint *ett[] = {
- &ett_dcerpc_netlogon,
+ &ett_dcerpc_netlogon,
+ &ett_authenticate_flags,
&ett_CYPHER_VALUE,
&ett_QUOTA_LIMITS,
&ett_IDENTITY_INFO,
@@ -7767,6 +9349,7 @@ static hf_register_info hf[] = {
&ett_DS_DOMAIN_TRUSTS,
&ett_BLOB,
&ett_DOMAIN_TRUST_INFO,
+ &ett_LSA_POLICY_INFO,
&ett_trust_flags,
&ett_trust_attribs,
&ett_get_dcname_request_flags,
@@ -7776,6 +9359,7 @@ static hf_register_info hf[] = {
&ett_secchan_verf,
&ett_group_attrs,
&ett_user_flags,
+ &ett_nt_counted_longs_as_string,
&ett_user_account_control
};
@@ -7785,26 +9369,30 @@ static hf_register_info hf[] = {
proto_register_field_array(proto_dcerpc_netlogon, hf,
array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ register_init_routine(netlogon_reassemble_init);
+
}
static dcerpc_auth_subdissector_fns secchan_auth_fns = {
dissect_secchan_bind_creds, /* Bind */
dissect_secchan_bind_ack_creds, /* Bind ACK */
NULL, /* AUTH3 */
- dissect_secchan_verf, /* Request verifier */
- dissect_secchan_verf, /* Response verifier */
- NULL, /* Request data */
- NULL /* Response data */
+ dissect_request_secchan_verf, /* Request verifier */
+ dissect_response_secchan_verf, /* Response verifier */
+ dissect_request_data, /* Request data */
+ dissect_response_data /* Response data */
};
void
proto_reg_handoff_dcerpc_netlogon(void)
{
- /* Register protocol as dcerpc */
+ /* Register protocol as dcerpc */
+ seen.isseen = FALSE;
+ seen.num = 0;
+ dcerpc_init_uuid(proto_dcerpc_netlogon, ett_dcerpc_netlogon,
+ &uuid_dcerpc_netlogon, ver_dcerpc_netlogon,
+ dcerpc_netlogon_dissectors, hf_netlogon_opnum);
- dcerpc_init_uuid(proto_dcerpc_netlogon, ett_dcerpc_netlogon,
- &uuid_dcerpc_netlogon, ver_dcerpc_netlogon,
- dcerpc_netlogon_dissectors, hf_netlogon_opnum);
register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN,
diff --git a/epan/dissectors/packet-dcerpc-nt.c b/epan/dissectors/packet-dcerpc-nt.c
index 07f91bc4ab..681004403b 100644
--- a/epan/dissectors/packet-dcerpc-nt.c
+++ b/epan/dissectors/packet-dcerpc-nt.c
@@ -40,8 +40,8 @@
#include "packet-windows-common.h"
-static int hf_nt_cs_len = -1;
-static int hf_nt_cs_size = -1;
+int hf_nt_cs_len = -1;
+int hf_nt_cs_size = -1;
static int hf_lsa_String_name_len = -1;
static int hf_lsa_String_name_size = -1;
diff --git a/epan/dissectors/packet-dcerpc-nt.h b/epan/dissectors/packet-dcerpc-nt.h
index b9551b85ed..626f472337 100644
--- a/epan/dissectors/packet-dcerpc-nt.h
+++ b/epan/dissectors/packet-dcerpc-nt.h
@@ -265,5 +265,8 @@ void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
void dcerpc_smb_init(int proto_dcerpc);
+/* Used into packet-dcerpc-netlogon.c*/
+int hf_nt_cs_len;
+int hf_nt_cs_size;
#endif /* packet-dcerpc-nt.h */
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index d1ea2590e0..77659ffd97 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -3081,6 +3081,12 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
/* Start out assuming we won't succeed in decrypting. */
decrypted_tvb = NULL;
+ /* Schannel needs informations into the footer (verifier) in order to setup decryptions keys
+ * so we call it in order to have a chance to decypher the data
+ */
+ if (DCE_C_RPC_AUTHN_PROTOCOL_SEC_CHAN == auth_info->auth_type) {
+ dissect_dcerpc_cn_auth (tvb, offset, pinfo, dcerpc_tree, hdr, TRUE, auth_info);
+ }
if ((auth_fns = get_auth_subdissector_fns(
auth_info->auth_level, auth_info->auth_type))) {