📄 dce2_smb.c
字号:
* Returns: * ********************************************************************/static DCE2_Ret DCE2_NbssHdrChecks(DCE2_SmbSsnData *ssd, const NbssHdr *nb_hdr){ const SFSnortPacket *p = ssd->sd.wire_pkt; int is_seg_buf = DCE2_SmbIsSegBuf(ssd, (uint8_t *)nb_hdr); switch (NbssType(nb_hdr)) { case NBSS_SESSION_TYPE__MESSAGE: /* Only want to look at session messages */ DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "NetBIOS SS type: Message.\n"); if (!DCE2_SmbIsRawData(ssd)) { uint32_t nb_len = NbssLen(nb_hdr); if (nb_len < sizeof(SmbNtHdr)) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "NetBIOS SS len(%u) < SMB header len(%u). " "Ignoring %u bytes.\n", nb_len, sizeof(SmbNtHdr), sizeof(NbssHdr) + nb_len); if (is_seg_buf) DCE2_SmbSegAlert(ssd, DCE2_EVENT__SMB_NB_LT_SMBHDR); else DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_NB_LT_SMBHDR, nb_len, sizeof(SmbNtHdr)); return DCE2_RET__IGNORE; } } return DCE2_RET__SUCCESS; case NBSS_SESSION_TYPE__REQUEST: dce2_stats.smb_nbss_not_message++; DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "NetBIOS SS type: Request.\n"); if (DCE2_SsnFromServer(p)) { if (is_seg_buf) DCE2_SmbSegAlert(ssd, DCE2_EVENT__SMB_BAD_NBSS_TYPE); else DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_BAD_NBSS_TYPE); } break; case NBSS_SESSION_TYPE__POS_RESPONSE: case NBSS_SESSION_TYPE__NEG_RESPONSE: case NBSS_SESSION_TYPE__RETARGET_RESPONSE: dce2_stats.smb_nbss_not_message++; DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "NetBIOS SS type: Response, Negative response or Retarget response.\n"); if (DCE2_SsnFromClient(p)) { if (is_seg_buf) DCE2_SmbSegAlert(ssd, DCE2_EVENT__SMB_BAD_NBSS_TYPE); else DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_BAD_NBSS_TYPE); } break; case NBSS_SESSION_TYPE__KEEP_ALIVE: dce2_stats.smb_nbss_not_message++; DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "NetBIOS SS type: Keep alive.\n"); break; default: dce2_stats.smb_nbss_not_message++; DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "NetBIOS SS type: Invalid.\n"); if (is_seg_buf) DCE2_SmbSegAlert(ssd, DCE2_EVENT__SMB_BAD_NBSS_TYPE); else DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_BAD_NBSS_TYPE); break; } return DCE2_RET__IGNORE;}/******************************************************************** * Function: DCE2_SmbHdrChecks() * * Checks some relevant fields in the header to make sure they're * sane. * * Arguments: * DCE2_SmbSsnData * * Pointer to the session data structure. * SmbNtHdr * * Pointer to the header struct layed over the packet data. * * Returns: * DCE2_Ret * DCE2_RET__IGNORE if we should continue processing, but * ignore data because of the error. * DCE2_RET__SUCCESS if we should continue processing. * ********************************************************************/static DCE2_Ret DCE2_SmbHdrChecks(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr){ const SFSnortPacket *p = ssd->sd.wire_pkt; int is_seg_buf = DCE2_SmbIsSegBuf(ssd, (uint8_t *)smb_hdr); if ((DCE2_SsnFromServer(p) && (SmbType(smb_hdr) == SMB_TYPE__REQUEST)) || (DCE2_SsnFromClient(p) && (SmbType(smb_hdr) == SMB_TYPE__RESPONSE))) { if (is_seg_buf) DCE2_SmbSegAlert(ssd, DCE2_EVENT__SMB_BAD_TYPE); else DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_BAD_TYPE); return DCE2_RET__IGNORE; } if (SmbId(smb_hdr) != DCE2_SMB_ID) { if (is_seg_buf) DCE2_SmbSegAlert(ssd, DCE2_EVENT__SMB_BAD_ID); else DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_BAD_ID); return DCE2_RET__IGNORE; } return DCE2_RET__SUCCESS;}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static void DCE2_SmbSessSetupAndX(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr, const uint8_t *nb_ptr, uint32_t nb_len){ const int smb_com = SMB_COM_SESS_SETUP_ANDX; const int smb_type = SmbType(smb_hdr); const SmbAndXCommon *andx = (SmbAndXCommon *)nb_ptr; int com_size, bcc; if (smb_type == SMB_TYPE__RESPONSE) { const SmbEmptyCom *ec = (SmbEmptyCom *)nb_ptr; if (DCE2_SmbCheckComSize(ssd, nb_len, sizeof(SmbEmptyCom), smb_com) != DCE2_RET__SUCCESS) return; /* Server didn't accept client request */ if ((SmbEmptyComWct(ec) == 0) && (SmbEmptyComBcc(ec) == 0) && SmbError(smb_hdr)) return; } if (DCE2_SmbCheckComSize(ssd, nb_len, sizeof(SmbAndXCommon), smb_com) != DCE2_RET__SUCCESS) return; com_size = DCE2_SmbGetComSize(ssd, smb_hdr, (SmbCommon *)andx, smb_com); if ((com_size < 0) || (DCE2_SmbCheckComSize(ssd, nb_len, (uint16_t)com_size, smb_com) != DCE2_RET__SUCCESS)) return; DCE2_MOVE(nb_ptr, nb_len, com_size); bcc = DCE2_SmbGetBcc(ssd, smb_hdr, (SmbCommon *)andx, (uint16_t)com_size, smb_com); if ((bcc < 0) || (DCE2_SmbCheckBcc(ssd, nb_len, (uint16_t)bcc, smb_com) != DCE2_RET__SUCCESS)) return; DCE2_MOVE(nb_ptr, nb_len, bcc); if (smb_type == SMB_TYPE__RESPONSE) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Inserting uid: %u\n", SmbUid(smb_hdr)); DCE2_SmbInsertUid(ssd, SmbUid(smb_hdr)); } if (SmbAndXCom2(andx) != SMB_COM_NO_ANDX_COMMAND) DCE2_SmbChained(ssd, smb_hdr, andx, smb_com, nb_ptr, nb_len);}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static void DCE2_SmbLogoffAndX(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr, const uint8_t *nb_ptr, uint32_t nb_len, int ssx_chained){ const int smb_com = SMB_COM_LOGOFF_ANDX; const int smb_type = SmbType(smb_hdr); const SmbAndXCommon *andx = (SmbAndXCommon *)nb_ptr; int com_size, bcc; if (smb_type == SMB_TYPE__RESPONSE) { SmbEmptyCom *ec = (SmbEmptyCom *)nb_ptr; if (DCE2_SmbCheckComSize(ssd, nb_len, sizeof(SmbEmptyCom), smb_com) != DCE2_RET__SUCCESS) return; /* Server didn't accept client request */ if ((SmbEmptyComWct(ec) == 0) && (SmbEmptyComBcc(ec) == 0) && SmbError(smb_hdr)) return; } if (DCE2_SmbCheckComSize(ssd, nb_len, sizeof(SmbAndXCommon), smb_com) != DCE2_RET__SUCCESS) return; com_size = DCE2_SmbGetComSize(ssd, smb_hdr, (SmbCommon *)andx, smb_com); if ((com_size < 0) || (DCE2_SmbCheckComSize(ssd, nb_len, (uint16_t)com_size, smb_com) != DCE2_RET__SUCCESS)) return; DCE2_MOVE(nb_ptr, nb_len, com_size); bcc = DCE2_SmbGetBcc(ssd, smb_hdr, (SmbCommon *)andx, (uint16_t)com_size, smb_com); if ((bcc < 0) || (DCE2_SmbCheckBcc(ssd, nb_len, (uint16_t)bcc, smb_com) != DCE2_RET__SUCCESS)) return; /* Assume above checks are sufficient such that this will succeed */ if (smb_type == SMB_TYPE__REQUEST) { /* If there is a SessionSetupAndX chaining the LogoffAndX, the LogoffAndX will * apply to the newly created Uid created by the preceding SessionSetupAndX. * Don't remove the client request Uid */ if (!ssx_chained) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Removing uid: %u\n", SmbUid(smb_hdr)); DCE2_SmbRemoveUid(ssd, SmbUid(smb_hdr)); } } else { /* Should only apply to Samba */ if (ssx_chained) { DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Removing uid: %u\n", SmbUid(smb_hdr)); DCE2_SmbRemoveUid(ssd, SmbUid(smb_hdr)); } switch (DCE2_ScPolicy(ssd->sd.sconfig)) { case DCE2_POLICY__WIN2000: case DCE2_POLICY__WINXP: case DCE2_POLICY__WINVISTA: case DCE2_POLICY__WIN2003: /* Windows responds to a chained LogoffAndX => SessionSetupAndX with a * word count 3 LogoffAndX without the chained SessionSetupAndX */ if (SmbWct((SmbCommon *)andx) == 3) DCE2_SmbInsertUid(ssd, SmbUid(smb_hdr)); break; default: break; } } DCE2_MOVE(nb_ptr, nb_len, bcc); if (SmbAndXCom2(andx) != SMB_COM_NO_ANDX_COMMAND) DCE2_SmbChained(ssd, smb_hdr, andx, smb_com, nb_ptr, nb_len);}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static DCE2_Ret DCE2_SmbTreeConnect(DCE2_SmbSsnData *ssd, const SmbNtHdr *smb_hdr, const uint8_t *nb_ptr, uint32_t nb_len){ const int smb_com = SMB_COM_TREE_CON; const int smb_type = SmbType(smb_hdr); const SmbCommon *sc = (SmbCommon *)nb_ptr; int com_size, bcc; /* Don't care what we return for the server so just return success */ if (smb_type == SMB_TYPE__RESPONSE) { int is_ipc; if (ssd->tc_queue == NULL) return DCE2_RET__SUCCESS; if (DCE2_SsnAlerted(&ssd->sd, DCE2_EVENT__SMB_EXCESSIVE_TREE_CONNECTS)) { /* Assume they're all IPC. Want to see what's going on */ DCE2_DEBUG_MSG(DCE2_DEBUG__SMB, "Excessive tree connects. Inserting tid: %u\n", SmbTid(smb_hdr)); DCE2_SmbInsertTid(ssd, SmbTid(smb_hdr)); } is_ipc = (int)(uintptr_t)DCE2_CQueueDequeue(ssd->tc_queue); if (is_ipc != DCE2_TC__IPC) return DCE2_RET__SUCCESS; /* Didn't get a positive response */ if (SmbError(smb_hdr)) return DCE2_RET__SUCCESS; } if (DCE2_SmbCheckComSize(ssd, nb_len, sizeof(SmbCommon), smb_com) != DCE2_RET__SUCCESS) return DCE2_RET__ERROR; com_size = DCE2_SmbGetComSize(ssd, smb_hdr, sc, smb_com); if ((com_size < 0) || (DCE2_SmbCheckComSize(ssd, nb_len, (uint16_t)com_size, smb_com) != DCE2_RET__SUCCESS)) return DCE2_RET__ERROR; DCE2_MOVE(nb_ptr, nb_len, com_size); bcc = DCE2_SmbGetBcc(ssd, smb_hdr, sc, (uint16_t)com_size, smb_com); if ((bcc < 0) || (DCE2_SmbCheckBcc(ssd, nb_len, (uint16_t)bcc, smb_com) != DCE2_RET__SUCCESS)) return DCE2_RET__ERROR; if (smb_type == SMB_TYPE__REQUEST) { const uint8_t *bs = NULL; unsigned int bs_count = 0; const uint8_t ipc_unicode[] = {'I', '\0', 'P', '\0', 'C', '\0', '$', '\0', '\0', '\0'}; const uint8_t ipc_ascii[] = {'I', 'P', 'C', '$', '\0'}; const uint8_t *ipc_chars; unsigned int ipc_len; unsigned int i; /* Have at least 4 bytes */ /* If unicode flag is set, strings, except possibly the service string * are going to be unicode. The NT spec specifies that unicode strings * must be word aligned with respect to the beginning of the SMB and that for * type-prefixed strings (this case), the padding byte is found after the * type format byte */ /* This byte will realign things. */ if (*nb_ptr != SMB_FMT__ASCII) { DCE2_Alert(&ssd->sd, DCE2_EVENT__SMB_BAD_FORMAT, dce2_smb_coms[smb_com], *nb_ptr); return DCE2_RET__ERROR; } DCE2_MOVE(nb_ptr, nb_len, 1); /* IPC$ does not need to be case insensitive. And the case sensitivity flag in * the SMB header doesn't seem to have any effect on this. */ while ((bs = memchr(nb_ptr, '\\', nb_len)) != NULL) { DCE2_MOVE(nb_ptr, nb_len, (bs - nb_ptr) + 1); bs_count++; } if (SmbUnicode(smb_hdr) && (nb_len > 0)) { DCE2_MOVE(nb_ptr, nb_len, 1); }#if 0 /* more than \\path\IPC$ */ switch (DCE2_ScPolicy(ssd->sd.sconfig)) { case DCE2_POLICY__WIN2000: case DCE2_POLICY__WINXP: case DCE2_POLICY__WINVISTA: case DCE2_POLICY__WIN2003: if (bs_count > 3) { /* XXX Alert */ } break; default: break; }#endif /* Check for invalid shares first */ if ((DCE2_ScSmbInvalidShares(ssd->sd.sconfig) != NULL) && (nb_len > 0)) { DCE2_SmbInvalidShareCheck(ssd, smb_hdr, nb_ptr, nb_len); } /* Set appropriate array and length */ if (SmbUnicode(smb_hdr)) { ipc_chars = ipc_unicode; ipc_len = sizeof(ipc_unicode); } else { ipc_chars = ipc_ascii; ipc_len = sizeof(ipc_ascii); } /* Make sure we have enough data */ if (nb_len < ipc_len) r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -