A new type of DCERPC over SMB transport.
I have captures with w2k speaking DCERPC without using the normal Transaction named pipes SMBs. Instead DCERPC is just implemented ontop of ordinary read/write calls. The smb dissector now examines TreeConnectAndX and stores the conversation/tid/type-of-share in a table for later access. All SMB requests examine that hash table to find out if TID in the header refers to a normal share or an IPC$ share. Initial support in read/write SMB calls to detect if the operations are for an IPC share and thus it assumes it must be DCERPC commands in the payload. Desegmentation/Reassembly of these types of calls are not implemented yet. svn path=/trunk/; revision=4952
This commit is contained in:
parent
54fa1d944a
commit
17392c995b
|
@ -8,7 +8,7 @@ XXX Fixme : shouldnt show [malformed frame] for long packets
|
|||
* significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
|
||||
* Guy Harris 2001
|
||||
*
|
||||
* $Id: packet-smb-pipe.c,v 1.70 2002/03/15 08:59:52 sahlberg Exp $
|
||||
* $Id: packet-smb-pipe.c,v 1.71 2002/03/16 04:39:28 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -3157,7 +3157,7 @@ proto_register_pipe_lanman(void)
|
|||
|
||||
static heur_dissector_list_t smb_transact_heur_subdissector_list;
|
||||
|
||||
static gboolean
|
||||
gboolean
|
||||
dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
|
||||
proto_tree *tree, guint32 fid)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Declarations of routines for SMB named pipe packet dissection
|
||||
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
|
||||
*
|
||||
* $Id: packet-smb-pipe.h,v 1.9 2001/11/19 11:41:51 guy Exp $
|
||||
* $Id: packet-smb-pipe.h,v 1.10 2002/03/16 04:39:28 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -30,5 +30,8 @@ extern gboolean
|
|||
dissect_pipe_smb(tvbuff_t *sp_tvb, tvbuff_t *s_tvb, tvbuff_t *pd_tvb,
|
||||
tvbuff_t *p_tvb, tvbuff_t *d_tvb, const char *pipe,
|
||||
packet_info *pinfo, proto_tree *tree);
|
||||
gboolean
|
||||
dissect_pipe_dcerpc(tvbuff_t *d_tvb, packet_info *pinfo, proto_tree *parent_tree,
|
||||
proto_tree *tree, guint32 fid);
|
||||
|
||||
#endif
|
||||
|
|
91
packet-smb.c
91
packet-smb.c
|
@ -3,7 +3,7 @@
|
|||
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
|
||||
* 2001 Rewrite by Ronnie Sahlberg and Guy Harris
|
||||
*
|
||||
* $Id: packet-smb.c,v 1.219 2002/03/15 19:47:03 sharpe Exp $
|
||||
* $Id: packet-smb.c,v 1.220 2002/03/16 04:39:29 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -3114,8 +3114,9 @@ static int
|
|||
dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
|
||||
{
|
||||
guint32 ofs=0;
|
||||
guint16 cnt=0, bc, fid;
|
||||
guint16 cnt=0, bc, fid=0;
|
||||
guint8 wc;
|
||||
smb_info_t *si = (smb_info_t *)pinfo->private_data;
|
||||
|
||||
WORD_COUNT;
|
||||
|
||||
|
@ -3156,8 +3157,16 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
COUNT_BYTES(2);
|
||||
|
||||
if (bc != 0) {
|
||||
/* file data */
|
||||
offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
|
||||
if( (si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
|
||||
tvbuff_t *dcerpc_tvb;
|
||||
/* dcerpc call */
|
||||
dcerpc_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), bc);
|
||||
dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree,
|
||||
tree, fid);
|
||||
} else {
|
||||
/* ordinary file data */
|
||||
offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
|
||||
}
|
||||
bc = 0;
|
||||
}
|
||||
|
||||
|
@ -4775,6 +4784,7 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
guint8 wc, cmd=0xff;
|
||||
guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
|
||||
smb_info_t *si = (smb_info_t *)pinfo->private_data;
|
||||
int fid=0;
|
||||
|
||||
WORD_COUNT;
|
||||
|
||||
|
@ -4799,7 +4809,8 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
/* If we have seen the request, then print which FID this refers to */
|
||||
/* first check if we have seen the request */
|
||||
if(si->sip != NULL && si->sip->frame_req>0){
|
||||
add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
|
||||
fid=(int)si->sip->extra_info;
|
||||
add_fid(tvb, pinfo, tree, 0, 0, fid);
|
||||
}
|
||||
|
||||
/* remaining */
|
||||
|
@ -4876,9 +4887,21 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
}
|
||||
}
|
||||
|
||||
/* file data */
|
||||
offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
|
||||
bc = 0;
|
||||
/* another way to transport DCERPC over SMB is to skip Transaction completely and just
|
||||
read write */
|
||||
if(bc){
|
||||
if(si->sip->flags&SMB_SIF_TID_IS_IPC){
|
||||
tvbuff_t *dcerpc_tvb;
|
||||
/* dcerpc call */
|
||||
dcerpc_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), bc);
|
||||
dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree,
|
||||
tree, fid);
|
||||
} else {
|
||||
/* ordinary file data */
|
||||
offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
|
||||
}
|
||||
bc = 0;
|
||||
}
|
||||
|
||||
END_OF_SMB
|
||||
|
||||
|
@ -5713,6 +5736,22 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
|
|||
offset, an_len, an);
|
||||
COUNT_BYTES(an_len);
|
||||
|
||||
/* Now when we know the service type, store it so that we know it for later commands down
|
||||
this tree */
|
||||
if(!pinfo->fd->flags.visited){
|
||||
smb_info_t *si = (smb_info_t *)pinfo->private_data;
|
||||
/* Remove any previous entry for this TID */
|
||||
if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
|
||||
g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
|
||||
}
|
||||
if(!strcmp(an,"IPC")){
|
||||
g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
|
||||
} else {
|
||||
g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(wc==3){
|
||||
if (bc != 0) {
|
||||
/*
|
||||
|
@ -12430,6 +12469,8 @@ free_hash_tables(gpointer ctarg, gpointer user_data)
|
|||
g_hash_table_destroy(ct->matched);
|
||||
if (ct->dcerpc_fid_to_frame)
|
||||
g_hash_table_destroy(ct->dcerpc_fid_to_frame);
|
||||
if (ct->tid_service)
|
||||
g_hash_table_destroy(ct->tid_service);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -13928,7 +13969,6 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
|||
guint32 nt_status = 0;
|
||||
guint8 errclass = 0;
|
||||
guint16 errcode = 0;
|
||||
guint16 uid, pid, tid, mid;
|
||||
guint32 pid_mid;
|
||||
conversation_t *conversation;
|
||||
|
||||
|
@ -13963,11 +14003,11 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
|||
} else {
|
||||
si.unicode = FALSE;
|
||||
}
|
||||
tid = tvb_get_letohs(tvb, offset+24);
|
||||
pid = tvb_get_letohs(tvb, offset+26);
|
||||
uid = tvb_get_letohs(tvb, offset+28);
|
||||
mid = tvb_get_letohs(tvb, offset+30);
|
||||
pid_mid = (pid << 16) | mid;
|
||||
si.tid = tvb_get_letohs(tvb, offset+24);
|
||||
si.pid = tvb_get_letohs(tvb, offset+26);
|
||||
si.uid = tvb_get_letohs(tvb, offset+28);
|
||||
si.mid = tvb_get_letohs(tvb, offset+30);
|
||||
pid_mid = (si.pid << 16) | si.mid;
|
||||
si.info_level = -1;
|
||||
si.info_count = -1;
|
||||
|
||||
|
@ -14007,14 +14047,17 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
|||
si.ct->dcerpc_fid_to_frame=g_hash_table_new(
|
||||
smb_saved_info_hash_unmatched,
|
||||
smb_saved_info_equal_unmatched);
|
||||
si.ct->tid_service=g_hash_table_new(
|
||||
smb_saved_info_hash_unmatched,
|
||||
smb_saved_info_equal_unmatched);
|
||||
conversation_add_proto_data(conversation, proto_smb, si.ct);
|
||||
}
|
||||
|
||||
if( (si.request)
|
||||
&& (mid==0)
|
||||
&& (uid==0)
|
||||
&& (pid==0)
|
||||
&& (tid==0) ){
|
||||
&& (si.mid==0)
|
||||
&& (si.uid==0)
|
||||
&& (si.pid==0)
|
||||
&& (si.tid==0) ){
|
||||
/* this is a broadcast SMB packet, there will not be a reply.
|
||||
We dont need to do anything
|
||||
*/
|
||||
|
@ -14192,6 +14235,10 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
|||
sip = g_mem_chunk_alloc(smb_saved_info_chunk);
|
||||
sip->frame_req = pinfo->fd->num;
|
||||
sip->frame_res = 0;
|
||||
sip->flags = 0;
|
||||
if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)){
|
||||
sip->flags |= SMB_SIF_TID_IS_IPC;
|
||||
}
|
||||
sip->cmd = si.cmd;
|
||||
sip->extra_info = NULL;
|
||||
g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
|
||||
|
@ -14307,19 +14354,19 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
|
|||
offset += 12;
|
||||
|
||||
/* TID */
|
||||
proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
|
||||
proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
|
||||
offset += 2;
|
||||
|
||||
/* PID */
|
||||
proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
|
||||
proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
|
||||
offset += 2;
|
||||
|
||||
/* UID */
|
||||
proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
|
||||
proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
|
||||
offset += 2;
|
||||
|
||||
/* MID */
|
||||
proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, mid);
|
||||
proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
|
||||
offset += 2;
|
||||
|
||||
pinfo->private_data = &si;
|
||||
|
|
12
smb.h
12
smb.h
|
@ -2,7 +2,7 @@
|
|||
* Defines for smb packet dissection
|
||||
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
|
||||
*
|
||||
* $Id: smb.h,v 1.35 2002/03/15 08:59:53 sahlberg Exp $
|
||||
* $Id: smb.h,v 1.36 2002/03/16 04:39:29 sahlberg Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -225,8 +225,10 @@
|
|||
* The information we need to save about a request in order to show the
|
||||
* frame number of the request in the dissection of the reply.
|
||||
*/
|
||||
#define SMB_SIF_TID_IS_IPC 0x0001
|
||||
typedef struct {
|
||||
guint32 frame_req, frame_res;
|
||||
guint16 flags;
|
||||
int cmd;
|
||||
void *extra_info;
|
||||
} smb_saved_info_t;
|
||||
|
@ -256,6 +258,11 @@ typedef struct {
|
|||
#define TRANSACTION_PIPE 0
|
||||
#define TRANSACTION_MAILSLOT 1
|
||||
|
||||
/* these are defines used to represent different types of TIDs.
|
||||
dont use the value 0 for any of these */
|
||||
#define TID_NORMAL 1
|
||||
#define TID_IPC 2
|
||||
|
||||
/* this is the structure which is associated with each conversation */
|
||||
typedef struct conv_tables {
|
||||
/* these two tables are used to match requests with responses */
|
||||
|
@ -263,10 +270,13 @@ typedef struct conv_tables {
|
|||
GHashTable *matched;
|
||||
/* this tables is used by DCERPC over SMB reassembly*/
|
||||
GHashTable *dcerpc_fid_to_frame;
|
||||
/* This table is used to track TID->services for a conversation */
|
||||
GHashTable *tid_service;
|
||||
} conv_tables_t;
|
||||
|
||||
typedef struct smb_info {
|
||||
int cmd;
|
||||
int tid, pid, uid, mid;
|
||||
gboolean unicode; /* Are strings in this SMB Unicode? */
|
||||
gboolean request; /* Is this a request? */
|
||||
gboolean unidir;
|
||||
|
|
Loading…
Reference in New Issue