Пример #1
0
static int SIPReloadVerify(struct _SnortConfig *sc, void *swap_config)
{
    tSfPolicyUserContextId sip_swap_config = (tSfPolicyUserContextId)swap_config;
    SIPConfig * pPolicyConfig = NULL;
    SIPConfig * pCurrentConfig = NULL;
    int rval;

    if (sip_swap_config == NULL)
        return 0;

    pPolicyConfig = (SIPConfig *)sfPolicyUserDataGet(sip_swap_config, _dpd.getDefaultPolicy());
    if ( pPolicyConfig == NULL )
        return 0;

    if (sip_config != NULL)
    {
        pCurrentConfig = (SIPConfig *)sfPolicyUserDataGet(sip_config, _dpd.getDefaultPolicy());

        if (!pCurrentConfig) 
            return 0;

        if (pPolicyConfig->maxNumSessions != pCurrentConfig->maxNumSessions)
        {
            _dpd.errMsg("SIP reload: Changing the max_sessions requires a restart.\n");
            return -1;
        }
    }
    
    // validate each policy and do per policy initialization processing
    if ((rval = sfPolicyUserDataIterate (sc, sip_config, SIPCheckPolicyConfig)))
        return rval;

   return 0;
}
Пример #2
0
/* Registered as a callback with our SSH data blocks when
 * they are added to the underlying stream session. Called
 * by the stream preprocessor when a session is about to be
 * destroyed.
 *
 * PARAMETERS:
 *
 * idatap:	Pointer to the moribund data.
 *
 * RETURNS:	Nothing.
 */
static void
FreeSSHData( void* idatap )
{
    SSHData *ssn = (SSHData *)idatap;
    SSHConfig *config = NULL;

    if (ssn == NULL)
        return;

    if (ssn->config != NULL)
    {
        config = (SSHConfig *)sfPolicyUserDataGet(ssn->config, ssn->policy_id);
    }

    if (config != NULL)
    {
        config->ref_count--;
        if ((config->ref_count == 0) &&
            (ssn->config != ssh_config))
        {
            sfPolicyUserDataClear (ssn->config, ssn->policy_id);
            free(config);

            if (sfPolicyUserPolicyGetActive(ssn->config) == 0)
            {
                /* No more outstanding configs - free the config array */
                SSHFreeConfig(ssn->config);
            }

        }
    }

    free(ssn);
}
Пример #3
0
static void FreeModbusData(void *data)
{
    modbus_session_data_t *session = (modbus_session_data_t *)data;
    modbus_config_t *config = NULL;

    if (session == NULL)
        return;

    if (session->context_id != NULL)
    {
        config = (modbus_config_t *)sfPolicyUserDataGet(session->context_id, session->policy_id);
    }

    if (config != NULL)
    {
        config->ref_count--;
        if ((config->ref_count == 0) &&
            (session->context_id != modbus_context_id))
        {
            sfPolicyUserDataClear(session->context_id, session->policy_id);
            free(config);

            if (sfPolicyUserPolicyGetActive(session->context_id) == 0)
            {
                /* No more outstanding configs - free the config array */
                ModbusFreeConfig(session->context_id);
            }
        }
    }
    free(session);
}
Пример #4
0
static void FreeDNP3Data(void *bucket)
{
    MemBucket *tmp_bucket = (MemBucket *)bucket;
    dnp3_session_data_t *session;
    dnp3_config_t *config = NULL;

    if ((tmp_bucket == NULL) || (tmp_bucket->data == NULL))
        return;

    session = tmp_bucket->data;

    if (session->context_id != NULL)
    {
        config = (dnp3_config_t *)sfPolicyUserDataGet(session->context_id, session->policy_id);
    }

    if (config != NULL)
    {
        config->ref_count--;
        if ((config->ref_count == 0) &&
            (session->context_id != dnp3_context_id))
        {
            sfPolicyUserDataClear(session->context_id, session->policy_id);
            free(config);

            if (sfPolicyUserPolicyGetActive(session->context_id) == 0)
            {
                /* No more outstanding configs - free the config array */
                DNP3FreeConfig(session->context_id);
            }
        }
    }

    mempool_free(dnp3_mempool, tmp_bucket);
}
Пример #5
0
/*
 * Function: FTPFreeSession(void *preproc_session)
 *
 * Purpose: This function frees the data that is associated with a session.
 *
 * Arguments: preproc_session   => pointer to the session to free
 *
 * Returns: None
 */
static void FTPFreeSession(void *preproc_session)
{
    FTP_SESSION *ssn = (FTP_SESSION *)preproc_session;
    FTPTELNET_GLOBAL_CONF *pPolicyConfig = NULL;

    if (ssn == NULL)
        return;

    pPolicyConfig = (FTPTELNET_GLOBAL_CONF *)sfPolicyUserDataGet(ssn->global_conf, ssn->policy_id);

    if (pPolicyConfig != NULL)
    {
        pPolicyConfig->ref_count--;
        if ((pPolicyConfig->ref_count == 0) &&
            (ssn->global_conf != ftp_telnet_config))
        {

            sfPolicyUserDataClear (ssn->global_conf, ssn->policy_id);
            FTPTelnetFreeConfig(pPolicyConfig);

            if (sfPolicyUserPolicyGetActive(ssn->global_conf) == 0)
                FTPTelnetFreeConfigs(ssn->global_conf);
        }
    }

    if (ssn->filename)
    {
        free(ssn->filename);
    }

    free(ssn);
}
Пример #6
0
// *DROP* flags are set to mark the direction(s) for which traffic was
// seen since last reset and then cleared after sending new attempt so
// that we only send in the still active direction(s).
void Stream5ActiveResponse(Packet* p, Stream5LWSession *lwssn)
{
    Stream5Config *config = sfPolicyUserDataGet(s5_config, getRuntimePolicy());
    uint8_t max = config->global_config->max_active_responses;

    if ( p->packet_flags & PKT_FROM_CLIENT )
        lwssn->session_state |= STREAM5_STATE_DROP_CLIENT;
    else
        lwssn->session_state |= STREAM5_STATE_DROP_SERVER;

    if ( (lwssn->response_count < max) && Stream5GetExpire(p, lwssn) )
    {
        uint32_t delay = config->global_config->min_response_seconds;
        EncodeFlags flags =
            ( (lwssn->session_state & STREAM5_STATE_DROP_CLIENT) &&
              (lwssn->session_state & STREAM5_STATE_DROP_SERVER) ) ?
            ENC_FLAG_FWD : 0;  // reverse dir is always true

        Active_KillSession(p, &flags);
        ++lwssn->response_count;
        Stream5SetExpire(p, lwssn, delay);

        lwssn->session_state &= ~(STREAM5_STATE_DROP_CLIENT|STREAM5_STATE_DROP_SERVER);
    }
}
Пример #7
0
/*
 * Function: FTPFreeSession(void *preproc_session)
 *
 * Purpose: This function frees the data that is associated with a session.
 *
 * Arguments: preproc_session   => pointer to the session to free
 *
 * Returns: None
 */
static void FTPFreeSession(void *preproc_session)
{
    FTP_SESSION *ssn = (FTP_SESSION *)preproc_session;
    FTPTELNET_GLOBAL_CONF *pPolicyConfig = NULL;
    ssl_callback_interface_t *ssl_cb = (ssl_callback_interface_t *)_dpd.getSSLCallback();

    if (ssn == NULL)
        return;

    pPolicyConfig = (FTPTELNET_GLOBAL_CONF *)sfPolicyUserDataGet(ssn->global_conf, ssn->policy_id);

    if (pPolicyConfig != NULL)
    {
        pPolicyConfig->ref_count--;
        if ((pPolicyConfig->ref_count == 0) &&
            (ssn->global_conf != ftp_telnet_config))
        {

            sfPolicyUserDataClear (ssn->global_conf, ssn->policy_id);
            FTPTelnetFreeConfig(pPolicyConfig);

            if (sfPolicyUserPolicyGetActive(ssn->global_conf) == 0)
                FTPTelnetFreeConfigs(ssn->global_conf);
        }
    }

    if (ssn->filename)
    {
        free(ssn->filename);
    }

    if ( ssl_cb )
        ssl_cb->session_free(ssn->flow_id);
    free(ssn);
}
Пример #8
0
int ps_get_protocols(struct _SnortConfig *sc, tSfPolicyId policyId)
{
    tSfPolicyUserContextId config = portscan_config;
    PortscanConfig *pPolicyConfig = NULL;

#ifdef SNORT_RELOAD
    /* This is called during configuration time so use the swap
     * config if it exists */
    tSfPolicyUserContextId portscan_swap_config;
    portscan_swap_config = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "sfportscan");
    if (portscan_swap_config != NULL)
        config = portscan_swap_config;
#endif
    if( config == NULL)
        return 0;
    pPolicyConfig = (PortscanConfig *)sfPolicyUserDataGet(config, policyId);

    if (pPolicyConfig == NULL)
        return 0;

    /* Disabled in this policy */
    if (pPolicyConfig->disabled == 1)
        return 0;

    return pPolicyConfig->detect_scans;
}
Пример #9
0
int SSLReloadVerify(struct _SnortConfig *sc, void *swap_config)
{
    tSfPolicyUserContextId ssl_swap_config = (tSfPolicyUserContextId)swap_config;
    SSLPP_config_t *reload_config = NULL;
    SSLPP_config_t *start_config = NULL;
    tSfPolicyId policyId = _dpd.getDefaultPolicy();
    int ret = 0;

    if (!_dpd.isPreprocEnabled(sc, PP_STREAM))
    {
        _dpd.errMsg("SSLPP_init(): The Stream preprocessor must be enabled.\n");
        return -1;
    }

    if (!ssl_swap_config || !ssl_config)
        return 0;

    reload_config = (SSLPP_config_t *)sfPolicyUserDataGet(ssl_swap_config, policyId);
    start_config = (SSLPP_config_t *)sfPolicyUserDataGet(ssl_config, policyId);

    if( !reload_config || !start_config )
    {
        _dpd.errMsg("SSL reload: Turning on or off SSL preprocessor requires a restart.\n");
        return -1;
    }

    if ( reload_config->memcap != start_config->memcap )
    {
        _dpd.errMsg("SSL reload: Changing the memcap requires a restart.\n");
        return -1;
    }

    if ( reload_config->decrypt_memcap != start_config->decrypt_memcap )
    {
        _dpd.errMsg("SSL reload: Changing the decrypt_memcap requires a restart.\n");
        return -1;
    }

    ret = SSLPP_PolicyInit(sc, ssl_swap_config, reload_config, policyId, true);

    if (!ret)
    {
        start_config->reload_handle = reload_config->current_handle;
    }

    return ret;
}
Пример #10
0
static int DCE2_ReloadVerifyPolicy(
        tSfPolicyUserContextId config,
        tSfPolicyId policyId,
        void* pData
        )
{
    DCE2_Config *swap_config = (DCE2_Config *)pData;
    DCE2_Config *current_config = (DCE2_Config *)sfPolicyUserDataGet(dce2_config, policyId);
    DCE2_ServerConfig *dconfig;

    //do any housekeeping before freeing DCE2_Config

    if ( swap_config == NULL || swap_config->gconfig->disabled )
        return 0;

    if (!_dpd.isPreprocEnabled(PP_STREAM5))
    {
        DCE2_Die("%s(%d) \"%s\" configuration: "
            "Stream5 must be enabled with TCP and UDP tracking.",
            *_dpd.config_file, *_dpd.config_line, DCE2_GNAME);
    }

    dconfig = swap_config->dconfig;

    if (dconfig == NULL)
        DCE2_CreateDefaultServerConfig(swap_config, policyId);

#ifdef TARGET_BASED
    if (!_dpd.isAdaptiveConfigured(policyId, 1))
#endif
    {
        DCE2_ScCheckTransports(swap_config);
    }

#ifdef ENABLE_PAF
    DCE2_AddPortsToPaf(swap_config, policyId);
#endif

    /* Register routing table memory */
    if (swap_config->sconfigs != NULL)
        DCE2_RegMem(sfrt_usage(swap_config->sconfigs), DCE2_MEM_TYPE__RT);

    if (current_config == NULL)
        return 0;

    if (swap_config->gconfig->memcap != current_config->gconfig->memcap)
    {
        _dpd.errMsg("dcerpc2 reload:  Changing the memcap requires a restart.\n");
        DCE2_FreeConfigs(dce2_swap_config);
        dce2_swap_config = NULL;
        return -1;
    }

    return 0;
}
Пример #11
0
/* Check that Stream5 is still running, and that the memcap didn't change. */
static int DNP3ReloadVerify(struct _SnortConfig *sc, void *swap_config)
{
    tSfPolicyUserContextId dnp3_swap_context_id = (tSfPolicyUserContextId)swap_config;
    dnp3_config_t *current_default_config, *new_default_config;

    if ((dnp3_context_id == NULL) || (dnp3_swap_context_id == NULL))
        return 0;

    current_default_config =
        (dnp3_config_t *)sfPolicyUserDataGet(dnp3_context_id, _dpd.getDefaultPolicy());

    new_default_config =
        (dnp3_config_t *)sfPolicyUserDataGet(dnp3_swap_context_id, _dpd.getDefaultPolicy());

    /* Sanity check. Shouldn't be possible. */
    if (current_default_config == NULL)
        return 0;

    if (new_default_config == NULL)
    {
        _dpd.errMsg("DNP3 reload: Changing the DNP3 configuration "
            "requires a restart.\n");
        return -1;
    }

    /* Did memcap change? */
    if (current_default_config->memcap != new_default_config->memcap)
    {
        _dpd.errMsg("DNP3 reload: Changing the DNP3 memcap "
            "requires a restart.\n");
        return -1;
    }

    /* Did stream5 get turned off? */
    if (!_dpd.isPreprocEnabled(sc, PP_STREAM5))
    {
        _dpd.errMsg("SetupDNP3(): The Stream preprocessor must be enabled.\n");
        return -1;
    }

    return 0;
}
Пример #12
0
static int SIPReloadVerify(void)
{
    SIPConfig * pPolicyConfig = NULL;
    SIPConfig * pCurrentConfig = NULL;

    if (sip_swap_config == NULL)
        return 0;

    pPolicyConfig = (SIPConfig *)sfPolicyUserDataGet(sip_swap_config, _dpd.getDefaultPolicy());

    if (!pPolicyConfig)
        return 0;

    if ( pPolicyConfig->disabled )
        return 0;

    if (!_dpd.isPreprocEnabled(PP_STREAM5))
    {
        DynamicPreprocessorFatalMessage("SetupSIP(): The Stream preprocessor must be enabled.\n");
    }

    if (sip_config != NULL)
    {
        pCurrentConfig = (SIPConfig *)sfPolicyUserDataGet(sip_config, _dpd.getDefaultPolicy());
    }

    if (!pCurrentConfig)
        return 0;

    if (pPolicyConfig->maxNumSessions != pCurrentConfig->maxNumSessions)
    {
        _dpd.errMsg("SIP reload: Changing the max_sessions requires a restart.\n");
        SIPFreeConfig(sip_swap_config);
        sip_swap_config = NULL;
        return -1;
    }

    return 0;
}
Пример #13
0
static int SIPReloadVerify(struct _SnortConfig *sc, void *swap_config)
{
    tSfPolicyUserContextId sip_swap_config = (tSfPolicyUserContextId)swap_config;
    SIPConfig * pPolicyConfig = NULL;
    SIPConfig * pCurrentConfig = NULL;

    if (sip_swap_config == NULL)
        return 0;

    pPolicyConfig = (SIPConfig *)sfPolicyUserDataGet(sip_swap_config, _dpd.getDefaultPolicy());

    if (!pPolicyConfig)
        return 0;

    if ( pPolicyConfig->disabled )
        return 0;

    if (!_dpd.isPreprocEnabled(sc, PP_STREAM5))
    {
        _dpd.errMsg("SetupSIP(): The Stream preprocessor must be enabled.\n");
        return -1;
    }

    if (sip_config != NULL)
    {
        pCurrentConfig = (SIPConfig *)sfPolicyUserDataGet(sip_config, _dpd.getDefaultPolicy());
    }

    if (!pCurrentConfig)
        return 0;

    if (pPolicyConfig->maxNumSessions != pCurrentConfig->maxNumSessions)
    {
        _dpd.errMsg("SIP reload: Changing the max_sessions requires a restart.\n");
        return -1;
    }

    return 0;
}
Пример #14
0
static int FileReloadVerify(struct _SnortConfig *sc, void *swap_config)
{
    tSfPolicyUserContextId file_swap_config = (tSfPolicyUserContextId)swap_config;
    FileInspectConf * pPolicyConfig = NULL;
    FileInspectConf * pCurrentConfig = NULL;

    if (file_swap_config == NULL)
        return 0;

    pPolicyConfig = (FileInspectConf *)sfPolicyUserDataGet(file_swap_config, _dpd.getDefaultPolicy());

    if (!pPolicyConfig)
        return 0;


    if (file_config != NULL)
    {
        pCurrentConfig = (FileInspectConf *)sfPolicyUserDataGet(file_config, _dpd.getDefaultPolicy());
    }

    if (!pCurrentConfig)
        return 0;

    if (file_config_compare(pCurrentConfig, pPolicyConfig))
    {
        _dpd.errMsg("File inspect reload: Changing file settings requires a restart.\n");
        return -1;
    }

    if (!_dpd.isPreprocEnabled(sc, PP_STREAM))
    {
        _dpd.errMsg("SetupFile(): The Stream preprocessor must be enabled.\n");
        return -1;
    }

    return 0;
}
Пример #15
0
/***********************************************************************
 * Registered as a callback with our SIP data blocks when
 * they are added to the underlying stream session. Called
 * by the stream preprocessor when a session is about to be
 * destroyed.
 *
 * PARAMETERS:
 *
 * idatap:	Pointer to the moribund data.
 *
 * RETURNS:	Nothing.
 ***********************************************************************/
static void FreeSIPData( void* idatap )
{
    SIPData *ssn = (SIPData *)idatap;
    SIPConfig *config = NULL;

    if (ssn == NULL)
        return;
    if (numSessions > 0)
        numSessions--;

    /*Free all the dialog data*/
    sip_freeDialogs(&ssn->dialogs);

    /*Clean the configuration data*/
    if (ssn->config != NULL)
    {
        config = (SIPConfig *)sfPolicyUserDataGet(ssn->config, ssn->policy_id);
    }

    if (config == NULL)
    {
        free(ssn);
        return;
    }

    config->ref_count--;
    if ((config->ref_count == 0) &&	(ssn->config != sip_config))
    {
        sfPolicyUserDataClear (ssn->config, ssn->policy_id);
        free(config);

        if (sfPolicyUserPolicyGetActive(ssn->config) == 0)
        {
            /* No more outstanding configs - free the config array */
            SIPFreeConfig(ssn->config);
        }

    }

    free(ssn);
}
Пример #16
0
/***********************************************************************
 * Registered as a callback with our GTP data blocks when
 * they are added to the underlying stream session. Called
 * by the stream preprocessor when a session is about to be
 * destroyed.
 *
 * PARAMETERS:
 *
 * idatap:	Pointer to the moribund data.
 *
 * RETURNS:	Nothing.
 ***********************************************************************/
static void FreeGTPData( void* idatap )
{
    GTPData *ssn = (GTPData *)idatap;
    GTPConfig *config = NULL;

    if (ssn == NULL)
        return;
    if (numSessions > 0)
        numSessions--;

    /*Clean the configuration data*/
    if (ssn->config != NULL)
    {
        config = (GTPConfig *)sfPolicyUserDataGet(ssn->config, ssn->policy_id);
    }

    if (config == NULL)
    {
        free(ssn);
        return;
    }

    config->ref_count--;
    if ((config->ref_count == 0) &&	(ssn->config != gtp_config))
    {
        sfPolicyUserDataClear (ssn->config, ssn->policy_id);
        free(config);

        if (sfPolicyUserPolicyGetActive(ssn->config) == 0)
        {
            /* No more outstanding configs - free the config array */
            GTPFreeConfig(ssn->config);
        }

    }

    free(ssn);
}
Пример #17
0
int RemoveLWSession(Stream5SessionCache *sessionCache, Stream5LWSession *ssn)
{
    Stream5Config *pPolicyConfig = NULL;
    tSfPolicyId policy_id = ssn->policy_id;
    mempool_free(&s5FlowMempool, ssn->flowdata);
    ssn->flowdata = NULL;

    pPolicyConfig = (Stream5Config *)sfPolicyUserDataGet(ssn->config, policy_id);

    if (pPolicyConfig != NULL)
    {
        pPolicyConfig->ref_count--;
        if ((pPolicyConfig->ref_count == 0) && (ssn->config != s5_config))
        {
            sfPolicyUserDataClear (ssn->config, policy_id);
            Stream5FreeConfig(pPolicyConfig);

            if (sfPolicyUserPolicyGetActive(ssn->config) == 0)
                Stream5FreeConfigs(ssn->config);
        }
    }

    return sfxhash_remove(sessionCache->hashTable, &(ssn->key));
}
Пример #18
0
/* 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);

}
Пример #19
0
static void ParseDNP3Args(struct _SnortConfig *sc, dnp3_config_t *config, char *args)
{
    char *saveptr;
    char *token;

    /* Set defaults */
    config->memcap = DNP3_DEFAULT_MEMCAP;
    config->ports[PORT_INDEX(DNP3_PORT)] |= CONV_PORT(DNP3_PORT);
    config->check_crc = 0;

    /* No arguments? Stick with defaults. */
    if (args == NULL)
        return;

    token = strtok_r(args, " ,", &saveptr);
    while (token != NULL)
    {
        if (strcmp(token, DNP3_PORTS_KEYWORD) == 0)
        {
            unsigned nPorts = 0;

            /* Un-set the default port */
            config->ports[PORT_INDEX(DNP3_PORT)] = 0;

            /* Parse ports */
            token = strtok_r(NULL, " ,", &saveptr);

            if (token == NULL)
            {
                DynamicPreprocessorFatalMessage("%s(%d): Missing argument for "
                    "DNP3 preprocessor 'ports' option.\n",
                    *_dpd.config_file, *_dpd.config_line);
            }

            if (isdigit(token[0]))
            {
                ParseSinglePort(config, token);
                nPorts++;
            }
            else if (*token == '{')
            {
                /* list of ports */
                token = strtok_r(NULL, " ,", &saveptr);
                while (token != NULL && *token != '}')
                {
                    ParseSinglePort(config, token);
                    nPorts++;
                    token = strtok_r(NULL, " ,", &saveptr);
                }
            }

            else
            {
                nPorts = 0;
            }
            if ( nPorts == 0 )
            {
                DynamicPreprocessorFatalMessage("%s(%d): Bad DNP3 'ports' argument: '%s'\n"
                              "Argument to DNP3 'ports' must be an integer, or a list "
                              "enclosed in { } braces.\n",
                              *_dpd.config_file, *_dpd.config_line, token);
            }
        }
        else if (strcmp(token, DNP3_MEMCAP_KEYWORD) == 0)
        {
            uint32_t memcap;
            char *endptr;

            /* Parse memcap */
            token = strtok_r(NULL, " ", &saveptr);

            /* In a multiple policy scenario, the memcap from the default policy
               overrides the memcap in any targeted policies. */
            if (_dpd.getParserPolicy(sc) != _dpd.getDefaultPolicy())
            {
                dnp3_config_t *default_config =
                    (dnp3_config_t *)sfPolicyUserDataGet(dnp3_context_id,
                                                         _dpd.getDefaultPolicy());

                if (!default_config || default_config->memcap == 0)
                {
                    DynamicPreprocessorFatalMessage("%s(%d): DNP3 'memcap' must be "
                        "configured in the default config.\n",
                        *_dpd.config_file, *_dpd.config_line);
                }

                config->memcap = default_config->memcap;
            }
            else
            {
                if (token == NULL)
                {
                    DynamicPreprocessorFatalMessage("%s(%d): Missing argument for DNP3 "
                        "preprocessor 'memcap' option.\n",
                        *_dpd.config_file, *_dpd.config_line);
                }

                memcap = _dpd.SnortStrtoul(token, &endptr, 10);

                if ((token[0] == '-') || (*endptr != '\0') ||
                    (memcap < MIN_DNP3_MEMCAP) || (memcap > MAX_DNP3_MEMCAP))
                {
                    DynamicPreprocessorFatalMessage("%s(%d): Bad DNP3 'memcap' argument: %s\n"
                              "Argument to DNP3 'memcap' must be an integer between "
                              "%d and %d.\n", *_dpd.config_file, *_dpd.config_line,
                              token, MIN_DNP3_MEMCAP, MAX_DNP3_MEMCAP);
                }

                config->memcap = memcap;
            }
        }
        else if (strcmp(token, DNP3_CHECK_CRC_KEYWORD) == 0)
        {
            /* Parse check_crc */
            config->check_crc = 1;
        }
        else if (strcmp(token, DNP3_DISABLED_KEYWORD) == 0)
        {
            /* TODO: if disabled, check that no other stuff is turned on except memcap */
            config->disabled = 1;
        }
        else
        {
            DynamicPreprocessorFatalMessage("%s(%d): Failed to parse dnp3 argument: "
                "%s\n", *_dpd.config_file, *_dpd.config_line,  token);
        }
        token = strtok_r(NULL, " ,", &saveptr);
    }
}
Пример #20
0
/*********************************************************************
 * 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;
}
Пример #21
0
/* 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);
}
Пример #22
0
/*********************************************************************
 * 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;
}
Пример #23
0
/* Main runtime entry point for GTP preprocessor.
 * Analyzes GTP packets for anomalies/exploits.
 *
 * PARAMETERS:
 *
 * packetp:    Pointer to current packet to process.
 * contextp:    Pointer to context block, not used.
 *
 * RETURNS:     Nothing.
 */
