⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spp_ssl.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (C) 2007-2008 Sourcefire, Inc.**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License Version 2 as** published by the Free Software Foundation.  You may not use, modify or** distribute this program under any other version of the GNU General** Public License.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* * Adam Keeton * SSLPP Preprocessor * 10/10/07 **/#ifdef HAVE_CONFIG_H#include "config.h"#endif  /* HAVE_CONFIG_H */#include "sf_snort_packet.h"#include "sf_dynamic_preprocessor.h"#include "sf_snort_plugin_api.h"#include "debug.h"#include "preprocids.h"#include "spp_ssl.h"#include <stdio.h>#include <syslog.h>#include <string.h>#ifndef WIN32#include <strings.h>#include <sys/time.h>#endif#include <stdlib.h>#include <ctype.h>#include "profiler.h"#ifdef PERF_PROFILINGPreprocStats sslpp_perf_stats;#endif#define GENERATOR_SPP_SSLPP	133/* Ultimately calls SnortEventqAdd *//* Arguments are: gid, sid, rev, classification, priority, message, rule_info */#define ALERT(x,y) { _dpd.alertAdd(GENERATOR_SPP_SSLPP, x, 1, 0, 3, y, 0 ); }/* Wraps disabling detect with incrementing the counter */#define DISABLE_DETECT() { _dpd.disableDetect(packet); counts.disabled++; }extern DynamicPreprocessorData _dpd;static SSLPP_config_t config;static SSLPP_counters_t counts;static void SSL_UpdateCounts(const uint32_t);#if DEBUGstatic void SSL_PrintFlags(uint32_t);#endifstatic INLINE int SSLPP_is_encrypted(u_int32_t ssl_flags, SFSnortPacket *packet) {    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;}static INLINE u_int32_t SSLPP_process_alert(        u_int32_t ssn_flags, u_int32_t new_flags, SFSnortPacket *packet){    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Process Alert\n"););    ssn_flags |= new_flags;    /* Check if we've seen a handshake, that this isn't it,     * that the cipher flags is not set, and that we are disabling detection */    if(SSL_IS_HANDSHAKE(ssn_flags) &&        !SSL_IS_HANDSHAKE(new_flags) &&       !(new_flags & SSL_CHANGE_CIPHER_FLAG) &&       (config.flags & SSLPP_DISABLE_FLAG))    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Disabling detect\n"););        DISABLE_DETECT();    }    /* Need to negate the application flags from the opposing side. */    if(packet->flags & FLAG_FROM_CLIENT)        return ssn_flags & ~SSL_SAPP_FLAG;    else if(packet->flags & FLAG_FROM_SERVER)        return ssn_flags & ~SSL_CAPP_FLAG;    return ssn_flags;}static INLINE u_int32_t SSLPP_process_hs(u_int32_t ssl_flags, u_int32_t new_flags){    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Process Handshake\n"););    if(!SSL_BAD_HS(new_flags))    {        ssl_flags |= new_flags & (SSL_CLIENT_HELLO_FLAG |                                   SSL_SERVER_HELLO_FLAG |                                  SSL_CLIENT_KEYX_FLAG |                                  SSL_SFINISHED_FLAG);    }    else    {        counts.bad_handshakes++;    }    return ssl_flags;}static INLINE u_int32_t SSLPP_process_app(        u_int32_t ssn_flags, u_int32_t new_flags, SFSnortPacket *packet) {    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Process Application\n"););    if(!(config.flags & SSLPP_DISABLE_FLAG))        return ssn_flags | new_flags;    if(SSLPP_is_encrypted(ssn_flags | new_flags, packet) )     {        ssn_flags |= SSL_ENCRYPTED_FLAG;        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "STOPPING INSPECTION (process_app)\n"););        _dpd.streamAPI->stop_inspection(packet->stream_session_ptr,                           packet, SSN_DIR_BOTH, -1, 0);        counts.stopped++;    }    return ssn_flags | new_flags;}static INLINE void SSLPP_process_other(        u_int32_t ssn_flags, u_int32_t new_flags, SFSnortPacket *packet) {    /* Encrypted SSLv2 will appear unrecognizable.  Check if the handshake was     * seen and stop inspecting if so. */    /* Check for an existing handshake from both sides */    if((ssn_flags & SSL_VER_SSLV2_FLAG) &&        SSL_IS_CHELLO(ssn_flags) && SSL_IS_SHELLO(ssn_flags) &&       (config.flags & SSLPP_DISABLE_FLAG) && !(new_flags & SSL_CHANGE_CIPHER_FLAG))    {        ssn_flags |= SSL_ENCRYPTED_FLAG | new_flags;        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "STOPPING INSPECTION (process_other)\n"););        _dpd.streamAPI->stop_inspection(packet->stream_session_ptr,                                        packet, SSN_DIR_BOTH, -1, 0);    }    else    {        counts.unrecognized++;        /* Special handling for SSLv2 */        if(new_flags & SSL_VER_SSLV2_FLAG)             ssn_flags |= new_flags;        if(new_flags & SSL_UNKNOWN_FLAG)            ssn_flags |= new_flags;/* The following block is intentionally disabled. *//* If we were unable to decode the packet, and previous packets had been  * missed,  we will not assume it is encrypted SSLv2. */#if 0        /* More special handling for SSLv2.         * If both server-side and client-side data was missed, and it has not         * been identified it as TLS, it is possibly encrypted SSLv2. */        if( !(ssn_flags & ( SSL_VER_SSLV3_FLAG | SSL_VER_TLS10_FLAG |                            SSL_VER_TLS11_FLAG | SSL_VER_TLS12_FLAG)) )        {            if(packet->stream_session_ptr &&                 _dpd.streamAPI->missed_packets(                    packet->stream_session_ptr, SSN_DIR_SERVER) &&                 _dpd.streamAPI->missed_packets(                     packet->stream_session_ptr, SSN_DIR_CLIENT) )                ssn_flags |= SSL_VER_SSLV2_FLAG;        }#endif    }     /* Still need to set application data here because some of the ssn_flags     * flags were cleared in SSL_CLEAR_TEMPORARY_FLAGS */    _dpd.streamAPI->set_application_data(packet->stream_session_ptr, PP_SSL,                                         (void *)(uintptr_t)ssn_flags, NULL);}/* SSL Preprocessor process callback. */static void SSLPP_process(void *raw_packet, void *context){    SFSnortPacket *packet;    u_int32_t ssn_flags;    u_int32_t new_flags;    PROFILE_VARS;        PREPROC_PROFILE_START(sslpp_perf_stats);    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL Start ================================\n"););    packet = (SFSnortPacket*)raw_packet;    if(!packet || !packet->payload || !packet->payload_size ||        !packet->tcp_header || !packet->stream_session_ptr)    {#ifdef DEBUG        if (packet == NULL)        {            DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - Packet is NULL\n"););        }        if (packet->payload == NULL)        {            DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - Packet payload is NULL\n"););        }        if (packet->payload_size == 0)        {            DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - Packet payload size is 0\n"););        }        if (packet->tcp_header == NULL)        {            DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - Packet is not TCP\n"););        }        if (packet->stream_session_ptr == NULL)        {            DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - No stream session pointer\n"););        }        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - Not inspecting packet\n"););        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL End ================================\n"););#endif        PREPROC_PROFILE_END(sslpp_perf_stats);        return;    }    /* Make sure the packet is on the right port */    if(!config.ports[ PORT_INDEX(packet->src_port) ] &&       !config.ports[ PORT_INDEX(packet->dst_port) ])    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL - Not configured for these ports\n"););        PREPROC_PROFILE_END(sslpp_perf_stats);        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL End ================================\n"););        return;    }#ifdef DEBUG    if (packet->flags & FLAG_FROM_SERVER)    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Server packet\n"););    }    else    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Client packet\n"););    }    if (packet->flags & FLAG_REBUILT_STREAM)    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Packet is rebuilt\n"););    }#endif    ssn_flags = (u_int32_t)(uintptr_t)        _dpd.streamAPI->get_application_data(packet->stream_session_ptr, PP_SSL);    /* Flush opposite direction to keep conversation in sync */    if (!(packet->flags & FLAG_REBUILT_STREAM))    {        switch (_dpd.streamAPI->get_reassembly_direction(packet->stream_session_ptr))        {            case SSN_DIR_SERVER:                if (packet->flags & FLAG_FROM_SERVER)                {                    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Flushing server side\n"););                    _dpd.streamAPI->response_flush_stream(packet);                }                break;            case SSN_DIR_CLIENT:                if (packet->flags & FLAG_FROM_CLIENT)                {                    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Flushing client side\n"););                    _dpd.streamAPI->response_flush_stream(packet);                }                break;            case SSN_DIR_BOTH:                DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Flushing opposite side\n"););                _dpd.streamAPI->response_flush_stream(packet);                break;            case SSN_DIR_NONE:            default:                break;        }    }    if (packet->flags & FLAG_STREAM_INSERT)    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Packet is stream inserted - not inspecting\n"););        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL End ================================\n"););        return;    }#ifdef DEBUG    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Ssn flags before ----------------------\n"););    SSL_PrintFlags(ssn_flags);    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "---------------------------------------\n"););#endif    SSL_CLEAR_TEMPORARY_FLAGS(ssn_flags);#ifdef DEBUG    if (packet->payload_size >= 5)    {        const uint8_t *pkt = packet->payload;        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Five bytes of data: %02x %02x %02x %02x %02x\n",                                pkt[0], pkt[1], pkt[2], pkt[3], pkt[4]););    }    else    {        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Payload size < 5 bytes"););    }#endif    new_flags = SSL_decode(packet->payload, packet->payload_size, packet->flags);    counts.decoded++;#ifdef DEBUG    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "New flags -----------------------------\n"););    SSL_PrintFlags(new_flags);    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "---------------------------------------\n"););#endif    SSL_UpdateCounts(new_flags);    /* Note, there can be multiple record types in each SSL packet.     * Processing them in this order is intentional.  If there is an     * Alert, we don't care about the other records */    if(SSL_IS_ALERT(new_flags))    {        ssn_flags = SSLPP_process_alert(ssn_flags, new_flags, packet);    }    else if(SSL_IS_HANDSHAKE(new_flags))    {        ssn_flags = SSLPP_process_hs(ssn_flags, new_flags);    }    else if(SSL_IS_APP(new_flags))    {        ssn_flags = SSLPP_process_app(ssn_flags, new_flags, packet);    }    else     {        /* Different record type that we don't care about.         * Either it's a 'change cipher spec' or we failed to recognize the         * record type.  Do not update session data */        SSLPP_process_other(ssn_flags, new_flags, packet);                /* Application data is updated inside of SSLPP_process_other */        PREPROC_PROFILE_END(sslpp_perf_stats);        DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL End ================================\n"););        return;    }    ssn_flags |= new_flags;#if DEBUG    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "Ssn flags after -----------------------\n"););    SSL_PrintFlags(ssn_flags);    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "---------------------------------------\n"););#endif    _dpd.streamAPI->set_application_data(                packet->stream_session_ptr, PP_SSL,                (void*)(uintptr_t)ssn_flags, NULL);    PREPROC_PROFILE_END(sslpp_perf_stats);    DEBUG_WRAP(DebugMessage(DEBUG_SSL, "SSL End ================================\n"););}static void SSL_UpdateCounts(const uint32_t new_flags){    if(new_flags & SSL_CHANGE_CIPHER_FLAG)         counts.cipher_change++;    if (new_flags & SSL_ALERT_FLAG)        counts.alerts++;    if (new_flags & SSL_CLIENT_HELLO_FLAG)        counts.hs_chello++;    if (new_flags & SSL_SERVER_HELLO_FLAG)        counts.hs_shello++;    if (new_flags & SSL_CERTIFICATE_FLAG)        counts.hs_cert++;    if (new_flags & SSL_SERVER_KEYX_FLAG)        counts.hs_skey++;    if (new_flags & SSL_CLIENT_KEYX_FLAG)        counts.hs_ckey++;    if (new_flags & SSL_SFINISHED_FLAG)        counts.hs_finished++;    if (new_flags & SSL_HS_SDONE_FLAG)        counts.hs_sdone++;    if (new_flags & SSL_SAPP_FLAG)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -