SIPConfig *getParsingSIPConfig(struct _SnortConfig *sc) { SIPConfig * sip_parsing_config; #ifdef SNORT_RELOAD tSfPolicyUserContextId sip_swap_config = (tSfPolicyUserContextId)_dpd.getRelatedReloadData(sc, "sip"); if (sip_swap_config) sip_parsing_config = sfPolicyUserDataGetCurrent(sip_swap_config); else #endif sip_parsing_config = sfPolicyUserDataGetCurrent(sip_config); return sip_parsing_config; }
static MemBucket * DNP3CreateSessionData(SFSnortPacket *packet) { MemBucket *tmp_bucket = NULL; dnp3_session_data_t *data = NULL; /* Sanity Check */ if (!packet || !packet->stream_session_ptr) return NULL; /* data = (dnp3_session_data_t *)calloc(1, sizeof(dnp3_session_data_t)); */ tmp_bucket = mempool_alloc(dnp3_mempool); if (!tmp_bucket) return NULL; data = (dnp3_session_data_t *)tmp_bucket->data; if (!data) return NULL; /* Attach to Stream5 session */ _dpd.streamAPI->set_application_data(packet->stream_session_ptr, PP_DNP3, tmp_bucket, FreeDNP3Data); /* Not sure when this reference counting stuff got added to the old preprocs */ data->policy_id = _dpd.getRuntimePolicy(); data->context_id = dnp3_context_id; ((dnp3_config_t *)sfPolicyUserDataGetCurrent(dnp3_context_id))->ref_count++; return tmp_bucket; }
/* Responsible for allocating a DNP3 policy. Never returns NULL. */ static inline dnp3_config_t * DNP3PerPolicyInit(struct _SnortConfig *sc, tSfPolicyUserContextId context_id) { tSfPolicyId policy_id = _dpd.getParserPolicy(sc); dnp3_config_t *dnp3_policy = NULL; /* Check for existing policy & bail if found */ sfPolicyUserPolicySet(context_id, policy_id); dnp3_policy = (dnp3_config_t *)sfPolicyUserDataGetCurrent(context_id); if (dnp3_policy != NULL) { DynamicPreprocessorFatalMessage("%s(%d): DNP3 preprocessor can only be " "configured once.\n", *_dpd.config_file, *_dpd.config_line); } /* Allocate new policy */ dnp3_policy = (dnp3_config_t *)calloc(1, sizeof(dnp3_config_t)); if (!dnp3_policy) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "dnp3 preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(context_id, dnp3_policy); return dnp3_policy; }
static void SIPReload(struct _SnortConfig *sc, char *args, void **new_config) { tSfPolicyUserContextId sip_swap_config = (tSfPolicyUserContextId)*new_config; tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SIPConfig * pPolicyConfig = NULL; if (sip_swap_config == NULL) { //create a context sip_swap_config = sfPolicyConfigCreate(); if (sip_swap_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory for SIP config.\n"); } *new_config = (void *)sip_swap_config; } sfPolicyUserPolicySet (sip_swap_config, policy_id); pPolicyConfig = (SIPConfig *)sfPolicyUserDataGetCurrent(sip_swap_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SIP preprocessor can only be configured once.\n"); } pPolicyConfig = (SIPConfig *)calloc(1, sizeof(SIPConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SIP preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(sip_swap_config, pPolicyConfig); SIP_RegRuleOptions(sc); ParseSIPArgs(pPolicyConfig, (u_char *)args); }
/* Retrieves the SSH data block registered with the stream * session associated w/ the current packet. If none exists, * allocates it and registers it with the stream API. * * PARAMETERS: * * packetp: Pointer to the packet from which/in which to * retrieve/store the SSH data block. * * RETURNS: Pointer to an SSH data block, upon success. * NULL, upon failure. */ SSHData * SSHGetNewSession(SFSnortPacket *packetp, tSfPolicyId policy_id) { SSHData* datap = NULL; /* Sanity check(s) */ if (( !packetp ) || ( !packetp->stream_session_ptr )) { return NULL; } datap = (SSHData *)calloc(1, sizeof(SSHData)); if ( !datap ) return NULL; /*Register the new SSH data block in the stream session. */ _dpd.streamAPI->set_application_data( packetp->stream_session_ptr, PP_SSH, datap, FreeSSHData ); datap->policy_id = policy_id; datap->config = ssh_config; ((SSHConfig *)sfPolicyUserDataGetCurrent(ssh_config))->ref_count++; return datap; }
/********************************************************************** * Retrieves the GTP data block registered with the stream * session associated w/ the current packet. If none exists, * allocates it and registers it with the stream API. * * Arguments: * * packetp: Pointer to the packet from which/in which to * retrieve/store the GTP data block. * * RETURNS: Pointer to an GTP data block, upon success. * NULL, upon failure. **********************************************************************/ GTPData * GTPGetNewSession(SFSnortPacket *packetp, tSfPolicyId policy_id) { GTPData* datap = NULL; /* Sanity check(s) */ assert( packetp ); if ( !packetp->stream_session_ptr ) { return NULL; } datap = (GTPData *)calloc(1, sizeof(GTPData)); if ( !datap ) return NULL; /*Register the new GTP data block in the stream session. */ _dpd.streamAPI->set_application_data( packetp->stream_session_ptr, PP_GTP, datap, FreeGTPData ); datap->policy_id = policy_id; datap->config = gtp_config; ((GTPConfig *)sfPolicyUserDataGetCurrent(gtp_config))->ref_count++; gtp_stats.sessions++; DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Number of sessions created: %u\n", gtp_stats.sessions)); return datap; }
static inline int SSLPP_is_encrypted(uint32_t ssl_flags, SFSnortPacket *packet) { SSLPP_config_t *config = NULL; config = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_config); if (config->flags & SSLPP_TRUSTSERVER_FLAG) { if(ssl_flags & SSL_SAPP_FLAG) return SSLPP_TRUE; } if (SSL_IS_CLEAN(ssl_flags)) { if (((ssl_flags & SSLPP_ENCRYPTED_FLAGS) == SSLPP_ENCRYPTED_FLAGS) || ((ssl_flags & SSLPP_ENCRYPTED_FLAGS2) == SSLPP_ENCRYPTED_FLAGS2)) { counts.completed_hs++; return SSLPP_TRUE; } /* Check if we're either midstream or if packets were missed after the * connection was established */ else if ((_dpd.streamAPI->get_session_flags (packet->stream_session_ptr) & SSNFLAG_MIDSTREAM) || (_dpd.streamAPI->missed_packets(packet->stream_session_ptr, SSN_DIR_BOTH))) { if ((ssl_flags & (SSL_CAPP_FLAG | SSL_SAPP_FLAG)) == (SSL_CAPP_FLAG | SSL_SAPP_FLAG)) { return SSLPP_TRUE; } } } return SSLPP_FALSE; }
/********************************************************************** * Retrieves the SIP data block registered with the stream * session associated w/ the current packet. If none exists, * allocates it and registers it with the stream API. * * Arguments: * * packetp: Pointer to the packet from which/in which to * retrieve/store the SIP data block. * * RETURNS: Pointer to an SIP data block, upon success. * NULL, upon failure. **********************************************************************/ SIPData * SIPGetNewSession(SFSnortPacket *packetp, tSfPolicyId policy_id) { SIPData* datap = NULL; static int MaxSessionsAlerted = 0; /* Sanity check(s) */ assert( packetp ); if ( !packetp->stream_session ) { return NULL; } if(numSessions > ((SIPConfig *)sfPolicyUserDataGetCurrent(sip_config))->maxNumSessions) { if (!MaxSessionsAlerted) ALERT(SIP_EVENT_MAX_SESSIONS,SIP_EVENT_MAX_SESSIONS_STR); MaxSessionsAlerted = 1; return NULL; } else { MaxSessionsAlerted = 0; } datap = (SIPData *)calloc(1, sizeof(SIPData)); if ( !datap ) return NULL; /*Register the new SIP data block in the stream session. */ _dpd.sessionAPI->set_application_data( packetp->stream_session, PP_SIP, datap, FreeSIPData ); /* We're interested in this session. Turn on stream reassembly. */ if ( !(_dpd.streamAPI->get_reassembly_direction(packetp->stream_session) & SSN_DIR_BOTH )) { _dpd.streamAPI->set_reassembly(packetp->stream_session, STREAM_FLPOLICY_FOOTPRINT, SSN_DIR_BOTH, STREAM_FLPOLICY_SET_ABSOLUTE); } datap->policy_id = policy_id; datap->config = sip_config; ((SIPConfig *)sfPolicyUserDataGetCurrent(sip_config))->ref_count++; numSessions++; sip_stats.sessions++; DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Number of sessions created: %u\n", numSessions)); return datap; }
static IMAP * IMAP_GetNewSession(SFSnortPacket *p, tSfPolicyId policy_id) { IMAP *ssn; IMAPConfig *pPolicyConfig = NULL; pPolicyConfig = (IMAPConfig *)sfPolicyUserDataGetCurrent(imap_config); DEBUG_WRAP(DebugMessage(DEBUG_IMAP, "Creating new session data structure\n"););
static inline uint32_t SSLPP_process_alert( uint32_t ssn_flags, uint32_t new_flags, SFSnortPacket *packet) { SSLPP_config_t *config = NULL; config = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_config); DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Process Alert\n"););
static POP * POP_GetNewSession(SFSnortPacket *p, tSfPolicyId policy_id) { POP *ssn; POPConfig *pPolicyConfig = NULL; pPolicyConfig = (POPConfig *)sfPolicyUserDataGetCurrent(pop_config); DEBUG_WRAP(DebugMessage(DEBUG_POP, "Creating new session data structure\n"););
/* Initializes the SIP preprocessor module and registers * it in the preprocessor list. * * PARAMETERS: * * argp: Pointer to argument string to process for config * data. * * RETURNS: Nothing. */ static void SIPInit(struct _SnortConfig *sc, char *argp) { tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SIPConfig *pDefaultPolicyConfig = NULL; SIPConfig *pPolicyConfig = NULL; if (sip_config == NULL) { //create a context sip_config = sfPolicyConfigCreate(); if (sip_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for SIP config.\n"); } _dpd.addPreprocConfCheck(sc, SIPCheckConfig); _dpd.registerPreprocStats(SIP_NAME, SIP_PrintStats); _dpd.addPreprocExit(SIPCleanExit, NULL, PRIORITY_LAST, PP_SIP); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("sip", (void *)&sipPerfStats, 0, _dpd.totalPerfStats, NULL); #endif #ifdef TARGET_BASED sip_app_id = _dpd.findProtocolReference("sip"); if (sip_app_id == SFTARGET_UNKNOWN_PROTOCOL) sip_app_id = _dpd.addProtocolReference("sip"); // register with session to handle applications _dpd.sessionAPI->register_service_handler( PP_SIP, sip_app_id ); #endif } sfPolicyUserPolicySet (sip_config, policy_id); pDefaultPolicyConfig = (SIPConfig *)sfPolicyUserDataGetDefault(sip_config); pPolicyConfig = (SIPConfig *)sfPolicyUserDataGetCurrent(sip_config); if ((pPolicyConfig != NULL) && (pDefaultPolicyConfig == NULL)) { DynamicPreprocessorFatalMessage("SIP preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SIPConfig *)calloc(1, sizeof(SIPConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SIP preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(sip_config, pPolicyConfig); SIP_RegRuleOptions(sc); ParseSIPArgs(pPolicyConfig, (u_char *)argp); }
static void SIPReload(char *args) { tSfPolicyId policy_id = _dpd.getParserPolicy(); SIPConfig * pPolicyConfig = NULL; if (sip_swap_config == NULL) { //create a context sip_swap_config = sfPolicyConfigCreate(); if (sip_swap_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for SIP config.\n"); } } sfPolicyUserPolicySet (sip_swap_config, policy_id); pPolicyConfig = (SIPConfig *)sfPolicyUserDataGetCurrent(sip_swap_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SIP preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SIPConfig *)calloc(1, sizeof(SIPConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SIP preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(sip_swap_config, pPolicyConfig); SIP_RegRuleOptions(); ParseSIPArgs(pPolicyConfig, (u_char *)args); if( pPolicyConfig->disabled ) return; if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupSIP(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreproc( SIPmain, PRIORITY_APPLICATION, PP_SIP, PROTO_BIT__UDP|PROTO_BIT__TCP ); _dpd.addPreprocReloadVerify(SIPReloadVerify); _addPortsToStream5Filter(pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(policy_id); #endif }
/********************************************************************** * Retrieves the SIP data block registered with the stream * session associated w/ the current packet. If none exists, * allocates it and registers it with the stream API. * * Arguments: * * packetp: Pointer to the packet from which/in which to * retrieve/store the SIP data block. * * RETURNS: Pointer to an SIP data block, upon success. * NULL, upon failure. **********************************************************************/ SIPData * SIPGetNewSession(SFSnortPacket *packetp, tSfPolicyId policy_id) { SIPData* datap = NULL; static int MaxSessionsAlerted = 0; /* Sanity check(s) */ assert( packetp ); if ( !packetp->stream_session_ptr ) { return NULL; } if(numSessions > ((SIPConfig *)sfPolicyUserDataGetCurrent(sip_config))->maxNumSessions) { if (!MaxSessionsAlerted) ALERT(SIP_EVENT_MAX_SESSIONS,SIP_EVENT_MAX_SESSIONS_STR); MaxSessionsAlerted = 1; return NULL; } else { MaxSessionsAlerted = 0; } datap = (SIPData *)calloc(1, sizeof(SIPData)); if ( !datap ) return NULL; /*Register the new SIP data block in the stream session. */ _dpd.streamAPI->set_application_data( packetp->stream_session_ptr, PP_SIP, datap, FreeSIPData ); datap->policy_id = policy_id; datap->config = sip_config; ((SIPConfig *)sfPolicyUserDataGetCurrent(sip_config))->ref_count++; numSessions++; sip_stats.sessions++; DEBUG_WRAP(DebugMessage(DEBUG_SIP, "Number of sessions created: %u\n", numSessions)); return datap; }
/* Initializes the File preprocessor module and registers * it in the preprocessor list. * * PARAMETERS: * * argp: Pointer to argument string to process for config * data. * * RETURNS: Nothing. */ static void FileInit(struct _SnortConfig *sc, char *argp) { tSfPolicyId policy_id = _dpd.getParserPolicy(sc); FileInspectConf *pPolicyConfig = NULL; if (file_config == NULL) { /*create a context*/ file_config = sfPolicyConfigCreate(); if (file_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for File config.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupFile(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreprocConfCheck(sc, FileCheckConfig); _dpd.registerPreprocStats(FILE_PREPROC_NAME, print_file_stats); _dpd.addPreprocExit(FileCleanExit, NULL, PRIORITY_LAST, PP_FILE_INSPECT); } sfPolicyUserPolicySet (file_config, policy_id); pPolicyConfig = (FileInspectConf *)sfPolicyUserDataGetCurrent(file_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("File preprocessor can only be " "configured once.\n"); } pPolicyConfig = (FileInspectConf *)calloc(1, sizeof(FileInspectConf)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "File preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(file_config, pPolicyConfig); file_config_parse(pPolicyConfig, (u_char *)argp); FileUpdateConfig(pPolicyConfig, file_config); file_agent_init(pPolicyConfig); _dpd.addPostConfigFunc(sc, file_agent_thread_init, pPolicyConfig); }
static void SSHReload(struct _SnortConfig *sc, char *args, void **new_config) { tSfPolicyUserContextId ssh_swap_config = (tSfPolicyUserContextId)*new_config; tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SSHConfig * pPolicyConfig = NULL; if (ssh_swap_config == NULL) { //create a context ssh_swap_config = sfPolicyConfigCreate(); if (ssh_swap_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for SSH config.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupSSH(): The Stream preprocessor must be enabled.\n"); } *new_config = (void *)ssh_swap_config; } sfPolicyUserPolicySet (ssh_swap_config, policy_id); pPolicyConfig = (SSHConfig *)sfPolicyUserDataGetCurrent(ssh_swap_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSH preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSHConfig *)calloc(1, sizeof(SSHConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SSH preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssh_swap_config, pPolicyConfig); ParseSSHArgs(pPolicyConfig, (u_char *)args); _dpd.addPreproc( sc, ProcessSSH, PRIORITY_APPLICATION, PP_SSH, PROTO_BIT__TCP ); _addPortsToStream5Filter(sc, pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(sc, policy_id); #endif }
static void FileReload(struct _SnortConfig *sc, char *args, void **new_config) { tSfPolicyUserContextId file_swap_config = (tSfPolicyUserContextId)*new_config; tSfPolicyId policy_id = _dpd.getParserPolicy(sc); FileInspectConf * pPolicyConfig = NULL; if (file_swap_config == NULL) { //create a context file_swap_config = sfPolicyConfigCreate(); if (file_swap_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for File config.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupFile(): The Stream preprocessor must be enabled.\n"); } *new_config = (void *)file_swap_config; } sfPolicyUserPolicySet (file_swap_config, policy_id); pPolicyConfig = (FileInspectConf *)sfPolicyUserDataGetCurrent(file_swap_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("File preprocessor can only be " "configured once.\n"); } pPolicyConfig = (FileInspectConf *)calloc(1, sizeof(FileInspectConf)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "File preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(file_swap_config, pPolicyConfig); file_config_parse(pPolicyConfig, (u_char *)args); FileUpdateConfig(pPolicyConfig, file_config); }
/********************************************************************* * Function: DCE2_ReloadServer() * * Purpose: Creates a new DCE/RPC server configuration * * Arguments: snort.conf argument line for the DCE/RPC preprocessor. * * Returns: None * *********************************************************************/ static void DCE2_ReloadServer(char *args) { tSfPolicyId policy_id = _dpd.getParserPolicy(); DCE2_Config *pPolicyConfig = NULL; sfPolicyUserPolicySet (dce2_swap_config, policy_id); pPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_swap_config); if ((pPolicyConfig == NULL) || (pPolicyConfig->gconfig == NULL)) { DCE2_Die("%s(%d) \"%s\" configuration: \"%s\" must be configured " "before \"%s\".", *_dpd.config_file, *_dpd.config_line, DCE2_SNAME, DCE2_GNAME, DCE2_SNAME); } /* Parse configuration args */ DCE2_ServerConfigure(pPolicyConfig, args); }
/* Responsible for allocating a Modbus policy. Never returns NULL. */ static inline modbus_config_t * ModbusPerPolicyInit(tSfPolicyUserContextId context_id) { tSfPolicyId policy_id = _dpd.getParserPolicy(); modbus_config_t *modbus_policy = NULL; /* Check for existing policy & bail if found */ sfPolicyUserPolicySet(context_id, policy_id); modbus_policy = (modbus_config_t *)sfPolicyUserDataGetCurrent(context_id); if (modbus_policy != NULL) { _dpd.fatalMsg("%s(%d) Modbus preprocessor can only be " "configured once.\n", *_dpd.config_file, *_dpd.config_line); } /* Allocate new policy */ modbus_policy = (modbus_config_t *)calloc(1, sizeof(modbus_config_t)); if (!modbus_policy) { _dpd.fatalMsg("%s(%d) Could not allocate memory for " "modbus preprocessor configuration.\n" , *_dpd.config_file, *_dpd.config_line); } sfPolicyUserDataSetCurrent(context_id, modbus_policy); /* Register callbacks that are done for each policy */ _dpd.addPreproc(ProcessModbus, PRIORITY_APPLICATION, PP_MODBUS, PROTO_BIT__TCP); _addPortsToStream5Filter(modbus_policy, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(policy_id); #endif /* Add preprocessor rule options here */ /* _dpd.preprocOptRegister("foo_bar", FOO_init, FOO_rule_eval, free, NULL, NULL, NULL, NULL); */ _dpd.preprocOptRegister("modbus_func", ModbusFuncInit, ModbusRuleEval, free, NULL, NULL, NULL, NULL); _dpd.preprocOptRegister("modbus_unit", ModbusUnitInit, ModbusRuleEval, free, NULL, NULL, NULL, NULL); _dpd.preprocOptRegister("modbus_data", ModbusDataInit, ModbusRuleEval, free, NULL, NULL, NULL, NULL); return modbus_policy; }
static modbus_session_data_t * ModbusCreateSessionData(SFSnortPacket *packet) { modbus_session_data_t *data = NULL; /* Sanity Check */ if (!packet || !packet->stream_session_ptr) return NULL; data = (modbus_session_data_t *)calloc(1, sizeof(modbus_session_data_t)); if (!data) return NULL; /* Attach to Stream5 session */ _dpd.streamAPI->set_application_data(packet->stream_session_ptr, PP_MODBUS, data, FreeModbusData); /* Not sure when this reference counting stuff got added to the old preprocs */ data->policy_id = _dpd.getRuntimePolicy(); data->context_id = modbus_context_id; ((modbus_config_t *)sfPolicyUserDataGetCurrent(modbus_context_id))->ref_count++; return data; }
/* Main runtime entry point for SSH preprocessor. * Analyzes SSH packets for anomalies/exploits. * * PARAMETERS: * * packetp: Pointer to current packet to process. * contextp: Pointer to context block, not used. * * RETURNS: Nothing. */ static void ProcessSSH( void* ipacketp, void* contextp ) { SSHData* sessp = NULL; uint8_t source = 0; uint8_t dest = 0; uint8_t known_port = 0; uint8_t direction; SFSnortPacket* packetp; #ifdef TARGET_BASED int16_t app_id = SFTARGET_UNKNOWN_PROTOCOL; #endif tSfPolicyId policy_id = _dpd.getRuntimePolicy(); PROFILE_VARS; packetp = (SFSnortPacket*) ipacketp; sfPolicyUserPolicySet (ssh_config, policy_id); /* Make sure this preprocessor should run. */ if (( !packetp ) || ( !packetp->payload ) || ( !packetp->payload_size ) || ( !IPH_IS_VALID(packetp) ) || ( !packetp->tcp_header ) || /* check if we're waiting on stream reassembly */ ( packetp->flags & FLAG_STREAM_INSERT)) { return; } PREPROC_PROFILE_START(sshPerfStats); ssh_eval_config = sfPolicyUserDataGetCurrent(ssh_config); /* Attempt to get a previously allocated SSH block. */ sessp = _dpd.streamAPI->get_application_data(packetp->stream_session_ptr, PP_SSH); if (sessp != NULL) { ssh_eval_config = sfPolicyUserDataGet(sessp->config, sessp->policy_id); known_port = 1; } if (sessp == NULL) { /* If not doing autodetection, check the ports to make sure this is * running on an SSH 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) { PREPROC_PROFILE_END(sshPerfStats); return; } if (app_id && (app_id != ssh_app_id)) { PREPROC_PROFILE_END(sshPerfStats); return; } if (app_id == ssh_app_id) { known_port = 1; } if (!app_id) { #endif source = (uint8_t)CheckSSHPort( packetp->src_port ); dest = (uint8_t)CheckSSHPort( packetp->dst_port ); if ( !ssh_eval_config->AutodetectEnabled && !source && !dest ) { /* Not one of the ports we care about. */ PREPROC_PROFILE_END(sshPerfStats); return; } #ifdef TARGET_BASED } #endif /* Check the stream session. If it does not currently * have our SSH data-block attached, create one. */ sessp = SSHGetNewSession(packetp, policy_id); if ( !sessp ) { /* Could not get/create the session data for this packet. */ PREPROC_PROFILE_END(sshPerfStats); return; } /* See if a known server port is involved. */ if (!known_port) { known_port = ( source || dest ? 1 : 0 ); /* If this is a non-SSH port, but autodetect is on, we flag this session to reduce false positives later on. */ if (!known_port && ssh_eval_config->AutodetectEnabled) { sessp->state_flags |= SSH_FLG_AUTODETECTED; } } } /* Don't process if we've missed packets */ if (sessp->state_flags & SSH_FLG_MISSED_PACKETS) 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 ((_dpd.streamAPI->get_session_flags(packetp->stream_session_ptr) & SSNFLAG_MIDSTREAM) || _dpd.streamAPI->missed_packets(packetp->stream_session_ptr, SSN_DIR_BOTH)) { /* Don't turn off reassembly if autodetected since another preprocessor * may actually be looking at this session as well and the SSH * autodetect of this session may be wrong. */ if (!(sessp->state_flags & SSH_FLG_AUTODETECTED)) { _dpd.streamAPI->set_reassembly(packetp->stream_session_ptr, STREAM_FLPOLICY_IGNORE, SSN_DIR_BOTH, STREAM_FLPOLICY_SET_ABSOLUTE); } sessp->state_flags |= SSH_FLG_MISSED_PACKETS; return; } /* We're interested in this session. Turn on stream reassembly. */ if ( !(sessp->state_flags & SSH_FLG_REASSEMBLY_SET )) { _dpd.streamAPI->set_reassembly(packetp->stream_session_ptr, STREAM_FLPOLICY_FOOTPRINT, SSN_DIR_BOTH, STREAM_FLPOLICY_SET_APPEND); sessp->state_flags |= SSH_FLG_REASSEMBLY_SET; } /* Get the direction of the packet. */ direction = ( (packetp->flags & FLAG_FROM_SERVER ) ? SSH_DIR_FROM_SERVER : SSH_DIR_FROM_CLIENT ); if ( !(sessp->state_flags & SSH_FLG_SESS_ENCRYPTED )) { /* If server and client have not performed the protocol * version exchange yet, must look for version strings. */ if ( (sessp->state_flags & SSH_FLG_BOTH_IDSTRING_SEEN) != SSH_FLG_BOTH_IDSTRING_SEEN ) { if ( ProcessSSHProtocolVersionExchange( sessp, packetp, direction, known_port ) == SSH_FAILURE ) { /*Error processing protovers exchange msg */ } PREPROC_PROFILE_END(sshPerfStats); return; } /* Expecting to see the key init exchange at this point * (in SSH2) or the actual key exchange if SSH1 */ if ((( sessp->state_flags & SSH_FLG_V1_KEYEXCH_DONE ) != SSH_FLG_V1_KEYEXCH_DONE ) && ((sessp->state_flags & SSH_FLG_V2_KEXINIT_DONE ) != SSH_FLG_V2_KEXINIT_DONE )) { ProcessSSHKeyInitExchange( sessp, packetp, direction ); PREPROC_PROFILE_END(sshPerfStats); return; } /* If SSH2, need to process the actual key exchange msgs. * The actual key exchange type was negotiated in the * key exchange init msgs. SSH1 won't arrive here. */ ProcessSSHKeyExchange( sessp, packetp, direction ); } else { /* Traffic on this session is currently encrypted. * Two of the major SSH exploits, SSH1 CRC-32 and * the Challenge-Response Overflow attack occur within * the encrypted portion of the SSH session. Therefore, * the only way to detect these attacks is by examining * amounts of data exchanged for anomalies. */ sessp->num_enc_pkts++; if ( sessp->num_enc_pkts <= ssh_eval_config->MaxEncryptedPackets ) { if ( direction == SSH_DIR_FROM_CLIENT ) { sessp->num_client_bytes += packetp->payload_size; if ( sessp->num_client_bytes >= ssh_eval_config->MaxClientBytes ) { /* Probable exploit in progress.*/ if (sessp->version == SSH_VERSION_1) { if ( ssh_eval_config->EnabledAlerts & SSH_ALERT_CRC32 ) { ALERT(SSH_EVENT_CRC32, SSH_EVENT_CRC32_STR); _dpd.streamAPI->stop_inspection( packetp->stream_session_ptr, packetp, SSN_DIR_BOTH, -1, 0 ); } } else { if (ssh_eval_config->EnabledAlerts & SSH_ALERT_RESPOVERFLOW ) { ALERT(SSH_EVENT_RESPOVERFLOW, SSH_EVENT_RESPOVERFLOW_STR); _dpd.streamAPI->stop_inspection( packetp->stream_session_ptr, packetp, SSN_DIR_BOTH, -1, 0 ); } } } } else { /* * Have seen a server response, so * this appears to be a valid exchange. * Reset suspicious byte count to zero. */ sessp->num_client_bytes = 0; } } else { /* Have already examined more than the limit * of encrypted packets. Both the Gobbles and * the CRC32 attacks occur during authentication * and therefore cannot be used late in an * encrypted session. For performance purposes, * stop examining this session. */ _dpd.streamAPI->stop_inspection( packetp->stream_session_ptr, packetp, SSN_DIR_BOTH, -1, 0 ); } } PREPROC_PROFILE_END(sshPerfStats); }
/********************************************************************* * Function: DCE2_InitGlobal() * * Purpose: Initializes the global DCE/RPC preprocessor config. * * Arguments: snort.conf argument line for the DCE/RPC preprocessor. * * Returns: None * *********************************************************************/ static void DCE2_InitGlobal(char *args) { tSfPolicyId policy_id = _dpd.getParserPolicy(); DCE2_Config *pDefaultPolicyConfig = NULL; DCE2_Config *pCurrentPolicyConfig = NULL; if ((_dpd.streamAPI == NULL) || (_dpd.streamAPI->version != STREAM_API_VERSION5)) { DCE2_Die("%s(%d) \"%s\" configuration: " "Stream5 must be enabled with TCP and UDP tracking.", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } if (dce2_config == NULL) { dce2_config = sfPolicyConfigCreate(); if (dce2_config == NULL) { DCE2_Die("%s(%d) \"%s\" configuration: Could not allocate memory " "configuration.\n", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } DCE2_MemInit(); DCE2_StatsInit(); DCE2_EventsInit(); /* Initialize reassembly packet */ DCE2_InitRpkts(); DCE2_SmbInitGlobals(); _dpd.addPreprocConfCheck(DCE2_CheckConfig); _dpd.registerPreprocStats(DCE2_GNAME, DCE2_PrintStats); _dpd.addPreprocReset(DCE2_Reset, NULL, PRIORITY_LAST, PP_DCE2); _dpd.addPreprocResetStats(DCE2_ResetStats, NULL, PRIORITY_LAST, PP_DCE2); _dpd.addPreprocExit(DCE2_CleanExit, NULL, PRIORITY_LAST, PP_DCE2); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc(DCE2_PSTAT__MAIN, &dce2_pstat_main, 0, _dpd.totalPerfStats); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SESSION, &dce2_pstat_session, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__NEW_SESSION, &dce2_pstat_new_session, 2, &dce2_pstat_session); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SSN_STATE, &dce2_pstat_session_state, 2, &dce2_pstat_session); _dpd.addPreprocProfileFunc(DCE2_PSTAT__LOG, &dce2_pstat_log, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__DETECT, &dce2_pstat_detect, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_SEG, &dce2_pstat_smb_seg, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_REQ, &dce2_pstat_smb_req, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_UID, &dce2_pstat_smb_uid, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_TID, &dce2_pstat_smb_tid, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FID, &dce2_pstat_smb_fid, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_FP, &dce2_pstat_smb_fingerprint, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__SMB_NEG, &dce2_pstat_smb_negotiate, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_SEG, &dce2_pstat_co_seg, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_FRAG, &dce2_pstat_co_frag, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_REASS, &dce2_pstat_co_reass, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CO_CTX, &dce2_pstat_co_ctx, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CL_ACTS, &dce2_pstat_cl_acts, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CL_FRAG, &dce2_pstat_cl_frag, 1, &dce2_pstat_main); _dpd.addPreprocProfileFunc(DCE2_PSTAT__CL_REASS, &dce2_pstat_cl_reass, 1, &dce2_pstat_main); #endif #ifdef TARGET_BASED dce2_proto_ids.dcerpc = _dpd.findProtocolReference(DCE2_PROTO_REF_STR__DCERPC); if (dce2_proto_ids.dcerpc == SFTARGET_UNKNOWN_PROTOCOL) dce2_proto_ids.dcerpc = _dpd.addProtocolReference(DCE2_PROTO_REF_STR__DCERPC); /* smb and netbios-ssn refer to the same thing */ dce2_proto_ids.nbss = _dpd.findProtocolReference(DCE2_PROTO_REF_STR__NBSS); if (dce2_proto_ids.nbss == SFTARGET_UNKNOWN_PROTOCOL) dce2_proto_ids.nbss = _dpd.addProtocolReference(DCE2_PROTO_REF_STR__NBSS); #endif } sfPolicyUserPolicySet(dce2_config, policy_id); pDefaultPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetDefault(dce2_config); pCurrentPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_config); if ((policy_id != 0) && (pDefaultPolicyConfig == NULL)) { DCE2_Die("%s(%d) \"%s\" configuration: Must configure default policy " "if other policies are to be configured.\n", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } /* Can only do one global configuration */ if (pCurrentPolicyConfig != NULL) { DCE2_Die("%s(%d) \"%s\" configuration: Only one global configuration can be specified.", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } DCE2_RegRuleOptions(); pCurrentPolicyConfig = (DCE2_Config *)DCE2_Alloc(sizeof(DCE2_Config), DCE2_MEM_TYPE__CONFIG); sfPolicyUserDataSetCurrent(dce2_config, pCurrentPolicyConfig); /* Parse configuration args */ DCE2_GlobalConfigure(pCurrentPolicyConfig, args); if (policy_id != 0) pCurrentPolicyConfig->gconfig->memcap = pDefaultPolicyConfig->gconfig->memcap; if ( pCurrentPolicyConfig->gconfig->disabled ) return; /* Register callbacks */ _dpd.addPreproc(DCE2_Main, PRIORITY_APPLICATION, PP_DCE2, PROTO_BIT__TCP | PROTO_BIT__UDP); #ifdef TARGET_BASED _dpd.streamAPI->set_service_filter_status (dce2_proto_ids.dcerpc, PORT_MONITOR_SESSION, policy_id, 1); _dpd.streamAPI->set_service_filter_status (dce2_proto_ids.nbss, PORT_MONITOR_SESSION, policy_id, 1); #endif }
/********************************************************************* * Function: DCE2_ReloadGlobal() * * Purpose: Creates a new global DCE/RPC preprocessor config. * * Arguments: snort.conf argument line for the DCE/RPC preprocessor. * * Returns: None * *********************************************************************/ static void DCE2_ReloadGlobal(char *args) { tSfPolicyId policy_id = _dpd.getParserPolicy(); DCE2_Config *pDefaultPolicyConfig = NULL; DCE2_Config *pCurrentPolicyConfig = NULL; if ((_dpd.streamAPI == NULL) || (_dpd.streamAPI->version != STREAM_API_VERSION5)) { DCE2_Die("%s(%d) \"%s\" configuration: " "Stream5 must be enabled with TCP and UDP tracking.", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } if (dce2_swap_config == NULL) { //create a context dce2_swap_config = sfPolicyConfigCreate(); if (dce2_swap_config == NULL) { DCE2_Die("%s(%d) \"%s\" configuration: Could not allocate memory " "configuration.\n", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } _dpd.addPreprocReloadVerify(DCE2_ReloadVerify); } sfPolicyUserPolicySet(dce2_swap_config, policy_id); pDefaultPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetDefault(dce2_swap_config); pCurrentPolicyConfig = (DCE2_Config *)sfPolicyUserDataGetCurrent(dce2_swap_config); if ((policy_id != 0) && (pDefaultPolicyConfig == NULL)) { DCE2_Die("%s(%d) \"%s\" configuration: Must configure default policy " "if other policies are to be configured.\n", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } /* Can only do one global configuration */ if (pCurrentPolicyConfig != NULL) { DCE2_Die("%s(%d) \"%s\" configuration: Only one global configuration can be specified.", *_dpd.config_file, *_dpd.config_line, DCE2_GNAME); } DCE2_RegRuleOptions(); pCurrentPolicyConfig = (DCE2_Config *)DCE2_Alloc(sizeof(DCE2_Config), DCE2_MEM_TYPE__CONFIG); sfPolicyUserDataSetCurrent(dce2_swap_config, pCurrentPolicyConfig); /* Parse configuration args */ DCE2_GlobalConfigure(pCurrentPolicyConfig, args); if ( pCurrentPolicyConfig->gconfig->disabled ) return; _dpd.addPreproc(DCE2_Main, PRIORITY_APPLICATION, PP_DCE2, PROTO_BIT__TCP | PROTO_BIT__UDP); #ifdef TARGET_BASED _dpd.streamAPI->set_service_filter_status (dce2_proto_ids.dcerpc, PORT_MONITOR_SESSION, policy_id, 1); _dpd.streamAPI->set_service_filter_status (dce2_proto_ids.nbss, PORT_MONITOR_SESSION, policy_id, 1); #endif if (policy_id != 0) pCurrentPolicyConfig->gconfig->memcap = pDefaultPolicyConfig->gconfig->memcap; }
/* This function receives the OTN of a fully-parsed rule, checks that it is a SDF rule, then adds pattern & OTN to the SDF pattern-matching tree. */ int SDFOtnHandler(void *potn) { OptTreeNode *otn = (OptTreeNode *)potn; SDFConfig *config; tSfPolicyId policy_id; SDFOptionData *sdf_data; OptFpList *tmp = otn->opt_func; PreprocessorOptionInfo *preproc_info = NULL; tSfPolicyUserContextId context_to_use = sdf_context_id; sdf_tree_node *head_node_to_use = head_node; uint32_t *num_patterns_to_use = &num_patterns; int sdf_option_added = 0; #ifdef SNORT_RELOAD /* If we are reloading, use that context instead. This should work since preprocessors get configured before rule parsing */ if (sdf_swap_context_id != NULL) { context_to_use = sdf_swap_context_id; head_node_to_use = swap_head_node; num_patterns_to_use = &swap_num_patterns; } #endif /* Retrieve the current policy being parsed */ policy_id = _dpd.getParserPolicy(); sfPolicyUserPolicySet(context_to_use, policy_id); config = (SDFConfig *) sfPolicyUserDataGetCurrent(context_to_use); /* Check that this is a SDF rule, then grab the context data. */ while (tmp != NULL && tmp->type != RULE_OPTION_TYPE_LEAF_NODE) { if (tmp->type == RULE_OPTION_TYPE_PREPROCESSOR) preproc_info = tmp->context; if (preproc_info == NULL || preproc_info->optionEval != (PreprocOptionEval) SDFOptionEval) { DynamicPreprocessorFatalMessage("%s(%d) Rules with SDF options cannot " "have other detection options in the same rule.\n", *_dpd.config_file, *_dpd.config_line); } if (sdf_option_added) { DynamicPreprocessorFatalMessage("A rule may contain only one " "\"%s\" option.\n", SDF_OPTION_NAME); } if (otn->sigInfo.generator != GENERATOR_SPP_SDF_RULES) { DynamicPreprocessorFatalMessage("Rules with SDF options must " "use GID %d.\n", GENERATOR_SPP_SDF_RULES); } sdf_data = (SDFOptionData *)preproc_info->data; sdf_data->otn = otn; sdf_data->sid = otn->sigInfo.id; sdf_data->gid = otn->sigInfo.generator; /* Add the pattern to the SDF pattern-matching tree */ AddPii(head_node_to_use, sdf_data); sdf_data->counter_index = (*num_patterns_to_use)++; AddPortsToConf(config, otn); AddProtocolsToConf(config, otn); sdf_option_added = 1; preproc_info = NULL; tmp = tmp->next; } return 1; }
static void FTPTelnetInit(struct _SnortConfig *sc, char *args) { char *pcToken; char ErrorString[ERRSTRLEN]; int iErrStrLen = ERRSTRLEN; int iRet = 0; tSfPolicyId policy_id = _dpd.getParserPolicy(sc); FTPTELNET_GLOBAL_CONF *pPolicyConfig = NULL; ErrorString[0] = '\0'; if ((args == NULL) || (strlen(args) == 0)) { DynamicPreprocessorFatalMessage("%s(%d) No arguments to FtpTelnet " "configuration.\n", *_dpd.config_file, *_dpd.config_line); } /* Find out what is getting configured */ maxToken = args + strlen(args); pcToken = mystrtok(args, CONF_SEPARATORS); if (pcToken == NULL) { DynamicPreprocessorFatalMessage("%s(%d)mystrtok returned NULL when it " "should not.", __FILE__, __LINE__); } if (ftp_telnet_config == NULL) { //create a context ftp_telnet_config = sfPolicyConfigCreate(); if (ftp_telnet_config == NULL) { DynamicPreprocessorFatalMessage("No memory to allocate " "FTP/Telnet configuration.\n"); } _dpd.addPreprocExit(FTPTelnetCleanExit, NULL, PRIORITY_APPLICATION, PP_FTPTELNET); _dpd.addPreprocReset(FTPTelnetReset, NULL, PRIORITY_APPLICATION, PP_FTPTELNET); _dpd.addPreprocResetStats(FTPTelnetResetStats, NULL, PRIORITY_APPLICATION, PP_FTPTELNET); _dpd.addPreprocConfCheck(sc, FTPConfigCheck); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("ftptelnet_ftp", (void*)&ftpPerfStats, 0, _dpd.totalPerfStats); _dpd.addPreprocProfileFunc("ftptelnet_telnet", (void*)&telnetPerfStats, 0, _dpd.totalPerfStats); _dpd.addPreprocProfileFunc("ftptelnet_ftpdata", (void*)&ftpdataPerfStats, 0, _dpd.totalPerfStats); #endif #ifdef TARGET_BASED if (_dpd.streamAPI != NULL) { /* Find and store the application ID for FTP & Telnet */ ftp_app_id = _dpd.addProtocolReference("ftp"); ftp_data_app_id = _dpd.addProtocolReference("ftp-data"); telnet_app_id = _dpd.addProtocolReference("telnet"); } // register with session to handle applications _dpd.sessionAPI->register_service_handler( PP_FTPTELNET, ftp_app_id ); _dpd.sessionAPI->register_service_handler( PP_FTPTELNET, ftp_data_app_id ); _dpd.sessionAPI->register_service_handler( PP_FTPTELNET, telnet_app_id ); #endif } /* * Global Configuration Processing * We only process the global configuration once, but always check for * user mistakes, like configuring more than once. That's why we * still check for the global token even if it's been checked. */ sfPolicyUserPolicySet (ftp_telnet_config, policy_id); pPolicyConfig = (FTPTELNET_GLOBAL_CONF *)sfPolicyUserDataGetCurrent(ftp_telnet_config); if (pPolicyConfig == NULL) { if (strcasecmp(pcToken, GLOBAL) != 0) { DynamicPreprocessorFatalMessage("%s(%d) Must configure the " "ftptelnet global configuration first.\n", *_dpd.config_file, *_dpd.config_line); } pPolicyConfig = (FTPTELNET_GLOBAL_CONF *)calloc(1, sizeof(FTPTELNET_GLOBAL_CONF)); if (pPolicyConfig == NULL) { DynamicPreprocessorFatalMessage("No memory to allocate " "FTP/Telnet configuration.\n"); } sfPolicyUserDataSetCurrent(ftp_telnet_config, pPolicyConfig); iRet = FtpTelnetInitGlobalConfig(pPolicyConfig, ErrorString, iErrStrLen); if (iRet == 0) { iRet = ProcessFTPGlobalConf(pPolicyConfig, ErrorString, iErrStrLen); if (iRet == 0) { PrintFTPGlobalConf(pPolicyConfig); _dpd.preprocOptRegister(sc, "ftp.bounce", &FTPPBounceInit, &FTPPBounceEval, NULL, NULL, NULL, NULL, NULL); #ifdef TARGET_BASED if (_dpd.streamAPI != NULL) { _dpd.streamAPI->set_service_filter_status (sc, ftp_app_id, PORT_MONITOR_SESSION, policy_id, 1); _dpd.streamAPI->set_service_filter_status (sc, telnet_app_id, PORT_MONITOR_SESSION, policy_id, 1); } #endif } } } else if (strcasecmp(pcToken, TELNET) == 0) { iRet = ProcessTelnetConf(pPolicyConfig, ErrorString, iErrStrLen); enableFtpTelnetPortStreamServices( sc, &pPolicyConfig->telnet_config->proto_ports, NULL, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT ); } else if (strcasecmp(pcToken, FTP) == 0) { pcToken = NextToken(CONF_SEPARATORS); if ( !pcToken ) { DynamicPreprocessorFatalMessage( "%s(%d) Missing ftp_telnet ftp keyword.\n", *(_dpd.config_file), *(_dpd.config_line)); } else if (strcasecmp(pcToken, SERVER) == 0) { iRet = ProcessFTPServerConf(sc, pPolicyConfig, ErrorString, iErrStrLen); } else if (strcasecmp(pcToken, CLIENT) == 0) { iRet = ProcessFTPClientConf(sc, pPolicyConfig, ErrorString, iErrStrLen); } else { DynamicPreprocessorFatalMessage("%s(%d) Invalid ftp_telnet ftp keyword.\n", *(_dpd.config_file), *(_dpd.config_line)); } } else { DynamicPreprocessorFatalMessage("%s(%d) Invalid ftp_telnet keyword.\n", *(_dpd.config_file), *(_dpd.config_line)); } if (iRet) { if(iRet > 0) { /* * Non-fatal Error */ if(*ErrorString) { _dpd.errMsg("WARNING: %s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), ErrorString); } } else { /* * Fatal Error, log error and exit. */ if(*ErrorString) { DynamicPreprocessorFatalMessage("%s(%d) => %s\n", *(_dpd.config_file), *(_dpd.config_line), ErrorString); } else { /* * Check if ErrorString is undefined. */ if(iRet == -2) { DynamicPreprocessorFatalMessage("%s(%d) => ErrorString is undefined.\n", *(_dpd.config_file), *(_dpd.config_line)); } else { DynamicPreprocessorFatalMessage("%s(%d) => Undefined Error.\n", *(_dpd.config_file), *(_dpd.config_line)); } } } } }
void SSLPP_init(struct _SnortConfig *sc, char *args) { tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SSLPP_config_t *pPolicyConfig = NULL; if (ssl_config == NULL) { //create a context ssl_config = sfPolicyConfigCreate(); if (ssl_config == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage( "SSLPP_init(): The Stream preprocessor must be enabled.\n"); } SSL_InitGlobals(); _dpd.registerPreprocStats("ssl", SSLPP_drop_stats); _dpd.addPreprocConfCheck(sc, SSLPP_CheckConfig); _dpd.addPreprocExit(SSLCleanExit, NULL, PRIORITY_LAST, PP_SSL); _dpd.addPreprocResetStats(SSLResetStats, NULL, PRIORITY_LAST, PP_SSL); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("ssl", (void *)&sslpp_perf_stats, 0, _dpd.totalPerfStats); #endif #ifdef ENABLE_HA _dpd.addFuncToPostConfigList(sc, SSLHAPostConfigInit, NULL); #endif #ifdef TARGET_BASED ssl_app_id = _dpd.findProtocolReference("ssl"); if (ssl_app_id == SFTARGET_UNKNOWN_PROTOCOL) { ssl_app_id = _dpd.addProtocolReference("ssl"); } _dpd.sessionAPI->register_service_handler( PP_SSL, ssl_app_id ); #endif } sfPolicyUserPolicySet (ssl_config, policy_id); pPolicyConfig = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSL preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSLPP_config_t *)calloc(1, sizeof(SSLPP_config_t)); if (pPolicyConfig == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssl_config, pPolicyConfig); SSLPP_init_config(pPolicyConfig); SSLPP_config(pPolicyConfig, args); SSLPP_print_config(pPolicyConfig); _dpd.preprocOptRegister(sc, "ssl_state", SSLPP_state_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.preprocOptRegister(sc, "ssl_version", SSLPP_ver_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.addPreproc( sc, SSLPP_process, PRIORITY_APPLICATION, PP_SSL, PROTO_BIT__TCP ); registerPortsForDispatch( sc, pPolicyConfig ); registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT ); _addPortsToStream5Filter(sc, pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(sc, policy_id); #endif }
void SSLReload(struct _SnortConfig *sc, char *args, void **new_config) { tSfPolicyUserContextId ssl_swap_config = (tSfPolicyUserContextId)*new_config; tSfPolicyId policy_id = _dpd.getParserPolicy(sc); SSLPP_config_t * pPolicyConfig = NULL; if (ssl_swap_config == NULL) { //create a context ssl_swap_config = sfPolicyConfigCreate(); if (ssl_swap_config == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage( "SSLPP_init(): The Stream preprocessor must be enabled.\n"); } *new_config = (void *)ssl_swap_config; } sfPolicyUserPolicySet (ssl_swap_config, policy_id); pPolicyConfig = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_swap_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSL preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSLPP_config_t *)calloc(1, sizeof(SSLPP_config_t)); if (pPolicyConfig == NULL) { DynamicPreprocessorFatalMessage("Could not allocate memory for the " "SSL preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssl_swap_config, pPolicyConfig); SSLPP_init_config(pPolicyConfig); SSLPP_config(pPolicyConfig, args); SSLPP_print_config(pPolicyConfig); _dpd.preprocOptRegister(sc, "ssl_state", SSLPP_state_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.preprocOptRegister(sc, "ssl_version", SSLPP_ver_init, SSLPP_rule_eval, free, NULL, NULL, NULL, NULL); _dpd.addPreproc(sc, SSLPP_process, PRIORITY_APPLICATION, PP_SSL, PROTO_BIT__TCP); registerPortsForDispatch( sc, pPolicyConfig ); registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT ); _addPortsToStream5Filter(sc, pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(sc, policy_id); #endif }
/* 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); }
/* Initializes the SIP preprocessor module and registers * it in the preprocessor list. * * PARAMETERS: * * argp: Pointer to argument string to process for config * data. * * RETURNS: Nothing. */ static void SIPInit(char *argp) { tSfPolicyId policy_id = _dpd.getParserPolicy(); SIPConfig *pDefaultPolicyConfig = NULL; SIPConfig *pPolicyConfig = NULL; if (sip_config == NULL) { //create a context sip_config = sfPolicyConfigCreate(); if (sip_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for SIP config.\n"); } _dpd.addPreprocConfCheck(SIPCheckConfig); _dpd.registerPreprocStats(SIP_NAME, SIP_PrintStats); _dpd.addPreprocExit(SIPCleanExit, NULL, PRIORITY_LAST, PP_SIP); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("sip", (void *)&sipPerfStats, 0, _dpd.totalPerfStats); #endif #ifdef TARGET_BASED sip_app_id = _dpd.findProtocolReference("sip"); if (sip_app_id == SFTARGET_UNKNOWN_PROTOCOL) sip_app_id = _dpd.addProtocolReference("sip"); #endif } sfPolicyUserPolicySet (sip_config, policy_id); pDefaultPolicyConfig = (SIPConfig *)sfPolicyUserDataGetDefault(sip_config); pPolicyConfig = (SIPConfig *)sfPolicyUserDataGetCurrent(sip_config); if ((pPolicyConfig != NULL) && (pDefaultPolicyConfig == NULL)) { DynamicPreprocessorFatalMessage("SIP preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SIPConfig *)calloc(1, sizeof(SIPConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SIP preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(sip_config, pPolicyConfig); SIP_RegRuleOptions(); ParseSIPArgs(pPolicyConfig, (u_char *)argp); if (policy_id != 0) pPolicyConfig->maxNumSessions = pDefaultPolicyConfig->maxNumSessions; if ( pPolicyConfig->disabled ) return; if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupSIP(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreproc( SIPmain, PRIORITY_APPLICATION, PP_SIP, PROTO_BIT__UDP|PROTO_BIT__TCP ); _addPortsToStream5Filter(pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(policy_id); #endif }
/* Initializes the SSH preprocessor module and registers * it in the preprocessor list. * * PARAMETERS: * * argp: Pointer to argument string to process for config * data. * * RETURNS: Nothing. */ static void SSHInit(char *argp) { tSfPolicyId policy_id = _dpd.getParserPolicy(); SSHConfig *pPolicyConfig = NULL; if (ssh_config == NULL) { //create a context ssh_config = sfPolicyConfigCreate(); if (ssh_config == NULL) { DynamicPreprocessorFatalMessage("Failed to allocate memory " "for SSH config.\n"); } if (_dpd.streamAPI == NULL) { DynamicPreprocessorFatalMessage("SetupSSH(): The Stream preprocessor must be enabled.\n"); } _dpd.addPreprocConfCheck(SSHCheckConfig); _dpd.addPreprocExit(SSHCleanExit, NULL, PRIORITY_LAST, PP_SSH); #ifdef PERF_PROFILING _dpd.addPreprocProfileFunc("ssh", (void *)&sshPerfStats, 0, _dpd.totalPerfStats); #endif #ifdef TARGET_BASED ssh_app_id = _dpd.findProtocolReference("ssh"); if (ssh_app_id == SFTARGET_UNKNOWN_PROTOCOL) ssh_app_id = _dpd.addProtocolReference("ssh"); #endif } sfPolicyUserPolicySet (ssh_config, policy_id); pPolicyConfig = (SSHConfig *)sfPolicyUserDataGetCurrent(ssh_config); if (pPolicyConfig != NULL) { DynamicPreprocessorFatalMessage("SSH preprocessor can only be " "configured once.\n"); } pPolicyConfig = (SSHConfig *)calloc(1, sizeof(SSHConfig)); if (!pPolicyConfig) { DynamicPreprocessorFatalMessage("Could not allocate memory for " "SSH preprocessor configuration.\n"); } sfPolicyUserDataSetCurrent(ssh_config, pPolicyConfig); ParseSSHArgs(pPolicyConfig, (u_char *)argp); _dpd.addPreproc( ProcessSSH, PRIORITY_APPLICATION, PP_SSH, PROTO_BIT__TCP ); _addPortsToStream5Filter(pPolicyConfig, policy_id); #ifdef TARGET_BASED _addServicesToStream5Filter(policy_id); #endif }