On Sat, Jun 9, 2012 at 5:20 PM, Richard Sharpe <[email protected]> wrote: > On Sat, Jun 9, 2012 at 4:51 PM, Richard Sharpe > <[email protected]> wrote: >> On Sat, Jun 9, 2012 at 3:12 PM, Richard Sharpe >> <[email protected]> wrote: >>> Hi folks, >>> >>> So, in Samba bug https://bugzilla.samba.org/show_bug.cgi?id=8989 you >>> will find two captures relating to the handling of NT TRANSACT SET >>> SECURITY DESCRIPTOR. >>> >>> Wireshark does not handle the dissection of these correctly, and I >>> suspect, normal SMB TRANSACT and SMB TRANSACT2 requests/responses. >>> >>> In dissect_smb, in the code for a normal bidirectional request or >>> response we lookup, using g_hash_table_lookup, the sip for the pid_mid >>> for the current frame. However, we look it up in the unmatched >>> requests. >>> >>> By the time we see a secondary, the original request with that pid_mid >>> is no longer unmatched, so we have a null sip. Later, when we call >>> smb_trans_defragment on the secondary (so we can give this fragment to >>> the original request), we do not have a sip, so we do nothing. >>> >>> It seems that in dissect_smb, if the request is an XXX_SECONDARY, we >>> should look up the sip in the matched packets not the unmatched >>> packets. >>> >>> What say ye? >>> >>> I will give that a try to see if I can make progress. >> >> The following patch gets much closer to handling this, but it is not >> yet correct. For example, it lables the secondary as an unknown and it >> shows extra byte parameters against the primary. > > A minor mod fixes the problem of the extra byte parameters ... now to > fix the two remaining problems: > > 1. The secondary is labeled as unknown. I suspect that it would better > to actually associate the dissection with the last secondary ... > > 2. Requests that require multiple secondaries are not handled > correctly. This will require adding some code from the response > handling section. > > Feedback welcome.
OK, this patch fixes the re-assembly of NT_TRANSACT requests and
responses. I suspect that the others will have to be fixed similarly.
Patch is attached as well.
There is also the issue of handling the continuations better.
Index: epan/dissectors/packet-smb.c
===================================================================
--- epan/dissectors/packet-smb.c (revision 43181)
+++ epan/dissectors/packet-smb.c (working copy)
@@ -8852,7 +8852,8 @@
dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_,
proto_tree *tree, int offset, proto_tree *smb_tree _U_)
{
guint8 wc, sc;
- guint32 pc=0, po=0, dc=0, od=0;
+ guint32 pc=0, pd = 0, po=0, dc=0, od=0, dd = 0;
+ guint32 td=0, tp=0;
smb_info_t *si;
smb_saved_info_t *sip;
int subcmd;
@@ -8860,6 +8861,9 @@
guint16 bc;
guint32 padcnt;
smb_nt_transact_info_t *nti=NULL;
+ fragment_data *r_fd = NULL;
+ tvbuff_t *pd_tvb=NULL;
+ gboolean save_fragmented;
ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
@@ -8887,11 +8891,13 @@
/* total param count */
- proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4,
ENC_LITTLE_ENDIAN);
+ tp = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
offset += 4;
/* total data count */
- proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4,
ENC_LITTLE_ENDIAN);
+ td = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
offset += 4;
if(wc>=19){
@@ -8940,7 +8946,8 @@
/* primary request */
} else {
/* secondary request */
- proto_tree_add_item(tree, hf_smb_data_disp32, tvb, offset, 4,
ENC_LITTLE_ENDIAN);
+ dd = tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4,
dd);
offset += 4;
}
@@ -9003,8 +9010,54 @@
BYTE_COUNT;
- /* parameters */
- if(po>(guint32)offset){
+ /* reassembly of SMB NT Transaction data payload.
+ In this section we do reassembly of both the data and parameters
+ blocks of the SMB transaction command.
+ */
+ save_fragmented = pinfo->fragmented;
+ /* do we need reassembly? */
+ if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
+ /* oh yeah, either data or parameter section needs
+ reassembly...
+ */
+ pinfo->fragmented = TRUE;
+ if(smb_trans_reassembly){
+ /* ...and we were told to do reassembly */
+ if(pc && ((unsigned int)tvb_length_remaining(tvb,
po)>=pc) ){
+ r_fd = smb_trans_defragment(tree, pinfo, tvb,
+ po, pc, pd, td+tp);
+ }
+ if((r_fd==NULL) && dc && ((unsigned
int)tvb_length_remaining(tvb,
od)>=dc) ){
+ r_fd = smb_trans_defragment(tree, pinfo, tvb,
+ od, dc, dd+tp,
td+tp);
+ }
+ }
+ }
+
+ /* if we got a reassembled fd structure from the reassembly routine we
+ must create pd_tvb from it
+ */
+ if(r_fd){
+ proto_item *frag_tree_item;
+
+ pd_tvb = tvb_new_child_real_data(tvb, r_fd->data, r_fd->datalen,
+ r_fd->datalen);
+ add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+
+ show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb,
&frag_tree_item);
+ }
+
+ if(pd_tvb){
+ /* we have reassembled data, grab param and data from there */
+ dissect_nt_trans_param_request(pd_tvb, pinfo, 0, tree, tp,
+ &ntd, (guint16) tvb_length(pd_tvb),
nti);
+ dissect_nt_trans_data_request(pd_tvb, pinfo, tp, tree, td, &ntd, nti);
+ COUNT_BYTES(bc); /* We are done */
+ } else {
+ /* we do not have reassembled data, just use what we have in the
+ packet as well as we can */
+ /* parameters */
+ if(po>(guint32)offset){
/* We have some initial padding bytes.
*/
padcnt = po-offset;
@@ -9013,15 +9066,15 @@
CHECK_BYTE_COUNT(padcnt);
proto_tree_add_item(tree, hf_smb_padding, tvb, offset,
padcnt, ENC_NA);
COUNT_BYTES(padcnt);
- }
- if(pc){
+ }
+ if(pc){
CHECK_BYTE_COUNT(pc);
dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc,
&ntd, bc, nti);
COUNT_BYTES(pc);
- }
+ }
- /* data */
- if(od>(guint32)offset){
+ /* data */
+ if(od>(guint32)offset){
/* We have some initial padding bytes.
*/
padcnt = od-offset;
@@ -9029,12 +9082,13 @@
padcnt = bc;
proto_tree_add_item(tree, hf_smb_padding, tvb, offset,
padcnt, ENC_NA);
COUNT_BYTES(padcnt);
- }
- if(dc){
+ }
+ if(dc){
CHECK_BYTE_COUNT(dc);
dissect_nt_trans_data_request(
tvb, pinfo, offset, tree, dc, &ntd, nti);
COUNT_BYTES(dc);
+ }
}
END_OF_SMB
@@ -9549,6 +9603,7 @@
dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
&ntd, (guint16) tvb_length(pd_tvb));
dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd,
nti);
+ COUNT_BYTES(bc); /* We are done */
} else {
/* we do not have reassembled data, just use what we have in the
packet as well as we can */
@@ -17213,6 +17268,8 @@
g_hash_table_destroy(ct->unmatched);
if (ct->matched)
g_hash_table_destroy(ct->matched);
+ if (ct->primaries)
+ g_hash_table_destroy(ct->primaries);
if (ct->tid_service)
g_hash_table_destroy(ct->tid_service);
g_free(ct);
@@ -17575,6 +17632,10 @@
smb_saved_info_equal_matched);
si->ct->unmatched=
g_hash_table_new(smb_saved_info_hash_unmatched,
smb_saved_info_equal_unmatched);
+ /* We used the same key format as the unmatched entries */
+ si->ct->primaries=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);
@@ -17640,6 +17701,12 @@
new_key->pid_mid = pid_mid;
g_hash_table_insert(si->ct->matched, new_key,
sip);
+ } else {
+ if (si->cmd == SMB_COM_TRANSACTION_SECONDARY ||
+ si->cmd == SMB_COM_TRANSACTION2_SECONDARY ||
+ si->cmd == SMB_COM_NT_TRANSACT_SECONDARY) {
+ sip =
g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
+ }
}
} else {
/* we have seen this packet before; check the
@@ -17785,6 +17852,12 @@
sip=NULL;
}
}
+ } else {
+ if (si->cmd == SMB_COM_TRANSACTION ||
+ si->cmd == SMB_COM_TRANSACTION2 ||
+ si->cmd == SMB_COM_NT_TRANSACT) {
+ sip =
g_hash_table_lookup(si->ct->primaries, GUINT_TO_POINTER(pid_mid));
+ }
}
if(si->request){
sip = se_alloc(sizeof(smb_saved_info_t));
@@ -17806,6 +17879,13 @@
new_key->frame = sip->frame_req;
new_key->pid_mid = pid_mid;
g_hash_table_insert(si->ct->matched, new_key,
sip);
+
+ /* If it is a TRANSACT cmd, insert in hash */
+ if (si->cmd == SMB_COM_TRANSACTION ||
+ si->cmd == SMB_COM_TRANSACTION2 ||
+ si->cmd == SMB_COM_NT_TRANSACT) {
+ g_hash_table_insert(si->ct->primaries,
GUINT_TO_POINTER(pid_mid), sip);
+ }
}
} else {
/* we have seen this packet before; check the
Index: epan/dissectors/packet-smb.h
===================================================================
--- epan/dissectors/packet-smb.h (revision 42332)
+++ epan/dissectors/packet-smb.h (working copy)
@@ -282,6 +282,9 @@
/* these two tables are used to match requests with responses */
GHashTable *unmatched;
GHashTable *matched;
+ /* This table keeps primary transact requests so secondaries can find
+ them */
+ GHashTable *primaries;
/* This table is used to track TID->services for a conversation */
GHashTable *tid_service;
--
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)
packet-smb.nttrans.patch
Description: Binary data
___________________________________________________________________________ Sent via: Wireshark-dev mailing list <[email protected]> Archives: http://www.wireshark.org/lists/wireshark-dev Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev mailto:[email protected]?subject=unsubscribe
