📄 dce2_smb.c
字号:
/* See if this is something we need to inspect */ if (!DCE2_SmbInspect(ssd, smb_hdr)) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Not inspecting SMB message. Ignoring %u bytes.\n", nb_need); *ignore_bytes = nb_need; dce2_stats.smb_ignored_bytes += *ignore_bytes; continue; } if (DCE2_SmbHdrChecks(ssd, smb_hdr) != DCE2_RET__SUCCESS) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Bad SMB header. Ignoring %u bytes.\n", nb_need); *ignore_bytes = nb_need; dce2_stats.smb_ignored_bytes += *ignore_bytes; continue; } }#if 0 /* XXX Need to determine some reasonable NBSS length for DCE/RPC requests * less we get DoSed. Maybe get Negotiate protocol response and use max buf size? */ /* Alert on nb_len > max negotiated length, but continue processing */ if (nb_len > SOME_MAX_LIMIT) { ssd->ignore_bytes = nb_len - SOME_MAX_LIMIT; dce2_stats.smb_ignored_bytes += *ignore_bytes; nb_len = SOME_MAX_LIMIT; }#endif /* It's something we want to inspect so make sure we have the full NBSS packet */ if (data_len < nb_need) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Data len(%u) < NetBIOS SS header + NetBIOS len(%u). " "Queueing data.\n", data_len, nb_len); seg->nb_len = nb_len; DCE2_SmbHandleSegmentation(seg, data_ptr, data_len, nb_need, &data_used); return; } DCE2_SmbProcessData(ssd, data_ptr, nb_need); /* data_len >= nb_need so it's < UINT16_MAX */ DCE2_MOVE(data_ptr, data_len, (uint16_t)nb_need); } else { const SmbNtHdr *smb_hdr = NULL; const NbssHdr *nb_hdr; uint16_t data_used; uint32_t nb_need; DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Segmentation handling => current buffer " "length: %u\n", DCE2_BufferLength(seg->buf)); /* Not enough data yet for NetBIOS header ... add to segmentation buffer */ if (DCE2_BufferLength(seg->buf) < nb_hdr_need) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Seg buf len(%u) < NetBIOS SS header(%u). " "Queueing data.\n", DCE2_BufferLength(seg->buf), nb_hdr_need); status = DCE2_SmbHandleSegmentation(seg, data_ptr, data_len, nb_hdr_need, &data_used); if (status != DCE2_RET__SUCCESS) return; /* We've got the NetBIOS header */ DCE2_MOVE(data_ptr, data_len, data_used); seg->nb_len = NbssLen((NbssHdr *)DCE2_BufferData(seg->buf)); DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "SEG: NetBIOS SS len: %u\n", seg->nb_len); /* Only look at session messages - these contain SMBs */ if (DCE2_NbssHdrChecks(ssd, (NbssHdr *)DCE2_BufferData(seg->buf)) != DCE2_RET__SUCCESS) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Not a NetBIOS Session Message. " "Ignoring %u bytes.\n", seg->nb_len); *ignore_bytes = seg->nb_len; dce2_stats.smb_ignored_bytes += *ignore_bytes; DCE2_BufferEmpty(seg->buf); continue; } } nb_hdr = (NbssHdr *)DCE2_BufferData(seg->buf); nb_need = nb_hdr_need + seg->nb_len; /* If we're not in block raw mode or we're waiting for server block raw response * and we don't yet have enough data in segmentation buffer for SMB header */ if (!DCE2_SmbIsRawData(ssd) && (DCE2_BufferLength(seg->buf) < smb_hdr_need)) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Seg buf len(%u) < NetBIOS SS header + SMB header(%u). " "Queueing data.\n", DCE2_BufferLength(seg->buf), smb_hdr_need); status = DCE2_SmbHandleSegmentation(seg, data_ptr, data_len, smb_hdr_need, &data_used); if (status != DCE2_RET__SUCCESS) return; /* We've got the SMB header */ DCE2_MOVE(data_ptr, data_len, data_used); smb_hdr = (SmbNtHdr *)((uint8_t *)nb_hdr + sizeof(NbssHdr)); if (!DCE2_SmbInspect(ssd, smb_hdr)) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Not inspecting SMB message. Ignoring %u bytes.\n", seg->nb_len - sizeof(SmbNtHdr)); /* Already gobbled the SMB header so subtract it */ *ignore_bytes = seg->nb_len - sizeof(SmbNtHdr); dce2_stats.smb_ignored_bytes += *ignore_bytes; DCE2_BufferEmpty(seg->buf); continue; } if (DCE2_SmbHdrChecks(ssd, smb_hdr) != DCE2_RET__SUCCESS) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "SEG: Bad SMB header. Ignoring %u bytes.\n", nb_need); *ignore_bytes = seg->nb_len - sizeof(SmbNtHdr); dce2_stats.smb_ignored_bytes += *ignore_bytes; DCE2_BufferEmpty(seg->buf); continue; } } /* It's something we want to inspect so make sure we have the full NBSS packet */ if (DCE2_BufferLength(seg->buf) < nb_need) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Seg buf len(%u) < NetBIOS SS header + seg->nb_len(%u). " "Queueing data.\n", DCE2_BufferLength(seg->buf), seg->nb_len); status = DCE2_SmbHandleSegmentation(seg, data_ptr, data_len, nb_need, &data_used); if (status != DCE2_RET__SUCCESS) return; /* We've got the NetBIOS data */ DCE2_MOVE(data_ptr, data_len, data_used); } DCE2_SmbProcessData(ssd, DCE2_BufferData(seg->buf), DCE2_BufferLength(seg->buf)); DCE2_BufferEmpty(seg->buf); } }}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static int DCE2_SmbInspect(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr){ DCE2_Policy policy = DCE2_ScPolicy(ssd->sd.sconfig); int smb_com = SmbCom(smb_hdr); /* Don't support SMB2 yet */ if (SmbId(smb_hdr) == DCE2_SMB2_ID) return 0; /* See if this is something we need to inspect */ switch (smb_com) { case SMB_COM_NEGPROT: /* Don't really need to look at this */ return 0; case SMB_COM_SESS_SETUP_ANDX: case SMB_COM_LOGOFF_ANDX: case SMB_COM_TREE_CON: case SMB_COM_TREE_CON_ANDX: case SMB_COM_RENAME: break; case SMB_COM_OPEN: case SMB_COM_WRITE_AND_CLOSE: case SMB_COM_READ: case SMB_COM_READ_BLOCK_RAW: case SMB_COM_WRITE_BLOCK_RAW: /* Samba doesn't allow these commands under an IPC tree */ switch (policy) { case DCE2_POLICY__SAMBA: case DCE2_POLICY__SAMBA_3_0_20: case DCE2_POLICY__SAMBA_3_0_22: return 0; default: break; } /* Fall through */ default: if (DCE2_SmbFindTid(ssd, SmbTid(smb_hdr)) != DCE2_RET__SUCCESS) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Couldn't find TID.\n"); if (DCE2_SsnFromClient(ssd->sd.wire_pkt) || (DCE2_SsnFromServer(ssd->sd.wire_pkt) && !ssd->chained_tc)) { dce2_stats.smb_non_ipc_packets++; return 0; } ssd->chained_tc = 0; } break; } return 1;}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static void DCE2_SmbHandleCom(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr, const uint8_t *nb_ptr, uint32_t nb_len){ DCE2_Ret status; DCE2_SmbIncComStat(smb_hdr); /* In case we get a reassembled packet */ ssd->uid = SmbUid(smb_hdr); ssd->tid = SmbTid(smb_hdr); if (SmbType(smb_hdr) == SMB_TYPE__REQUEST) { ssd->req_uid = SmbUid(smb_hdr); ssd->req_tid = SmbTid(smb_hdr); } /* Handle the command */ switch (SmbCom(smb_hdr)) { case SMB_COM_SESS_SETUP_ANDX: DCE2_SmbSessSetupAndX(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_LOGOFF_ANDX: DCE2_SmbLogoffAndX(ssd, smb_hdr, nb_ptr, nb_len, 0); break; case SMB_COM_TREE_CON: status = DCE2_SmbTreeConnect(ssd, smb_hdr, nb_ptr, nb_len); if ((SmbType(smb_hdr) == SMB_TYPE__REQUEST) && (status == DCE2_RET__SUCCESS)) DCE2_SmbTreeConnectEnqueue(ssd, smb_hdr, status); break; case SMB_COM_TREE_CON_ANDX: DCE2_SmbTreeConnectAndX(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_TREE_DIS: DCE2_SmbTreeDisconnect(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_OPEN: DCE2_SmbOpen(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_OPEN_ANDX: DCE2_SmbOpenAndX(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_NT_CREATE_ANDX: DCE2_SmbNtCreateAndX(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_CLOSE: DCE2_SmbClose(ssd, smb_hdr, nb_ptr, nb_len, 0); break; case SMB_COM_TRANS: DCE2_SmbTrans(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_TRANS_SEC: DCE2_SmbTransSec(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_WRITE: DCE2_SmbWrite(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_WRITE_BLOCK_RAW: DCE2_SmbWriteBlockRaw(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_WRITE_ANDX: DCE2_SmbWriteAndX(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_WRITE_AND_CLOSE: DCE2_SmbWriteAndClose(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_READ: DCE2_SmbRead(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_READ_BLOCK_RAW: DCE2_SmbReadBlockRaw(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_READ_ANDX: DCE2_SmbReadAndX(ssd, smb_hdr, nb_ptr, nb_len); break; case SMB_COM_RENAME: DCE2_SmbRename(ssd, smb_hdr, nb_ptr, nb_len); break; default: break; }}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static int DCE2_SmbGetComSize(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr, const SmbCommon *sc, const int com){ const int smb_type = SmbType(smb_hdr); uint8_t wct = SmbWct(sc); int alert = 0; /* XXX Might need to only check to make sure word count is greater than * the smallest word count. Watch out for interim or empty commands */ if (smb_type == SMB_TYPE__REQUEST) { switch (com) { case SMB_COM_NEGPROT: switch (wct) { case 0: break; default: alert = 1; break; } break; case SMB_COM_SESS_SETUP_ANDX: switch (wct) { case 10: case 12: case 13: break; default: alert = 1; break; } break; case SMB_COM_LOGOFF_ANDX: switch (wct) { case 2: break; default: alert = 1; break; } break; case SMB_COM_TREE_CON: switch (wct) { case 0: break; default: alert = 1; break; } break; case SMB_COM_TREE_CON_ANDX: switch (wct) { case 4: break; default: alert = 1; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -