📄 snort_dce2.c
字号:
/**************************************************************************** * Copyright (C) 2008-2008 Sourcefire,Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation. You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * **************************************************************************** * ****************************************************************************/#include "snort_dce2.h"#include "dce2_config.h"#include "dce2_utils.h"#include "dce2_list.h"#include "dce2_stats.h"#include "dce2_session.h"#include "dce2_event.h"#include "dce2_smb.h"#include "dce2_udp.h"#include "dce2_tcp.h"#include "dce2_http.h"#include "dce2_co.h"#include "dce2_cl.h"#include "dce2_memory.h"#include "sf_dynamic_preprocessor.h"#include "stream_api.h"#include "sfrt.h"#include <pcap.h>/******************************************************************** * Global variables ********************************************************************/SFSnortPacket *dce2_smb_seg_rpkt = NULL;SFSnortPacket *dce2_smb_trans_rpkt = NULL;SFSnortPacket *dce2_smb_co_seg_rpkt = NULL;SFSnortPacket *dce2_smb_co_frag_rpkt = NULL;SFSnortPacket *dce2_tcp_co_seg_rpkt = NULL;SFSnortPacket *dce2_tcp_co_frag_rpkt = NULL;SFSnortPacket *dce2_udp_cl_frag_rpkt = NULL;#ifdef SUP_IP6SFSnortPacket *dce2_smb_seg_rpkt6 = NULL;SFSnortPacket *dce2_smb_trans_rpkt6 = NULL;SFSnortPacket *dce2_smb_co_seg_rpkt6 = NULL;SFSnortPacket *dce2_smb_co_frag_rpkt6 = NULL;SFSnortPacket *dce2_tcp_co_seg_rpkt6 = NULL;SFSnortPacket *dce2_tcp_co_frag_rpkt6 = NULL;SFSnortPacket *dce2_udp_cl_frag_rpkt6 = NULL;#endifDCE2_CStack *dce2_pkt_stack = NULL;DCE2_ProtoIds dce2_proto_ids;static int dce2_detected = 0;/******************************************************************** * Extern variables ********************************************************************/extern DCE2_GlobalConfig *dce2_gconfig;extern DCE2_ServerConfig *dce2_dconfig;extern table_t *dce2_sconfigs;extern DCE2_MemState dce2_mem_state;extern DynamicPreprocessorData _dpd;extern DCE2_Stats dce2_stats;/******************************************************************** * Macros ********************************************************************/#define DCE2_PKT_STACK__SIZE 10/******************************************************************** * Private function prototypes ********************************************************************/static DCE2_SsnData * DCE2_NewSession(SFSnortPacket *);static DCE2_TransType DCE2_GetTransport(SFSnortPacket *, const DCE2_ServerConfig *, int *);static DCE2_TransType DCE2_GetDetectTransport(SFSnortPacket *, const DCE2_ServerConfig *);static DCE2_TransType DCE2_GetAutodetectTransport(SFSnortPacket *, const DCE2_ServerConfig *);static DCE2_Ret DCE2_SetSsnState(DCE2_SsnData *, SFSnortPacket *);static void DCE2_SetNoInspect(DCE2_SsnData *);static void DCE2_InitTcpRpkt(SFSnortPacket *);static void DCE2_InitUdpRpkt(SFSnortPacket *);static void DCE2_InitCommonRpkt(SFSnortPacket *);#ifdef SUP_IP6static void DCE2_InitTcp6Rpkt(SFSnortPacket *p);static void DCE2_InitUdp6Rpkt(SFSnortPacket *p);static void DCE2_InitCommonRpkt6(SFSnortPacket *);#endifstatic SFSnortPacket * DCE2_AllocPkt(void);static void DCE2_ServerConfigCleanup(void *);/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/static DCE2_SsnData * DCE2_NewSession(SFSnortPacket *p){ DCE2_SsnData *sd = NULL; DCE2_TransType trans; StreamAppDataFree sdfree; const DCE2_ServerConfig *sc = DCE2_ScGetConfig(p); int autodetected = 0; trans = DCE2_GetTransport(p, sc, &autodetected); switch (trans) { case DCE2_TRANS_TYPE__SMB: DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "SMB transport.\n"); sd = (DCE2_SsnData *)DCE2_SmbSsnInit(); sdfree = DCE2_SmbSsnFree; break; case DCE2_TRANS_TYPE__TCP: case DCE2_TRANS_TYPE__TCP_PENDING: DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "TCP transport.\n"); sd = (DCE2_SsnData *)DCE2_TcpSsnInit(); sdfree = DCE2_TcpSsnFree; break; case DCE2_TRANS_TYPE__UDP: DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "UDP transport.\n"); sd = (DCE2_SsnData *)DCE2_UdpSsnInit(); sdfree = DCE2_UdpSsnFree; break; case DCE2_TRANS_TYPE__HTTP_PROXY: DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "RPC over HTTP proxy transport.\n"); sd = (DCE2_SsnData *)DCE2_HttpProxySsnInit(); sdfree = DCE2_HttpSsnFree; break; case DCE2_TRANS_TYPE__HTTP_SERVER: DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "RPC over HTTP server transport.\n"); sd = (DCE2_SsnData *)DCE2_HttpServerSsnInit(); sdfree = DCE2_HttpSsnFree; break; case DCE2_TRANS_TYPE__NONE: DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Not configured to look at this traffic " "or unable to autodetect - not inspecting.\n"); return NULL; default: DCE2_Log("%s(%d) => Invalid transport type\n", __FILE__, __LINE__); return NULL; } if (sd == NULL) return NULL; DCE2_SsnSetAppData(p, (void *)sd, sdfree); dce2_stats.sessions++; DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Created new session.\n"); sd->trans = trans; sd->sconfig = sc; if (autodetected) { dce2_stats.sessions_autodetected++;#ifdef DEBUG if (DCE2_SsnFromServer(p)) dce2_stats.autoports[p->src_port][trans]++; else dce2_stats.autoports[p->dst_port][trans]++;#endif DCE2_SsnSetAutodetected(sd); } /* If we've determined a transport, make sure we're doing * reassembly on the session */ if (IsTCP(p)) { int rs_dir = DCE2_SsnGetReassembly(p); if (rs_dir != SSN_DIR_BOTH) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Setting client/server reassembly for this session.\n"); DCE2_SsnSetReassembly(p); } if (!DCE2_SsnIsRebuilt(p)) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Got non-rebuilt packet - flushing.\n"); DCE2_SsnFlush(p); if (DCE2_SsnIsStreamInsert(p)) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n"); return NULL; } } } return sd;}/********************************************************************* * Function: DCE2_Process() * * Purpose: Main entry point for DCE/RPC processing. * * Arguments: * SFSnortPacket * - pointer to packet structure * * Returns: * DCE2_Ret - status * *********************************************************************/DCE2_Ret DCE2_Process(SFSnortPacket *p){ DCE2_SsnData *sd = (DCE2_SsnData *)DCE2_SsnGetAppData(p); if (sd == NULL) { sd = DCE2_NewSession(p); if (sd == NULL) return DCE2_RET__NOT_INSPECTED; } else if (DCE2_SsnNoInspect(sd)) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Session set to not inspect. Returning\n"); return DCE2_RET__NOT_INSPECTED; } else if (IsTCP(p) && !DCE2_SsnIsRebuilt(p)) { if (DCE2_SsnFromServer(p) && (sd->trans == DCE2_TRANS_TYPE__TCP_PENDING)) { if (DCE2_TcpAutodetect(p) != DCE2_TRANS_TYPE__TCP) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Bad autodetect for TCP pending.\n"); DCE2_SetNoInspect(sd); dce2_stats.bad_autodetects++; return DCE2_RET__NOT_INSPECTED; } DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Autodetected server. Changing " "TCP pending to TCP transport.\n"); sd->trans = DCE2_TRANS_TYPE__TCP; } DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Got non-rebuilt packet - flushing opposite direction.\n"); DCE2_SsnFlush(p); if (DCE2_SsnIsStreamInsert(p)) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n"); return DCE2_RET__NOT_INSPECTED; } else { /* We should be doing reassembly both ways at this point */ DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Got non-stream inserted packet - not inspecting\n"); return DCE2_RET__NOT_INSPECTED; } } else if (DCE2_SsnHdrAnomaly(sd) && DCE2_SsnFromServer(p)) { DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Got header anomaly on last packet from client on " "autodetected session. Try to autodetect server packet.\n"); /* This is set if we autodetected the session, but later found protocol anomalies * We probably guessed wrong */ if (DCE2_GetAutodetectTransport(p, sd->sconfig) != sd->trans) { DCE2_SetNoInspect(sd); dce2_stats.bad_autodetects++; return DCE2_RET__NOT_INSPECTED; } DCE2_SsnClearHdrAnomaly(sd); } if (IsTCP(p)) { if (DCE2_SetSsnState(sd, p) != DCE2_RET__SUCCESS) return DCE2_RET__NOT_INSPECTED; } sd->wire_pkt = p; if (DCE2_PushPkt((void *)p) != DCE2_RET__SUCCESS) { DCE2_Log("%s(%d) => Failed to push packet onto packet stack\n", __FILE__, __LINE__); return DCE2_RET__NOT_INSPECTED; } p->flags |= FLAG_DCE_PKT; dce2_detected = 0; switch (sd->trans) { case DCE2_TRANS_TYPE__SMB: DCE2_SmbProcess((DCE2_SmbSsnData *)sd); break; case DCE2_TRANS_TYPE__TCP: case DCE2_TRANS_TYPE__TCP_PENDING: DCE2_TcpProcess((DCE2_TcpSsnData *)sd); break; case DCE2_TRANS_TYPE__UDP: DCE2_UdpProcess((DCE2_UdpSsnData *)sd); break; case DCE2_TRANS_TYPE__HTTP_PROXY: DCE2_HttpProcessProxy((DCE2_HttpSsnData *)sd); break; case DCE2_TRANS_TYPE__HTTP_SERVER: DCE2_HttpProcessServer((DCE2_HttpSsnData *)sd); break; default: DCE2_Log("%s(%d) => Invalid transport type\n", __FILE__, __LINE__); return DCE2_RET__NOT_INSPECTED; } if (!dce2_detected) DCE2_Detect(sd); DCE2_PopPkt(); if (DCE2_SsnHdrAnomaly(sd) && DCE2_SsnFromServer(p)) { /* This is set if we autodetected the session, but later found protocol anomalies * We probably guessed wrong and it's the server */ DCE2_SetNoInspect(sd); dce2_stats.bad_autodetects++; } if (dce2_mem_state == DCE2_MEM_STATE__MEMCAP) DCE2_SetNoInspect(sd); return DCE2_RET__INSPECTED;}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * ********************************************************************/static void DCE2_SetNoInspect(DCE2_SsnData *sd){ if (sd == NULL) return; switch (sd->trans) { case DCE2_TRANS_TYPE__SMB: DCE2_SmbDataFree((DCE2_SmbSsnData *)sd); break; case DCE2_TRANS_TYPE__TCP: case DCE2_TRANS_TYPE__TCP_PENDING: DCE2_TcpDataFree((DCE2_TcpSsnData *)sd); break; case DCE2_TRANS_TYPE__UDP: DCE2_UdpDataFree((DCE2_UdpSsnData *)sd); break; case DCE2_TRANS_TYPE__HTTP_PROXY: case DCE2_TRANS_TYPE__HTTP_SERVER: DCE2_HttpDataFree((DCE2_HttpSsnData *)sd); break; default: DCE2_Log("%s(%d) => Invalid transport type\n", __FILE__, __LINE__); break; } DCE2_SsnSetNoInspect(sd);}/******************************************************************** * Function: * * Purpose: * * Arguments: * * Returns: * DCE2_RET__SUCCESS * DCE2_RET__INSPECTED * DCE2_RET__NOT_INSPECTED * ********************************************************************/static DCE2_Ret DCE2_SetSsnState(DCE2_SsnData *sd, SFSnortPacket *p){ uint32_t pkt_seq = ntohl(p->tcp_header->sequence); DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Payload size: %u\n", p->payload_size); if (DCE2_SsnFromClient(p) && !DCE2_SsnSeenClient(sd)) { int missing = 0; DCE2_DEBUG_MSG(DCE2_DEBUG__MAIN, "Initial client => seq: %u, next seq: %u\n", pkt_seq, pkt_seq + p->payload_size); if (DCE2_SsnIsRebuilt(p)) { switch (DCE2_SsnClientMissedInReassembled(p)) { case SSN_MISSING_BOTH: /* Missed packets before and after this one */ case SSN_MISSING_BEFORE: /* Missed packets before this one */ missing = 1; break; case SSN_MISSING_AFTER: /* Missed packets after this one */ default: /* Didn't miss any packets */ break; } } if (missing) { /* Try to autodetect */ if (DCE2_GetAutodetectTransport(p, sd->sconfig) != sd->trans) return DCE2_RET__NOT_INSPECTED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -