aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2020-01-07 17:33:35 +0100
committerAnders Broman <a.broman58@gmail.com>2020-01-08 07:30:36 +0000
commit9483fbcbf424cabcc34bdd7da6d1bba947e0aa90 (patch)
tree5d32859ced5cba64532f273ed2b3de2997b954fd
parent088266e39eb55a94720150ce234b6224e6e88325 (diff)
packet-dcerpc-netlogon: relax the data model for netlogon_auth_key
This is a change into the correct direction and allows decryption even if DCERPC security context multiplexing is not used. The final design is added as comment, which would make it possible to do decryption in all cases allowed by the protocol. Change-Id: Ided40e0028967f2a047bf2722e627800ca77054d Reviewed-on: https://code.wireshark.org/review/35680 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-dcerpc-netlogon.c104
1 files changed, 34 insertions, 70 deletions
diff --git a/epan/dissectors/packet-dcerpc-netlogon.c b/epan/dissectors/packet-dcerpc-netlogon.c
index 1b05041d1c..ea695d6290 100644
--- a/epan/dissectors/packet-dcerpc-netlogon.c
+++ b/epan/dissectors/packet-dcerpc-netlogon.c
@@ -557,11 +557,23 @@ static const true_false_string user_account_control_account_disabled= {
};
typedef struct _netlogon_auth_key {
- address src;
- address dst;
- guint32 srcport;
- guint32 dstport;
- char * name;
+ /*
+ * For now we only match the client and server ip
+ * addresses, as keys can be used across tcp connections.
+ *
+ * Also note that ServerChallenge and ServerAuthenticate
+ * can be on different tcp connections!
+ *
+ * TODO:
+ * * We could have a challenge table indexed by client, server
+ * and computer name
+ * * A good ServerAuthenticate could fill a session key table
+ * indexed by computer name.
+ * * A DCERPC bind/alter context could lookup the session key table
+ * and copy the session key to the DCERPC connection/auth_context.
+ */
+ address client;
+ address server;
} netlogon_auth_key;
static gint
@@ -569,33 +581,18 @@ 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->srcport == key2->srcport) && (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));
+
+ return (addresses_equal(&key1->client,&key2->client) && addresses_equal(&key1->server,&key2->server));
}
static 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;
- hash_val1 += key1->srcport;
- }
- else {
- unsigned int i = 0;
- hash_val1 = 0;
- for(i=0; key1->name[i]; i++) {
- hash_val1 += key1->name[i];
- }
- }
+ guint hash_val1 = 0;
- hash_val1 = add_address_to_hash(hash_val1, &key1->src);
- hash_val1 = add_address_to_hash(hash_val1, &key1->dst);
+ hash_val1 = add_address_to_hash(hash_val1, &key1->client);
+ hash_val1 = add_address_to_hash(hash_val1, &key1->server);
return hash_val1;
}
static int
@@ -2372,23 +2369,15 @@ 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)
+static void generate_hash_key(packet_info *pinfo,unsigned char is_server,netlogon_auth_key *key)
{
if(is_server) {
- key->dstport = pinfo->srcport;
- key->srcport = pinfo->destport;
- copy_address_shallow(&key->dst,&pinfo->src);
- copy_address_shallow(&key->src,&pinfo->dst);
- /* name has been durably allocated */
- key->name = name;
+ copy_address_shallow(&key->server,&pinfo->src);
+ copy_address_shallow(&key->client,&pinfo->dst);
}
else {
- copy_address_shallow(&key->dst,&pinfo->dst);
- copy_address_shallow(&key->src,&pinfo->src);
- key->dstport = pinfo->destport;
- key->srcport = pinfo->srcport;
- /* name has been durably allocated */
- key->name = name;
+ copy_address_shallow(&key->server,&pinfo->dst);
+ copy_address_shallow(&key->client,&pinfo->src);
}
}
@@ -2433,12 +2422,12 @@ netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t *tvb, int offset,
vars->next_start = -1;
vars->next = NULL;
- generate_hash_key(pinfo,0,&key,NULL);
+ generate_hash_key(pinfo,0,&key);
existing_vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths, &key);
if (!existing_vars) {
netlogon_auth_key *k = (netlogon_auth_key *)wmem_memdup(wmem_file_scope(), &key, sizeof(netlogon_auth_key));
- copy_address_wmem(wmem_file_scope(), &k->src, &key.src);
- copy_address_wmem(wmem_file_scope(), &k->dst, &key.dst);
+ copy_address_wmem(wmem_file_scope(), &k->client, &key.client);
+ copy_address_wmem(wmem_file_scope(), &k->server, &key.server);
debugprintf("Adding initial vars with this start packet = %d\n",vars->start);
wmem_map_insert(netlogon_auths, k, vars);
}
@@ -2457,31 +2446,6 @@ netlogon_dissect_netrserverreqchallenge_rqst(tvbuff_t *tvb, int offset,
existing_vars->next = vars;
}
}
- /* used by other rpc that use schannel ie lsa */
-#if 0
- generate_hash_key(pinfo,0,&key,vars->client_name);
- existing_vars = NULL;
- existing_vars = wmem_map_lookup(schannel_auths, key);
- if (!existing_vars)
- {
- netlogon_auth_key *k = (netlogon_auth_key *)wmem_memdup(wmem_file_scope(), &key, sizeof(netlogon_auth_key));
- copy_address_wmem(wmem_file_scope(), &k->src, &key.src);
- copy_address_wmem(wmem_file_scope(), &k->dst, &key.dst);
- wmem_map_insert(schannel_auths, k, 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->num;
- existing_vars->next = vars;
- }
-#endif
return offset;
}
@@ -2493,7 +2457,7 @@ netlogon_dissect_netrserverreqchallenge_reply(tvbuff_t *tvb, int offset,
netlogon_auth_key key;
guint64 server_challenge;
- generate_hash_key(pinfo,1,&key,NULL);
+ generate_hash_key(pinfo,1,&key);
vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths,(gconstpointer*) &key);
offset = dissect_dcerpc_8bytes(tvb, offset, pinfo, tree, drep,
@@ -6622,7 +6586,7 @@ netlogon_dissect_netrserverauthenticate23_reply(tvbuff_t *tvb, int offset,
offset = dissect_ntstatus(tvb, offset, pinfo, tree, di, drep,
hf_netlogon_rc, NULL);
- generate_hash_key(pinfo, 1 , &key, NULL);
+ generate_hash_key(pinfo, 1 , &key);
vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths, &key);
if(vars != NULL) {
@@ -7909,7 +7873,7 @@ dissect_packet_data(tvbuff_t *tvb ,tvbuff_t *auth_tvb _U_,
netlogon_auth_key key;
/*debugprintf("Dissection of request data offset %d len=%d on packet %d\n",offset,tvb_length_remaining(tvb,offset),pinfo->num);*/
- generate_hash_key(pinfo,is_server,&key,NULL);
+ generate_hash_key(pinfo,is_server,&key);
vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths, &key);
if(vars != NULL ) {
@@ -7984,7 +7948,7 @@ dissect_secchan_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint64 confounder = 0;
int update_vars = 0;
- generate_hash_key(pinfo,is_server,&key,NULL);
+ generate_hash_key(pinfo,is_server,&key);
vars = (netlogon_auth_vars *)wmem_map_lookup(netlogon_auths,(gconstpointer*) &key);
if( ! (seen.isseen && seen.num == pinfo->num) ) {
/*