static void GTPmain( void* ipacketp, void* contextp )
{
    GTPData* 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_GTP, "%s\n", GTP_DEBUG__START_MSG));

    packetp = (SFSnortPacket*) ipacketp;
    sfPolicyUserPolicySet (gtp_config, policy_id);

    /* Make sure this preprocessor should run. */
    if (( !packetp ) ||	( !packetp->payload ) ||( !packetp->payload_size ))
    {
        DEBUG_WRAP(DebugMessage(DEBUG_GTP, "No payload - not inspecting.\n"));
        DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
        return;
    }
    else if (!IsUDP(packetp))
    {
        DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Not UDP - not inspecting.\n"));
        DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
        return;
    }

    PREPROC_PROFILE_START(gtpPerfStats);

    gtp_eval_config = sfPolicyUserDataGetCurrent(gtp_config);

    /* Attempt to get a previously allocated GTP block. */
    sessp = _dpd.streamAPI->get_application_data(packetp->stream_session_ptr, PP_GTP);
    if (sessp != NULL)
    {
        gtp_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 GTP 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_GTP, "Unknown protocol - not inspecting.\n"));
            DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
            PREPROC_PROFILE_END(gtpPerfStats);
            return;
        }

        else if (app_id && (app_id != gtp_app_id))
        {
            DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Not GTP - not inspecting.\n"));
            DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
            PREPROC_PROFILE_END(gtpPerfStats);
            return;
        }

        else if (!app_id)
        {
#endif
            source = (uint8_t)CheckGTPPort( packetp->src_port );
            dest = (uint8_t)CheckGTPPort( packetp->dst_port );

            if ( !source && !dest )
            {
                /* Not one of the ports we care about. */
                DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Not GTP ports - not inspecting.\n"));
                DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
                PREPROC_PROFILE_END(gtpPerfStats);
                return;
            }
#ifdef TARGET_BASED
        }
#endif
        /* Check the stream session. If it does not currently
         * have our GTP data-block attached, create one.
         */
        sessp = GTPGetNewSession(packetp, policy_id);

        if ( !sessp )
        {
            /* Could not get/create the session data for this packet. */
            DEBUG_WRAP(DebugMessage(DEBUG_GTP, "Create session error - not inspecting.\n"));
            DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
            PREPROC_PROFILE_END(gtpPerfStats);
            return;
        }

    }


    /* We're interested in this session. Turn on stream reassembly. */
    if ( !(sessp->state_flags & GTP_FLG_REASSEMBLY_SET ))
    {
        _dpd.streamAPI->set_reassembly(packetp->stream_session_ptr,
                STREAM_FLPOLICY_FOOTPRINT, SSN_DIR_BOTH, STREAM_FLPOLICY_SET_ABSOLUTE);
        sessp->state_flags |= GTP_FLG_REASSEMBLY_SET;
    }
    /*
     * Start process PAYLOAD
     */
    GTP_Process(packetp,sessp);

    DEBUG_WRAP(DebugMessage(DEBUG_GTP, "%s\n", GTP_DEBUG__END_MSG));
    PREPROC_PROFILE_END(gtpPerfStats);

}