Esempio n. 1
0
/*
 * Function: TelnetSessionInspection(Packet *p,
 *                          FTPTELNET_GLOBAL_CONF *GlobalConf,
 *                          FTPP_SI_INPUT *SiInput,
 *                          int *piInspectMode)
 *
 * Purpose: The Session Inspection module selects the appropriate
 *          configuration for the session, and the type of inspection
 *          to be performed (client or server.)
 *
 *          When the Session Inspection module is in stateful mode, it
 *          checks to see if there is a TELNET_SESSION pointer already
 *          associated with the stream.  If there is, then it uses that
 *          session pointer, otherwise it calculates the server configuration
 *          using the FTP_SI_INPUT and returns a TELNET_SESSION pointer.  In
 *          stateful mode, this means that memory is allocated, but in
 *          stateless mode, the same session pointer is used for all packets
 *          to reduce the allocation overhead.
 *
 *          The inspection mode can be either client or server.
 *
 * Arguments: p             => pointer to the packet/stream
 *            GlobalConf    => pointer to the global configuration
 *            Session       => double pointer to the Session structure
 *            SiInput       => pointer to the session information
 *            piInspectMode => pointer for setting inspection mode
 *
 * Returns: int => return code indicating error or success
 *
 */
int TelnetSessionInspection(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf,
        TELNET_SESSION **TelnetSession, FTPP_SI_INPUT *SiInput, int *piInspectMode)
{
    int iRet;
    int iTelnetSip;
    int iTelnetDip;
#ifdef TARGET_BASED
    int16_t app_id = SFTARGET_UNKNOWN_PROTOCOL;

    /* If possible, use Stream API to determine protocol. */
    if (_dpd.streamAPI)
    {
        app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);
    }
    if (app_id == SFTARGET_UNKNOWN_PROTOCOL)
    {
        return FTPP_INVALID_PROTO;
    }
    if (app_id == telnet_app_id)
    {
        if (SiInput->pdir == FTPP_SI_CLIENT_MODE ||
            SiInput->pdir == FTPP_SI_SERVER_MODE)
        {
            *piInspectMode = (int)SiInput->pdir;
        }
    }
    else if (app_id && app_id != telnet_app_id)
    {
        return FTPP_INVALID_PROTO;
    }
    else
    {
#endif
        iTelnetSip = PortMatch((PROTO_CONF*)GlobalConf->telnet_config,
                               SiInput->sport);
        iTelnetDip = PortMatch((PROTO_CONF*)GlobalConf->telnet_config,
                               SiInput->dport);

        if (iTelnetSip)
        {
            *piInspectMode = FTPP_SI_SERVER_MODE;
        }
        else if (iTelnetDip)
        {
            *piInspectMode = FTPP_SI_CLIENT_MODE;
        }
        else
        {
            return FTPP_INVALID_PROTO;
        }
#ifdef TARGET_BASED
    }
#endif

    /*
     * We get the server configuration and the session structure differently
     * depending on what type of inspection we are doing.  In the case of
     * stateful processing, we may get the session structure from the Stream
     * Reassembly module (which includes the server configuration) or the
     * structure will be allocated and added to the stream pointer for the
     * rest of the session.
     *
     * In stateless mode, we just use a static variable that is contained in
     * the function here.
     */
    if(GlobalConf->inspection_type == FTPP_UI_CONFIG_STATEFUL)
    {
        iRet = TelnetStatefulSessionInspection(p, GlobalConf, TelnetSession, SiInput);
        if (iRet)
            return iRet;
    }
    else
    {
        /* Assume stateless processing otherwise */
        iRet = TelnetStatelessSessionInspection(p, GlobalConf, TelnetSession, SiInput);
        if (iRet)
            return iRet;
    }

    return FTPP_SUCCESS;
}
Esempio n. 2
0
/*
 * Function: FTPInitConf(Packet *p, FTPTELNET_GLOBAL_CONF *GlobalConf,
 *                       FTP_CLIENT_PROTO_CONF **ClientConf,
 *                       FTP_SERVER_PROTO_CONF **ServerConf,
 *                       FTPP_SI_INPUT *SiInput, int *piInspectMode)
 *
 * Purpose: When a session is initialized, we must select the appropriate
 *          server configuration and select the type of inspection based
 *          on the source and destination ports.
 *
 * IMPORTANT NOTE:
 *   We should check to make sure that there are some unique configurations,
 *   otherwise we can just default to the global default and work some magic
 *   that way.
 *
 * Arguments: p                 => pointer to the Packet/Session
 *            GlobalConf        => pointer to the global configuration
 *            ClientConf        => pointer to the address of the client
 *                                 config so we can set it.
 *            ServerConf        => pointer to the address of the server
 *                                 config so we can set it.
 *            SiInput           => pointer to the packet info
 *            piInspectMode     => pointer so we can set the inspection mode
 *
 * Returns: int => return code indicating error or success
 *
 */
static int FTPInitConf(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf,
                          FTP_CLIENT_PROTO_CONF **ClientConf,
                          FTP_SERVER_PROTO_CONF **ServerConf,
                          FTPP_SI_INPUT *SiInput, int *piInspectMode)
{
    FTP_CLIENT_PROTO_CONF *ClientConfSip;
    FTP_CLIENT_PROTO_CONF *ClientConfDip;
    FTP_SERVER_PROTO_CONF *ServerConfSip;
    FTP_SERVER_PROTO_CONF *ServerConfDip;
    int iServerSip;
    int iServerDip;
    int iErr = 0;
    int iRet = FTPP_SUCCESS;
#ifdef TARGET_BASED
    int16_t app_id = 0;
#endif
    snort_ip sip;
    snort_ip dip;

    //structure copy
    sip = SiInput->sip;
    dip = SiInput->dip;

    if (sip.family == AF_INET)
    {
        sip.ip.u6_addr32[0] = ntohl(sip.ip.u6_addr32[0]);
    }
    if (dip.family == AF_INET)
    {
        dip.ip.u6_addr32[0] = ntohl(dip.ip.u6_addr32[0]);
    }

    /*
     * We find the client configurations for both the source and dest IPs.
     * There should be a check on the global configuration to see if there
     * is at least one unique client configuration.  If there isn't then we
     * assume the global client configuration.
     */
    ClientConfDip = ftpp_ui_client_lookup_find(GlobalConf->client_lookup,
            &dip,
            &iErr);

    if(!ClientConfDip)
    {
        ClientConfDip = GlobalConf->default_ftp_client;
    }

    ClientConfSip = ftpp_ui_client_lookup_find(GlobalConf->client_lookup,
            &sip,
            &iErr);

    if(!ClientConfSip)
    {
        ClientConfSip = GlobalConf->default_ftp_client;
    }

    /*
     * Now, we find the server configurations for both the source and dest IPs.
     * There should be a check on the global configuration to see if there
     * is at least one unique client configuration.  If there isn't then we
     * assume the global client configuration.
     */
    ServerConfDip = ftpp_ui_server_lookup_find(GlobalConf->server_lookup,
            &dip,
            &iErr);

    if(!ServerConfDip)
    {
        ServerConfDip = GlobalConf->default_ftp_server;
    }

    ServerConfSip = ftpp_ui_server_lookup_find(GlobalConf->server_lookup,
            &sip,
            &iErr);

    if(!ServerConfSip)
    {
        ServerConfSip = GlobalConf->default_ftp_server;
    }

    /*
     * We check the IP and the port to see if the FTP client is talking in
     * the session.  This should tell us whether it is client communication
     * or server configuration.  If both IPs and ports are servers, then there
     * is a sort of problem.  We don't know which side is the client and which
     * side is the server so we have to assume one.
     *
     * In stateful processing, we only do this stage on the startup of a
     * session, so we can still assume that the initial packet is the client
     * talking.
     */
    iServerDip = PortMatch((PROTO_CONF*)ServerConfDip, SiInput->dport);
    iServerSip = PortMatch((PROTO_CONF*)ServerConfSip, SiInput->sport);

    /*
     * We default to the no FTP traffic case
     */
    *piInspectMode = FTPP_SI_NO_MODE;
    *ClientConf = NULL;
    *ServerConf = NULL;

    /*
     * Depending on the type of packet direction we get from the
     * state machine, we evaluate client/server differently.
     */
    switch(SiInput->pdir)
    {
        case FTPP_SI_NO_MODE:

#ifdef TARGET_BASED
            app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);

            if (app_id == ftp_app_id || app_id == 0)
            {
#endif

            /*
             * We check for the case where both SIP and DIP
             * appear to be servers.  In this case, we assume server
             * and process that way.
             */
            if(iServerSip && iServerDip)
            {
                /*
                 * We check for the case where both SIP and DIP
                 * appear to be servers.  In this case, we look at
                 * the first few bytes of the packet to try to
                 * determine direction -- 3 digits indicate server
                 * response.
                 */

                /* look at the first few bytes of the packet.  We might
                 * be wrong if this is a reassembled packet and we catch
                 * a server response mid-stream.
                 */
                *piInspectMode = FTPGetPacketDir(p);
                if (*piInspectMode == FTPP_SI_SERVER_MODE)
                {
                    /* Packet is from server --> src is Server */
                    *ClientConf = ClientConfDip;
                    *ServerConf = ServerConfSip;
                }
                else /* Assume client */
                {
                    /* Packet is from client --> dest is Server */
                    *piInspectMode = FTPP_SI_CLIENT_MODE;
                    *ClientConf = ClientConfSip;
                    *ServerConf = ServerConfDip;
                }
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else if(iServerDip)
            {
                /* Packet is from client --> dest is Server */
                *piInspectMode = FTPP_SI_CLIENT_MODE;
                *ClientConf = ClientConfSip;
                *ServerConf = ServerConfDip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else if(iServerSip)
            {
                /* Packet is from server --> src is Server */
                *piInspectMode = FTPP_SI_SERVER_MODE;
                *ClientConf = ClientConfDip;
                *ServerConf = ServerConfSip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            break;

#ifdef TARGET_BASED
            }
#endif

        case FTPP_SI_CLIENT_MODE:
            /* Packet is from client --> dest is Server */
#ifdef TARGET_BASED
            app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);

            if ((app_id == ftp_app_id) || (!app_id && iServerDip))
#else
            if(iServerDip)
#endif
            {
                *piInspectMode = FTPP_SI_CLIENT_MODE;
                *ClientConf = ClientConfSip;
                *ServerConf = ServerConfDip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else
            {
                *piInspectMode = FTPP_SI_NO_MODE;
                iRet = FTPP_NONFATAL_ERR;
            }
            break;

        case FTPP_SI_SERVER_MODE:
            /* Packet is from server --> src is Server */
#ifdef TARGET_BASED
            app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);

            if ((app_id == ftp_app_id) || (!app_id && iServerSip))
#else
            if(iServerSip)
#endif
            {
                *piInspectMode = FTPP_SI_SERVER_MODE;
                *ClientConf = ClientConfDip;
                *ServerConf = ServerConfSip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else
            {
                *piInspectMode = FTPP_SI_NO_MODE;
                iRet = FTPP_NONFATAL_ERR;
            }
            break;

        default:
            *piInspectMode = FTPP_SI_NO_MODE;
            *ClientConf = NULL;
            *ServerConf = NULL;
            break;
    }

    return iRet;
}
Esempio n. 3
0
/*
 * Function: TelnetSessionInspection(Packet *p,
 *                          FTPTELNET_GLOBAL_CONF *GlobalConf,
 *                          FTPP_SI_INPUT *SiInput,
 *                          int *piInspectMode)
 *
 * Purpose: The Session Inspection module selects the appropriate
 *          configuration for the session, and the type of inspection
 *          to be performed (client or server.)
 *
 *          When the Session Inspection module is in stateful mode, it
 *          checks to see if there is a TELNET_SESSION pointer already
 *          associated with the stream.  If there is, then it uses that
 *          session pointer, otherwise it calculates the server configuration
 *          using the FTP_SI_INPUT and returns a TELNET_SESSION pointer.  In
 *          stateful mode, this means that memory is allocated, but in
 *          stateless mode, the same session pointer is used for all packets
 *          to reduce the allocation overhead.
 *
 *          The inspection mode can be either client or server.
 *
 * Arguments: p             => pointer to the packet/stream
 *            GlobalConf    => pointer to the global configuration
 *            Session       => double pointer to the Session structure
 *            SiInput       => pointer to the session information
 *            piInspectMode => pointer for setting inspection mode
 *
 * Returns: int => return code indicating error or success
 *
 */
int TelnetSessionInspection(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf,
        FTPP_SI_INPUT *SiInput, int *piInspectMode)
{
    TELNET_SESSION *TelnetSession;
    int iRet;
    int iTelnetSip;
    int iTelnetDip;

    iTelnetSip = PortMatch((PROTO_CONF*)&GlobalConf->global_telnet,
                           SiInput->sport);
    iTelnetDip = PortMatch((PROTO_CONF*)&GlobalConf->global_telnet,
                           SiInput->dport);

    if (iTelnetSip)
    {
        *piInspectMode = FTPP_SI_SERVER_MODE;
    }
    else if (iTelnetDip)
    {
        *piInspectMode = FTPP_SI_CLIENT_MODE;
    }
    else
    {
        return FTPP_INVALID_PROTO;
    }

    SiInput->pproto = FTPP_SI_PROTO_TELNET;

    /*
     * We get the server configuration and the session structure differently 
     * depending on what type of inspection we are doing.  In the case of 
     * stateful processing, we may get the session structure from the Stream
     * Reassembly module (which includes the server configuration) or the 
     * structure will be allocated and added to the stream pointer for the
     * rest of the session.
     *
     * In stateless mode, we just use a static variable that is contained in
     * the function here.
     */
    if(GlobalConf->inspection_type == FTPP_UI_CONFIG_STATEFUL)
    {
        iRet = TelnetStatefulSessionInspection(p, GlobalConf, &TelnetSession, SiInput);
        if (iRet)
        {
            return iRet;
        }

        if (p->stream_session_ptr)
        {
            _dpd.streamAPI->set_application_data(p->stream_session_ptr,
                    PP_TELNET, TelnetSession, &TelnetFreeSession);
        }
        else
        {
            /* Uh, can't create the session info */
            /* Free session data, to avoid memory leak */
            TelnetFreeSession(TelnetSession);
            return FTPP_NONFATAL_ERR;
        }
    }
    else
    {
        /*
         * Assume stateless processing otherwise
         */
        iRet = TelnetStatelessSessionInspection(p, GlobalConf, &TelnetSession, SiInput);
        if (iRet)
        {
            return iRet;
        }

        if (p->stream_session_ptr)
        {
            /* Set the free function pointer to NULL, 
             * since this is a static one */
            _dpd.streamAPI->set_application_data(p->stream_session_ptr,
                    PP_TELNET, TelnetSession, NULL);
        }
        else
        {
            /* Uh, can't create the session info */
            return FTPP_NONFATAL_ERR;
        }
    }

    SiInput->pproto = FTPP_SI_PROTO_TELNET;

    return FTPP_SUCCESS;
}