void RZBProcess(void *p, void *context) { SFSnortPacket *sp = (SFSnortPacket *)p; // preconditions - what we registered for assert(IsTCP(sp)); // Only rebuilt packets from server if (sp->src_port == 80 && !(sp->flags & FLAG_REBUILT_STREAM) && sp->payload_size != 0) { ProcessFromServer(sp); return; } // No rebuilt packets to server, and only packets with data if(sp->dst_port == 80 && !(sp->flags & FLAG_REBUILT_STREAM) && sp->payload_size != 0) { ProcessFromClient(sp); return; } if(sp->dst_port == 25 && (sp->flags & FLAG_REBUILT_STREAM) && sp->payload_size != 0) { smtpdumpereval(sp); return; } return; }
/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/ static DCE2_TransType DCE2_GetDetectTransport(SFSnortPacket *p, const DCE2_ServerConfig *sc) { DCE2_TransType trans = DCE2_TRANS_TYPE__NONE; uint16_t port; if (DCE2_SsnFromServer(p)) port = p->src_port; else port = p->dst_port; /* Check our configured ports to see if we should continue processing */ if (IsTCP(p)) { if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__SMB)) trans = DCE2_TRANS_TYPE__SMB; else if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__TCP)) trans = DCE2_TRANS_TYPE__TCP; else if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_PROXY)) trans = DCE2_TRANS_TYPE__HTTP_PROXY; else if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_SERVER)) trans = DCE2_TRANS_TYPE__HTTP_SERVER; } else /* it's UDP */ { if (DCE2_ScIsDetectPortSet(sc, port, DCE2_TRANS_TYPE__UDP)) trans = DCE2_TRANS_TYPE__UDP; } return trans; }
/* * Function: SMTPFunction(Packet *) * * Purpose: Perform the preprocessor's intended function. This can be * simple (statistics collection) or complex (IP defragmentation) * as you like. Try not to destroy the performance of the whole * system by trying to do too much.... * * Arguments: p => pointer to the current packet data struct * * Returns: void function * */ static void SMTPDetect(void *pkt, void *context) { SFSnortPacket *p = (SFSnortPacket *)pkt; PROFILE_VARS; if(!IsTCP(p)) { return; } PREPROC_PROFILE_START(smtpPerfStats); SnortSMTP(p); PREPROC_PROFILE_END(smtpPerfStats); #ifdef PERF_PROFILING if (smtpDetectCalled) { smtpPerfStats.ticks -= smtpDetectPerfStats.ticks; /* And Reset ticks to 0 */ smtpDetectPerfStats.ticks = 0; smtpDetectCalled = 0; } #endif /* * if you need to issue an alert from your preprocessor, check out * event_wrapper.h, there are some useful helper functions there */ }
/* * Function: FTPTelnetChecks(Packet *p) * * Purpose: This function wraps the functionality in the generic FTPTelnet * processing. We get a Packet structure and pass this into the * FTPTelnet module where the first stage in FTPTelnet is the * Normalization stage where most of the other Snortisms are * taken care of. After that, the modules are generic. * * Arguments: p => pointer to a Packet structure that contains * Snort info about the packet. * * Returns: None * */ void FTPTelnetChecks(void *pkt, void *context) { SFSnortPacket *p = (SFSnortPacket*)pkt; // precondition - what we registered for assert(IsTCP(p) && p->payload && p->payload_size); SnortFTPTelnet(p); }
/********************************************************************* * Function: DCE2_GetTransport() * * Determines whether or not we should look at this traffic and if * so, what transport it should be classified as. * * Arguments: * SFSnortPacket * * Pointer to packet structure. * const DCE2_ServerConfig * * The server configuration associated with the packet's IP. * int * * Pointer to a value that will be filled in with whether * or not the packet was autodetected. * Non-zero if autodetected * Zero if not autodetected * * Returns: * DCE2_TransType * DCE2_TRANS_TYPE__NONE if a transport could not be * determined or target based labeled the session as * traffic we are not interested in. * DCE2_TRANS_TYPE__SMB if the traffic is determined to be * DCE/RPC over SMB. * DCE2_TRANS_TYPE__TCP if the traffic is determined to be * DCE/RPC over TCP. * DCE2_TRANS_TYPE__UDP if the traffic is determined to be * DCE/RPC over UDP. * DCE2_TRANS_TYPE__HTTP_PROXY if the traffic is determined * to be DCE/RPC over HTTP proxy. * DCE2_TRANS_TYPE__HTTP_SERVER if the traffic is determined * to be DCE/RPC over HTTP server. * *********************************************************************/ static DCE2_TransType DCE2_GetTransport(SFSnortPacket *p, const DCE2_ServerConfig *sc, int *autodetected) { DCE2_TransType trans = DCE2_TRANS_TYPE__NONE; #ifdef TARGET_BASED int16_t proto_id = 0; #endif *autodetected = 0; #ifdef TARGET_BASED if (_dpd.isAdaptiveConfigured()) { proto_id = _dpd.sessionAPI->get_application_protocol_id(p->stream_session); if (proto_id == SFTARGET_UNKNOWN_PROTOCOL) return DCE2_TRANS_TYPE__NONE; } if (proto_id != 0) { if (proto_id == dce2_proto_ids.dcerpc) { if (IsTCP(p)) { return DCE2_TRANS_TYPE__TCP; } else { return DCE2_TRANS_TYPE__UDP; } } else if (proto_id == dce2_proto_ids.nbss) { return DCE2_TRANS_TYPE__SMB; } } else #endif { trans = DCE2_GetDetectTransport(p, sc); if (trans == DCE2_TRANS_TYPE__NONE) { trans = DCE2_GetAutodetectTransport(p, sc); *autodetected = 1; } else if ((trans == DCE2_TRANS_TYPE__HTTP_PROXY) && (DCE2_ScAutodetectHttpProxyPorts(sc) == DCE2_CS__ENABLED)) { trans = DCE2_HttpAutodetectProxy(p); *autodetected = 1; } } return trans; }
/********************************************************************* * Function: DCE2_GetAutodetectTransport() * * * Arguments: * * Returns: * *********************************************************************/ static DCE2_TransType DCE2_GetAutodetectTransport(SFSnortPacket *p, const DCE2_ServerConfig *sc) { DCE2_TransType trans = DCE2_TRANS_TYPE__NONE; uint16_t port; if (DCE2_SsnFromServer(p)) port = p->src_port; else port = p->dst_port; if (IsTCP(p)) { /* Look for raw DCE/RCP over TCP first, since it's * more likely not to have configured a port for this. */ if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__TCP)) { trans = DCE2_TcpAutodetect(p); if (trans != DCE2_TRANS_TYPE__NONE) return trans; } if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_SERVER)) { trans = DCE2_HttpAutodetectServer(p); if (trans != DCE2_TRANS_TYPE__NONE) return trans; } if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__HTTP_PROXY)) { trans = DCE2_HttpAutodetectProxy(p); if (trans != DCE2_TRANS_TYPE__NONE) return trans; } if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__SMB)) { trans = DCE2_SmbAutodetect(p); if (trans != DCE2_TRANS_TYPE__NONE) return trans; } } else /* it's UDP */ { if (DCE2_ScIsAutodetectPortSet(sc, port, DCE2_TRANS_TYPE__UDP)) { trans = DCE2_UdpAutodetect(p); if (trans != DCE2_TRANS_TYPE__NONE) return trans; } } return DCE2_TRANS_TYPE__NONE; }
static inline int SIP_RoptDoEval(SFSnortPacket *p) { if ((p->payload_size == 0) || (p->stream_session == NULL) || (!IsTCP(p) && !IsUDP(p))) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "No payload or no " "session pointer or not TCP or UDP - not evaluating.\n")); return 0; } return 1; }
/********************************************************************* * Main entry point for SIP processing. * * Arguments: * SFSnortPacket * - pointer to packet structure * * Returns: * int - SIP_SUCCESS * SIP_FAILURE * *********************************************************************/ static inline int SIP_Process(SFSnortPacket *p, SIPData* sessp) { int status; char* sip_buff = (char*) p->payload; char* end; SIP_Roptions *pRopts; SIPMsg sipMsg; memset(&sipMsg, 0, SIPMSG_ZERO_LEN); /*Input parameters*/ sipMsg.isTcp = IsTCP(p); end = sip_buff + p->payload_size; status = sip_parse(&sipMsg, sip_buff, end); if (SIP_SUCCESS == status) { SIP_overloadURI(p, &sipMsg); /*Update the dialog state*/ SIP_updateDialog(&sipMsg, &(sessp->dialogs), p); } /*Update the session data*/ pRopts = &(sessp->ropts); pRopts->methodFlag = sipMsg.methodFlag; pRopts->header_data = sipMsg.header; pRopts->header_len = sipMsg.headerLen; pRopts->body_len = sipMsg.bodyLen; pRopts->body_data = sipMsg.body_data; pRopts->status_code = sipMsg.status_code; DEBUG_WRAP(DebugMessage(DEBUG_SIP, "SIP message header length: %d\n", sipMsg.headerLen)); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Parsed method: %.*s, Flag: 0x%x\n", sipMsg.methodLen, sipMsg.method, sipMsg.methodFlag)); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Parsed status code: %d\n", sipMsg.status_code)); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Parsed header address: %p.\n", sipMsg.header)); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Parsed body address: %p.\n", sipMsg.body_data)); sip_freeMsg(&sipMsg); return status; }
void FTPDataTelnetChecks(void *pkt, void *context) { SFSnortPacket *p = (SFSnortPacket*)pkt; // precondition - what we registered for assert(IsTCP(p)); if ( _dpd.fileAPI->get_max_file_depth() >= 0 ) { if ( _dpd.sessionAPI->get_application_protocol_id(p->stream_session) == ftp_data_app_id ) { PROFILE_VARS; PREPROC_PROFILE_START(ftpdataPerfStats); SnortFTPData(p); PREPROC_PROFILE_END(ftpdataPerfStats); return; } } if ( !p->payload_size || (p->payload == NULL) ) return; SnortFTPTelnet(p); }
/********************************************************************* * Function: DCE2_Main() * * Purpose: Main entry point for DCE/RPC processing. * * Arguments: * void * - pointer to packet structure * void * - pointer to context * * Returns: None * *********************************************************************/ static void DCE2_Main(void *pkt, void *context) { SFSnortPacket *p = (SFSnortPacket *)pkt; PROFILE_VARS; DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__START_MSG)); sfPolicyUserPolicySet (dce2_config, _dpd.getRuntimePolicy()); #ifdef DEBUG_MSGS if (DCE2_SsnFromServer(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Packet from Server.\n")); } else { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Packet from Client.\n")); } #endif /* No inspection to do */ if ((p->payload_size == 0) || (p->payload == NULL)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "No payload - not inspecting.\n")); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG)); return; } else if (p->stream_session_ptr == NULL) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "No session pointer - not inspecting.\n")); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG)); return; } else if (!IsTCP(p) && !IsUDP(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not UDP or TCP - not inspecting.\n")); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG)); return; } if (IsTCP(p)) { if (DCE2_SsnIsMidstream(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Midstream - not inspecting.\n")); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG)); return; } else if (!DCE2_SsnIsEstablished(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not established - not inspecting.\n")); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG)); return; } } PREPROC_PROFILE_START(dce2_pstat_main); if (DCE2_Process(p) == DCE2_RET__INSPECTED) DCE2_DisableDetect(p); PREPROC_PROFILE_END(dce2_pstat_main); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__ALL, "%s\n", DCE2_DEBUG__END_MSG)); }
/* Main runtime entry point for SIP preprocessor. * Analyzes SIP packets for anomalies/exploits. * * PARAMETERS: * * packetp: Pointer to current packet to process. * contextp: Pointer to context block, not used. * * RETURNS: Nothing. */ static void SIPmain( void* ipacketp, void* contextp ) { SIPData* sessp = NULL; uint8_t source = 0; uint8_t dest = 0; SFSnortPacket* packetp; #ifdef TARGET_BASED int16_t app_id = SFTARGET_UNKNOWN_PROTOCOL; #endif tSfPolicyId policy_id = _dpd.getRuntimePolicy(); PROFILE_VARS; DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__START_MSG)); packetp = (SFSnortPacket*) ipacketp; sfPolicyUserPolicySet (sip_config, policy_id); /* Make sure this preprocessor should run. */ if (( !packetp ) || ( !packetp->payload ) ||( !packetp->payload_size )) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "No payload - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); return; } /* check if we're waiting on stream reassembly */ else if ( packetp->flags & FLAG_STREAM_INSERT) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Stream inserted - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); return; } else if (!IsTCP(packetp) && !IsUDP(packetp)) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Not UDP or TCP - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); return; } PREPROC_PROFILE_START(sipPerfStats); sip_eval_config = sfPolicyUserDataGetCurrent(sip_config); /* Attempt to get a previously allocated SIP block. */ sessp = _dpd.streamAPI->get_application_data(packetp->stream_session_ptr, PP_SIP); if (sessp != NULL) { sip_eval_config = sfPolicyUserDataGet(sessp->config, sessp->policy_id); } if (sessp == NULL) { /* If not doing autodetection, check the ports to make sure this is * running on an SIP port, otherwise no need to examine the traffic. */ #ifdef TARGET_BASED app_id = _dpd.streamAPI->get_application_protocol_id(packetp->stream_session_ptr); if (app_id == SFTARGET_UNKNOWN_PROTOCOL) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Unknown protocol - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); return; } else if (app_id && (app_id != sip_app_id)) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Not SIP - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); return; } else if (!app_id) { #endif source = (uint8_t)CheckSIPPort( packetp->src_port ); dest = (uint8_t)CheckSIPPort( packetp->dst_port ); if ( !source && !dest ) { /* Not one of the ports we care about. */ DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Not SIP ports - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); return; } #ifdef TARGET_BASED } #endif /* Check the stream session. If it does not currently * have our SIP data-block attached, create one. */ sessp = SIPGetNewSession(packetp, policy_id); if ( !sessp ) { /* Could not get/create the session data for this packet. */ DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Create session error - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); return; } } /* Don't process if we've missed packets */ if (sessp->state_flags & SIP_FLG_MISSED_PACKETS) { DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Missed packets - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); return; } /* If we picked up mid-stream or missed any packets (midstream pick up * means we've already missed packets) set missed packets flag and make * sure we don't do any more reassembly on this session */ if (IsTCP(packetp)) { if ((_dpd.streamAPI->get_session_flags(packetp->stream_session_ptr) & SSNFLAG_MIDSTREAM) || _dpd.streamAPI->missed_packets(packetp->stream_session_ptr, SSN_DIR_BOTH)) { _dpd.streamAPI->set_reassembly(packetp->stream_session_ptr, STREAM_FLPOLICY_IGNORE, SSN_DIR_BOTH, STREAM_FLPOLICY_SET_ABSOLUTE); sessp->state_flags |= SIP_FLG_MISSED_PACKETS; DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Missed packets - not inspecting.\n")); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); return; } } /* We're interested in this session. Turn on stream reassembly. */ if ( !(sessp->state_flags & SIP_FLG_REASSEMBLY_SET )) { _dpd.streamAPI->set_reassembly(packetp->stream_session_ptr, STREAM_FLPOLICY_FOOTPRINT, SSN_DIR_BOTH, STREAM_FLPOLICY_SET_ABSOLUTE); sessp->state_flags |= SIP_FLG_REASSEMBLY_SET; } /* * Start process PAYLOAD */ SIP_Process(packetp,sessp); DEBUG_WRAP(DebugMessage(DEBUG_SIP, "%s\n", SIP_DEBUG__END_MSG)); PREPROC_PROFILE_END(sipPerfStats); }
void GetLWPacketDirection(Packet *p, Stream5LWSession *ssn) { #ifndef SUP_IP6 if (p->iph->ip_src.s_addr == ssn->client_ip) { if ( IsTCP(p) ) { if (p->tcph->th_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if ( IsUDP(p) ) { if (p->udph->uh_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if ( IsICMP(p) ) { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->iph->ip_dst.s_addr == ssn->client_ip) { if ( IsTCP(p) ) { if (p->tcph->th_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if ( IsUDP(p) ) { if (p->udph->uh_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if ( IsICMP(p) ) { p->packet_flags |= PKT_FROM_CLIENT; } } else { /* Uh, no match of the packet to the session. */ /* Probably should log an error */ } #else if(IS_IP4(p)) { if (sfip_fast_eq4(&p->ip4h->ip_src, &ssn->client_ip)) { if (p->ip4h->ip_proto == IPPROTO_TCP) { if (p->tcph->th_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->ip4h->ip_proto == IPPROTO_UDP) { if (p->udph->uh_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->ip4h->ip_proto == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } else if (sfip_fast_eq4(&p->ip4h->ip_dst, &ssn->client_ip)) { if (p->ip4h->ip_proto == IPPROTO_TCP) { if (p->tcph->th_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->ip4h->ip_proto == IPPROTO_UDP) { if (p->udph->uh_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->ip4h->ip_proto == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } } else /* IS_IP6(p) */ { if (sfip_fast_eq6(&p->ip6h->ip_src, &ssn->client_ip)) { if (p->ip6h->next == IPPROTO_TCP) { if (p->tcph->th_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->ip6h->next == IPPROTO_UDP) { if (p->udph->uh_sport == ssn->client_port) { p->packet_flags |= PKT_FROM_CLIENT; } else { p->packet_flags |= PKT_FROM_SERVER; } } else if (p->ip6h->next == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } else if (sfip_fast_eq6(&p->ip6h->ip_dst, &ssn->client_ip)) { if (p->ip6h->next == IPPROTO_TCP) { if (p->tcph->th_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->ip6h->next == IPPROTO_UDP) { if (p->udph->uh_dport == ssn->client_port) { p->packet_flags |= PKT_FROM_SERVER; } else { p->packet_flags |= PKT_FROM_CLIENT; } } else if (p->ip6h->next == IPPROTO_ICMP) { p->packet_flags |= PKT_FROM_CLIENT; } } } #endif /* SUP_IP6 */ }
/********************************************************************* * Function: * * Purpose: * * Arguments: * * Returns: * *********************************************************************/ static DCE2_SsnData * DCE2_NewSession(SFSnortPacket *p, tSfPolicyId policy_id) { DCE2_SsnData *sd = NULL; DCE2_TransType trans; const DCE2_ServerConfig *sc = DCE2_ScGetConfig(p); int autodetected = 0; PROFILE_VARS; PREPROC_PROFILE_START(dce2_pstat_new_session); DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Creating new session: ")); trans = DCE2_GetTransport(p, sc, &autodetected); switch (trans) { case DCE2_TRANS_TYPE__SMB: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "SMB transport ... ")); sd = (DCE2_SsnData *)DCE2_SmbSsnInit(p); break; case DCE2_TRANS_TYPE__TCP: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "TCP transport ... ")); sd = (DCE2_SsnData *)DCE2_TcpSsnInit(); break; case DCE2_TRANS_TYPE__UDP: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "UDP transport ... ")); sd = (DCE2_SsnData *)DCE2_UdpSsnInit(); break; case DCE2_TRANS_TYPE__HTTP_PROXY: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "RPC over HTTP proxy transport ... ")); sd = (DCE2_SsnData *)DCE2_HttpProxySsnInit(); break; case DCE2_TRANS_TYPE__HTTP_SERVER: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "RPC over HTTP server transport ... ")); sd = (DCE2_SsnData *)DCE2_HttpServerSsnInit(); break; case DCE2_TRANS_TYPE__NONE: DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Not configured to " "look at this traffic or unable to autodetect - not inspecting.\n")); PREPROC_PROFILE_END(dce2_pstat_new_session); return NULL; default: DCE2_Log(DCE2_LOG_TYPE__ERROR, "%s(%d) Invalid transport type: %d", __FILE__, __LINE__, trans); PREPROC_PROFILE_END(dce2_pstat_new_session); return NULL; } if (sd == NULL) { PREPROC_PROFILE_END(dce2_pstat_new_session); return NULL; } DCE2_SsnSetAppData(p, (void *)sd, DCE2_SsnFree); dce2_stats.sessions++; DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Created (%p)\n", (void *)sd)); sd->trans = trans; sd->server_policy = DCE2_ScPolicy(sc); sd->client_policy = DCE2_POLICY__WINXP; // Default to Windows XP sd->sconfig = sc; sd->wire_pkt = p; sd->policy_id = policy_id; sd->config = dce2_config; ((DCE2_Config *)sfPolicyUserDataGet(sd->config, policy_id))->ref_count++; 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, p); } /* 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 (!_dpd.isPafEnabled() && (rs_dir != SSN_DIR_BOTH)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Setting client/server reassembly to FOOTPRINT for this session.\n")); DCE2_SsnSetReassembly(p); } if (!DCE2_SsnIsRebuilt(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-rebuilt packet\n")); if (DCE2_SsnIsStreamInsert(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n")); PREPROC_PROFILE_END(dce2_pstat_new_session); return NULL; } else if ((DCE2_SsnFromClient(p) && (rs_dir == SSN_DIR_FROM_SERVER)) || (DCE2_SsnFromServer(p) && (rs_dir == SSN_DIR_FROM_CLIENT)) || (rs_dir == SSN_DIR_BOTH)) { /* Reassembly was already set for this session, but stream * decided not to use the packet so it's probably not good */ DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-stream inserted packet - not inspecting\n")); PREPROC_PROFILE_END(dce2_pstat_new_session); return NULL; } } } PREPROC_PROFILE_END(dce2_pstat_new_session); 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) { tSfPolicyId policy_id = _dpd.getNapRuntimePolicy(); DCE2_SsnData *sd = (DCE2_SsnData *)DCE2_SsnGetAppData(p); PROFILE_VARS; PREPROC_PROFILE_START(dce2_pstat_session); if ((sd != NULL) && DCE2_SsnNoInspect(sd)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session set to " "not inspect. Returning\n")); PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } dce2_eval_config = (DCE2_Config *)sfPolicyUserDataGet(dce2_config, policy_id); if (sd != NULL) dce2_eval_config = (DCE2_Config *)sfPolicyUserDataGet(sd->config, sd->policy_id); if (dce2_eval_config == NULL) { PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } if (sd == NULL) { sd = DCE2_NewSession(p, policy_id); if (sd == NULL) { PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } } else { sd->wire_pkt = p; if (_dpd.isPafEnabled() && !DCE2_SsnIsPafActive(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "PAF was aborted on " "one or both sides - aborting session inspection\n")); DCE2_SetNoInspect(sd); PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } if (IsTCP(p) && !DCE2_SsnIsRebuilt(p)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-rebuilt packet " "on session (%p)\n", (void *)sd)); if (DCE2_SsnIsStreamInsert(p)) { if (!_dpd.isPafEnabled()) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Flushing opposite direction.\n")); DCE2_SsnFlush(p); } DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Stream inserted - not inspecting.\n")); } else { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Got non-stream inserted packet " "- not inspecting\n")); } PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } else if (DCE2_SsnAutodetected(sd) && !(p->flags & sd->autodetect_dir)) { /* Try to autodetect in opposite direction */ if ((sd->trans != DCE2_TRANS_TYPE__HTTP_PROXY) && (sd->trans != DCE2_TRANS_TYPE__HTTP_SERVER) && (DCE2_GetAutodetectTransport(p, sd->sconfig) != sd->trans)) { DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Bad autodetect.\n")); DCE2_SetNoInspect(sd); dce2_stats.bad_autodetects++; PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } DCE2_SsnClearAutodetected(sd); } } DEBUG_WRAP(DCE2_DebugMsg(DCE2_DEBUG__MAIN, "Session pointer: %p\n", (void *)sd)); if (IsTCP(p) && (DCE2_SetSsnState(sd, p) != DCE2_RET__SUCCESS)) { PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } if (DCE2_PushPkt((void *)p) != DCE2_RET__SUCCESS) { DCE2_Log(DCE2_LOG_TYPE__ERROR, "%s(%d) Failed to push packet onto packet stack.", __FILE__, __LINE__); PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } p->flags |= FLAG_ALLOW_MULTIPLE_DETECT; dce2_detected = 0; PREPROC_PROFILE_END(dce2_pstat_session); switch (sd->trans) { case DCE2_TRANS_TYPE__SMB: DCE2_SmbProcess((DCE2_SmbSsnData *)sd); break; case DCE2_TRANS_TYPE__TCP: 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(DCE2_LOG_TYPE__ERROR, "%s(%d) Invalid transport type: %d", __FILE__, __LINE__, sd->trans); return DCE2_RET__NOT_INSPECTED; } if (sd->flags & DCE2_SSN_FLAG__NO_INSPECT) { DCE2_SetNoInspect(sd); DCE2_PopPkt(); PREPROC_PROFILE_END(dce2_pstat_session); return DCE2_RET__NOT_INSPECTED; } if (!dce2_detected) DCE2_Detect(sd); DCE2_ResetRopts(&sd->ropts); DCE2_PopPkt(); if (dce2_mem_state == DCE2_MEM_STATE__MEMCAP) { DCE2_SetNoInspect(sd); dce2_mem_state = DCE2_MEM_STATE__OKAY; return DCE2_RET__NOT_INSPECTED; } if (DCE2_SsnAutodetected(sd)) return DCE2_RET__NOT_INSPECTED; return DCE2_RET__INSPECTED; }
/* Main runtime entry point */ static void ProcessModbus(void *ipacketp, void *contextp) { SFSnortPacket *packetp = (SFSnortPacket *)ipacketp; modbus_session_data_t *sessp; PROFILE_VARS; // preconditions - what we registered for assert(IsTCP(packetp) && packetp->payload && packetp->payload_size); PREPROC_PROFILE_START(modbusPerfStats); /* Fetch me a preprocessor config to use with this VLAN/subnet/etc.! */ modbus_eval_config = sfPolicyUserDataGetCurrent(modbus_context_id); /* Look for a previously-allocated session data. */ sessp = _dpd.sessionAPI->get_application_data(packetp->stream_session, PP_MODBUS); if (sessp == NULL) { /* No existing session. Check those ports. */ if (ModbusPortCheck(modbus_eval_config, packetp) != MODBUS_OK) { PREPROC_PROFILE_END(modbusPerfStats); return; } } if ( !PacketHasFullPDU(packetp) && ModbusIsPafActive(packetp) ) { if ( sessp ) { sessp->unit = 0; sessp->func = 0; } /* If a packet is rebuilt, but not a full PDU, then it's garbage that got flushed at the end of a stream. */ if ( packetp->flags & (FLAG_REBUILT_STREAM|FLAG_PDU_HEAD) ) { _dpd.alertAdd(GENERATOR_SPP_MODBUS, MODBUS_BAD_LENGTH, 1, 0, 3, MODBUS_BAD_LENGTH_STR, 0); } PREPROC_PROFILE_END(modbusPerfStats); return; } if (sessp == NULL) { /* Create session data and attach it to the Stream session */ sessp = ModbusCreateSessionData(packetp); if ( !sessp ) { PREPROC_PROFILE_END(modbusPerfStats); return; } } /* When pipelined Modbus PDUs appear in a single TCP segment, the detection engine caches the results of the rule options after evaluating on the first PDU. Setting this flag stops the caching. */ packetp->flags |= FLAG_ALLOW_MULTIPLE_DETECT; /* Do preprocessor-specific detection stuff here */ if (ModbusDecode(modbus_eval_config, packetp) == MODBUS_FAIL) { sessp->unit = 0; sessp->func = 0; } /* That's the end! */ PREPROC_PROFILE_END(modbusPerfStats); }