📄 snort_dce2.c
字号:
rpkt->flags |= FLAG_FROM_CLIENT; else rpkt->flags |= FLAG_FROM_SERVER; rpkt->flags |= (rpkt_flag | FLAG_DCE_PKT); rpkt->stream_session_ptr = wire_pkt->stream_session_ptr; return rpkt;}/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/DCE2_Ret DCE2_AddDataToRpkt(SFSnortPacket *rpkt, DCE2_RpktType rtype, const uint8_t *data, uint32_t data_len){ int hdr_overhead = 0; const uint8_t *pkt_data_end; const uint8_t *payload_end; uint16_t ip_len; DCE2_Ret status; if ((rpkt == NULL) || (data == NULL) || (data_len == 0)) return DCE2_RET__ERROR; if (rpkt->payload == NULL) return DCE2_RET__ERROR; /* This is a check to make sure we don't overwrite header data */ switch (rtype) { case DCE2_RPKT_TYPE__SMB_CO_SEG: hdr_overhead = DCE2_MOCK_HDR_LEN__SMB; break; case DCE2_RPKT_TYPE__SMB_CO_FRAG: hdr_overhead = DCE2_MOCK_HDR_LEN__SMB + DCE2_MOCK_HDR_LEN__CO; break; case DCE2_RPKT_TYPE__TCP_CO_FRAG: hdr_overhead = DCE2_MOCK_HDR_LEN__CO; break; case DCE2_RPKT_TYPE__UDP_CL_FRAG: hdr_overhead = DCE2_MOCK_HDR_LEN__CL; break; default: break; } if (rpkt->payload_size < hdr_overhead) return DCE2_RET__ERROR; pkt_data_end = rpkt->pkt_data + DCE2_PKT_SIZE; payload_end = rpkt->payload + rpkt->payload_size; if ((payload_end + data_len) > pkt_data_end) data_len = pkt_data_end - payload_end; status = DCE2_Memcpy((void *)payload_end, (void *)data, (size_t)data_len, (void *)payload_end, (void *)pkt_data_end); if (status != DCE2_RET__SUCCESS) { DCE2_Log("%s(%d) => Failed to copy data into reassembly packet.\n", __FILE__, __LINE__); return DCE2_RET__ERROR; } rpkt->payload_size += (uint16_t)data_len; if (IsUDP(rpkt)) ((UDPHeader *)rpkt->udp_header)->data_length = ntohs((uint16_t)(rpkt->payload_size + UDP_HDR_LEN)); ((struct pcap_pkthdr *)rpkt->pcap_header)->caplen += data_len; ((struct pcap_pkthdr *)rpkt->pcap_header)->len = rpkt->pcap_header->caplen;#ifdef SUP_IP6 if (rpkt->family == AF_INET) { ip_len = (uint16_t)(ntohs(rpkt->ip4h->ip_len) + data_len); rpkt->ip4h->ip_len = ((IPV4Header *)rpkt->ip4_header)->data_length = htons(ip_len); } else { ip_len = (uint16_t)(ntohs(rpkt->ip6h->len) + data_len); rpkt->ip6h->len = htons(ip_len); }#else ip_len = (uint16_t)(ntohs(rpkt->ip4_header->data_length) + data_len); ((IPV4Header *)rpkt->ip4_header)->data_length = htons(ip_len);#endif return DCE2_RET__SUCCESS;}/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/DCE2_Ret DCE2_PushPkt(SFSnortPacket *p){ SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack); if (top_pkt != NULL) { _dpd.logAlerts((void *)top_pkt); _dpd.resetAlerts(); } if (DCE2_CStackPush(dce2_pkt_stack, (void *)p) != DCE2_RET__SUCCESS) return DCE2_RET__ERROR; return DCE2_RET__SUCCESS;}/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/void DCE2_PopPkt(void){ SFSnortPacket *pop_pkt = (SFSnortPacket *)DCE2_CStackPop(dce2_pkt_stack); if (pop_pkt == NULL) { DCE2_Log("%s(%d) => No packet to pop off stack.\n", __FILE__, __LINE__); return; } _dpd.logAlerts((void *)pop_pkt); _dpd.resetAlerts();}/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/void DCE2_Detect(DCE2_SsnData *sd){ SFSnortPacket *top_pkt = (SFSnortPacket *)DCE2_CStackTop(dce2_pkt_stack); if (top_pkt == NULL) { DCE2_Log("%s(%d) => No packet on top of stack.\n", __FILE__, __LINE__); return; } DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Detecting\n"); DCE2_DEBUG_MSG(DCE2_DEBUG__ROPTIONS, "Rule options:\n"); DCE2_DEBUG_CODE(DCE2_DEBUG__ROPTIONS, DCE2_PrintRoptions(&sd->ropts);); DCE2_DEBUG_MSG(DCE2_DEBUG__ROPTIONS, "Payload:\n"); DCE2_DEBUG_CODE(DCE2_DEBUG__MAIN, DCE2_PrintPktData(top_pkt->payload, top_pkt->payload_size);); _dpd.detect(top_pkt); /* Always reset rule option data after detecting */ DCE2_ResetRopts(&sd->ropts); dce2_detected = 1;}/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/uint16_t DCE2_GetRpktMaxData(DCE2_SsnData *sd, DCE2_RpktType rtype){ const SFSnortPacket *p = sd->wire_pkt; uint16_t overhead = 0;#ifndef SUP_IP6 overhead += IP_HDR_LEN;#else if (IS_IP4(p)) overhead += IP_HDR_LEN; else overhead += IP6_HDR_LEN;#endif if (IsTCP(((SFSnortPacket *)p))) overhead += TCP_HDR_LEN; else overhead += UDP_HDR_LEN; switch (rtype) { case DCE2_RPKT_TYPE__SMB_SEG: case DCE2_RPKT_TYPE__SMB_TRANS: break; case DCE2_RPKT_TYPE__SMB_CO_SEG: overhead += DCE2_MOCK_HDR_LEN__SMB; break; case DCE2_RPKT_TYPE__SMB_CO_FRAG: overhead += DCE2_MOCK_HDR_LEN__SMB + DCE2_MOCK_HDR_LEN__CO; break; case DCE2_RPKT_TYPE__TCP_CO_SEG: break; case DCE2_RPKT_TYPE__TCP_CO_FRAG: overhead = DCE2_MOCK_HDR_LEN__CO; break; case DCE2_RPKT_TYPE__UDP_CL_FRAG: overhead = DCE2_MOCK_HDR_LEN__CL; break; default: DCE2_Log("%s(%d) => Invalid reassembly packet type.\n", __FILE__, __LINE__); return 0; } return (IP_MAXPKT - overhead);}/****************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ******************************************************************/ void DCE2_FreeGlobals(void){ if (dce2_gconfig != NULL) { DCE2_Free((void *)dce2_gconfig, sizeof(DCE2_GlobalConfig), DCE2_MEM_TYPE__CONFIG); dce2_gconfig = NULL; } if (dce2_dconfig != NULL) { if (dce2_dconfig->smb_invalid_shares != NULL) { DCE2_ListDestroy(dce2_dconfig->smb_invalid_shares); dce2_dconfig->smb_invalid_shares = NULL; } DCE2_Free((void *)dce2_dconfig, sizeof(DCE2_ServerConfig), DCE2_MEM_TYPE__CONFIG); dce2_dconfig = NULL; } /* Free routing tables and server configurations */ if (dce2_sconfigs != NULL) { /* UnRegister routing table memory */ if (dce2_sconfigs != NULL) DCE2_UnRegMem(sfrt_usage(dce2_sconfigs), DCE2_MEM_TYPE__RT); sfrt_cleanup(dce2_sconfigs, DCE2_ServerConfigCleanup); sfrt_free(dce2_sconfigs); dce2_sconfigs = NULL; } if (dce2_pkt_stack != NULL) { DCE2_CStackDestroy(dce2_pkt_stack); dce2_pkt_stack = NULL; } if (dce2_smb_seg_rpkt != NULL) { DCE2_Free((void *)dce2_smb_seg_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_seg_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_seg_rpkt = NULL; } if (dce2_smb_trans_rpkt != NULL) { DCE2_Free((void *)dce2_smb_trans_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_trans_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_trans_rpkt = NULL; } if (dce2_smb_co_seg_rpkt != NULL) { DCE2_Free((void *)dce2_smb_co_seg_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_co_seg_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_co_seg_rpkt = NULL; } if (dce2_smb_co_frag_rpkt != NULL) { DCE2_Free((void *)dce2_smb_co_frag_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_co_frag_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_co_frag_rpkt = NULL; } if (dce2_tcp_co_seg_rpkt != NULL) { DCE2_Free((void *)dce2_tcp_co_seg_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_tcp_co_seg_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_tcp_co_seg_rpkt = NULL; } if (dce2_tcp_co_frag_rpkt != NULL) { DCE2_Free((void *)dce2_tcp_co_frag_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_tcp_co_frag_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_tcp_co_frag_rpkt = NULL; } if (dce2_udp_cl_frag_rpkt != NULL) { DCE2_Free((void *)dce2_udp_cl_frag_rpkt->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_udp_cl_frag_rpkt, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_udp_cl_frag_rpkt = NULL; }#ifdef SUP_IP6 if (dce2_smb_seg_rpkt6 != NULL) { DCE2_Free((void *)dce2_smb_seg_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_seg_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_seg_rpkt6 = NULL; } if (dce2_smb_trans_rpkt6 != NULL) { DCE2_Free((void *)dce2_smb_trans_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_trans_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_trans_rpkt6 = NULL; } if (dce2_smb_co_seg_rpkt6 != NULL) { DCE2_Free((void *)dce2_smb_co_seg_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_co_seg_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_co_seg_rpkt6 = NULL; } if (dce2_smb_co_frag_rpkt6 != NULL) { DCE2_Free((void *)dce2_smb_co_frag_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_smb_co_frag_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_smb_co_frag_rpkt6 = NULL; } if (dce2_tcp_co_seg_rpkt6 != NULL) { DCE2_Free((void *)dce2_tcp_co_seg_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_tcp_co_seg_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_tcp_co_seg_rpkt6 = NULL; } if (dce2_tcp_co_frag_rpkt6 != NULL) { DCE2_Free((void *)dce2_tcp_co_frag_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_tcp_co_frag_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_tcp_co_frag_rpkt6 = NULL; } if (dce2_udp_cl_frag_rpkt6 != NULL) { DCE2_Free((void *)dce2_udp_cl_frag_rpkt6->pcap_header, DCE2_PKTH_SIZE, DCE2_MEM_TYPE__INIT); DCE2_Free((void *)dce2_udp_cl_frag_rpkt6, sizeof(SFSnortPacket), DCE2_MEM_TYPE__INIT); dce2_udp_cl_frag_rpkt6 = NULL; }#endif DCE2_EventsFree();}/****************************************************************** * Function: DCE2_ServerConfigCleanup() * * Purpose: Free server configurations in routing table. * Note, this is dependent on the routing table * implementation in how it stores the data associated * with an entry. Since the same server configuration * can exist in the table for multiple entries, the * function stores the last address it's seen and * doesn't free it if it's already been freed. An * alternative would be to duplicate a server config * for each entry, which would require more memory * and an adjustment to the parsing, but would * avoid this issue. * * Arguments: * void * - pointer to data * * Returns: None * ******************************************************************/ static void DCE2_ServerConfigCleanup(void *data){ DCE2_ServerConfig *sc = (DCE2_ServerConfig *)data; if (sc != NULL) { sc->ref_count--; if (sc->ref_count == 0) { if (sc->smb_invalid_shares != NULL) { DCE2_ListDestroy(sc->smb_invalid_shares); sc->smb_invalid_shares = NULL; } DCE2_Free((void *)sc, sizeof(DCE2_ServerConfig), DCE2_MEM_TYPE__CONFIG); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -