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

📄 snort_smtp.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Handle DATA_BODY state * * @param   packet  standard Packet structure * * @param   i       index into p->payload buffer to start looking at data * * @return  i       index into p->payload where we stopped looking at data */static const u_int8_t * SMTP_HandleDataBody(SFSnortPacket *p, const u_int8_t *ptr,                                            const u_int8_t *data_end_marker){    int boundary_found = 0;    const u_int8_t *boundary_ptr = NULL;    /* look for boundary */    if (_smtp->state_flags & SMTP_FLAG_GOT_BOUNDARY)    {        boundary_found = _dpd.searchAPI->search_instance_find(_smtp->mime_boundary.boundary_search,                                                              (const char *)ptr, data_end_marker - ptr,                                                              0, SMTP_BoundaryStrFound);        if (boundary_found > 0)        {            boundary_ptr = ptr + _smtp_search_info.index;            /* should start at beginning of line */            if ((boundary_ptr == ptr) || (*(boundary_ptr - 1) == '\n'))            {                const u_int8_t *eol;                const u_int8_t *eolm;                const u_int8_t *tmp;                /* Check for end boundary */                tmp = boundary_ptr + _smtp_search_info.length;                if (((tmp + 1) < data_end_marker) && (tmp[0] == '-') && (tmp[1] == '-'))                {                    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Mime boundary end found: %s--\n",                                            (char *)_smtp->mime_boundary.boundary););                    /* no more MIME */                    _smtp->state_flags &= ~SMTP_FLAG_GOT_BOUNDARY;                    /* free boundary search */                    _dpd.searchAPI->search_instance_free(_smtp->mime_boundary.boundary_search);                    _smtp->mime_boundary.boundary_search = NULL;                }                else                {                    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Mime boundary found: %s\n",                                            (char *)_smtp->mime_boundary.boundary););                    _smtp->data_state = STATE_MIME_HEADER;                }                /* get end of line - there could be spaces after boundary before eol */                SMTP_GetEOL(boundary_ptr + _smtp_search_info.length, data_end_marker, &eol, &eolm);                return eol;            }        }    }            return data_end_marker;}/* * Process client packet * * @param   packet  standard Packet structure * * @return  none */static void SMTP_ProcessClientPacket(SFSnortPacket *p){    const u_int8_t *ptr = NULL;    const u_int8_t *end = NULL;    if (_smtp->state == STATE_CONNECT)    {        _smtp->state = STATE_COMMAND;    }    ptr = p->payload;    end = p->payload + p->payload_size;    while ((ptr != NULL) && (ptr < end))    {        switch (_smtp->state)        {            case STATE_COMMAND:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "COMMAND STATE ~~~~~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleCommand(p, ptr, end);                break;            case STATE_DATA:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA STATE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleData(p, ptr, end);                break;            case STATE_DATA_PEND:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA PEND STATE ~~~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleData(p, ptr, end);                break;            default:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Unknown SMTP state\n"););                return;        }    }#ifdef DEBUG    if (_smtp_normalizing)    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Normalized payload\n%s\n", SMTP_PrintBuffer(p)););    }#endif    return;}/* very simplistic - just enough to say this is binary data - the rules will make a final  * judgement.  Should maybe add an option to the smtp configuration to enable the  * continuing of command inspection like ftptelnet. */static int SMTP_IsTlsClientHello(const u_int8_t *ptr, const u_int8_t *end){    /* at least 7 bytes of data - see below */    if ((end - ptr) < 3)        return 0;    if ((ptr[0] == 0x16) && (ptr[1] == 0x03))    {        /* TLS v1 or SSLv3 */        return 1;    }    else if ((ptr[2] == 0x01) || (ptr[3] == 0x01))    {        /* SSLv2 */        return 1;    }    return 0;}/* this may at least tell us whether the server accepted the client hello by the presence * of binary data */static int SMTP_IsTlsServerHello(const u_int8_t *ptr, const u_int8_t *end){    /* at least 7 bytes of data - see below */    if ((end - ptr) < 3)        return 0;    if ((ptr[0] == 0x16) && (ptr[1] == 0x03))    {        /* TLS v1 or SSLv3 */        return 1;    }    else if (ptr[2] == 0x04)    {        /* SSLv2 */        return 1;    }    return 0;}/* * Process server packet * * @param   packet  standard Packet structure * * @return  do_flush * @retval  1           flush queued packets on client side * @retval  0           do not flush queued packets on client side */static int SMTP_ProcessServerPacket(SFSnortPacket *p){    int resp_found;    const u_int8_t *ptr;    const u_int8_t *end;    const u_int8_t *eolm;    const u_int8_t *eol;    const u_int8_t *dash;    int do_flush = 0;     int resp_line_len;    ptr = p->payload;    end = p->payload + p->payload_size;    if (_smtp->state == STATE_TLS_SERVER_PEND)    {        if (SMTP_IsTlsServerHello(ptr, end))        {            _smtp->state = STATE_TLS_DATA;        }        else        {            /* revert back to command state - assume server didn't accept STARTTLS */            _smtp->state = STATE_COMMAND;        }    }            if (_smtp->state == STATE_TLS_DATA)    {        /* Ignore data */        if (_smtp_config.ignore_tls_data)        {            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Ignoring Server TLS encrypted data\n"););            p->normalized_payload_size = 0;            p->flags |= FLAG_ALT_DECODE;        }        return 0;    }        while (ptr < end)    {        SMTP_GetEOL(ptr, end, &eol, &eolm);        resp_line_len = eol - ptr;                if ((_smtp_config.max_response_line_len != 0) &&            (resp_line_len > _smtp_config.max_response_line_len))        {            SMTP_GenerateAlert(SMTP_RESPONSE_OVERFLOW, "%s: %d chars",                               SMTP_RESPONSE_OVERFLOW_STR, resp_line_len);        }        /* Check for response code */        _smtp_current_search = &_smtp_resp_search[0];        resp_found = _dpd.searchAPI->search_find(SEARCH_RESP, (const char *)ptr,                                                 eol - ptr, 1, SMTP_SearchStrFound);                if (resp_found > 0)        {            switch (_smtp_search_info.id)            {                case RESP_220:                    /* This is either an initial server response or a STARTTLS response                     * flush the client side. if we've already seen STARTTLS, no need                     * to flush */                    if (_smtp->state == STATE_CONNECT)                    {                        _smtp->state = STATE_COMMAND;                    }                    else if (_smtp->state != STATE_TLS_CLIENT_PEND)                    {                        do_flush = 1;                    }                    break;                case RESP_354:                    /* we may have processed a complete message before receiving data response and                     * moved back to command state.  if we're pending response, move to data state                     * otherwise recognize the response, but set got data command to zero.                     * this is to ensure that we don't flush when we don't need to. */                    if (_smtp->state_flags & SMTP_FLAG_GOT_DATA_CMD)                    {                        if (_smtp->state == STATE_DATA_PEND)                        {                            _smtp->state = STATE_DATA;                        }                                                _smtp->state_flags &= ~SMTP_FLAG_GOT_DATA_CMD;                    }                    else                    {                        _smtp->state_flags |= SMTP_FLAG_GOT_DATA_RESP;                        do_flush = 1;                    }                    break;                default:                    break;            }            dash = ptr + _smtp_search_info.index + _smtp_search_info.length;            /* only add response if not a dash after response code */            if ((dash == eolm) || ((dash < eolm) && (*dash != '-')))            {                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Server sent %s response\n",                                                     _smtp_resps[_smtp_search_info.id].name););            }        }                ptr = eol;    }    return do_flush;}/* * Entry point to snort preprocessor for each packet * * @param   packet  standard Packet structure * * @return  none */void SnortSMTP(SFSnortPacket *p){    int detected = 0;    int do_flush = 0;    PROFILE_VARS;    /* Ignore if no data */    if (p->payload_size == 0)    {#ifdef DEBUG        int pkt_dir = SMTP_GetPacketDirection(p, 0);        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "SMTP %s packet\n",                                pkt_dir == SMTP_PKT_FROM_SERVER ? "server" :                                (pkt_dir == SMTP_PKT_FROM_CLIENT ? "client" : "unknown")););        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "No payload to inspect\n"););#endif        return;    }        SMTP_Setup(p);    /* Figure out direction of packet */    _smtp_pkt_direction = SMTP_GetPacketDirection(p, 1);    if (_smtp_pkt_direction == SMTP_PKT_FROM_SERVER)    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "SMTP server packet\n"););        /* Process as a server packet */        do_flush = SMTP_ProcessServerPacket(p);        if (do_flush)        {            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Flushing stream\n"););            _dpd.streamAPI->response_flush_stream(p);        }    }    else if (_smtp_pkt_direction == SMTP_PKT_FROM_CLIENT)    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "SMTP client packet\n"););        /* This packet should be a tls client hello */        if (_smtp->state == STATE_TLS_CLIENT_PEND)        {            if (SMTP_IsTlsClientHello(p->payload, p->payload + p->payload_size))            {                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "TLS DATA STATE ~~~~~~~~~~~~~~~~~~~~~~~~~\n"););                _smtp->state = STATE_TLS_SERVER_PEND;            }            else            {                /* reset state - server may have rejected STARTTLS command */                _smtp->state = STATE_COMMAND;            }        }        if ((_smtp->state == STATE_TLS_DATA) || (_smtp->state == STATE_TLS_SERVER_PEND))        {            /* if we're ignoring tls data, set a zero length alt buffer */            if (_smtp_config.ignore_tls_data)            {                p->normalized_payload_size = 0;                p->flags |= FLAG_ALT_DECODE;            }        }        else        {            if (p->flags & FLAG_STREAM_INSERT)            {                /* Packet will be rebuilt, so wait for it */                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Client packet will be reassembled\n"));                /* Turn off detection until we get the rebuilt packet. */                SMTP_DisableDetect(p);                return;            }#ifdef DEBUG            /* Interesting to see how often packets are rebuilt */            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Payload: %s\n%s\n",                                    (p->flags & FLAG_REBUILT_STREAM) ? "reassembled" : "not reassembled",                                    SMTP_PrintBuffer(p)););#endif            SMTP_ProcessClientPacket(p);        }    }    else    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "SMTP packet NOT from client or server! "                                            "Processing as a client packet\n"););        SMTP_ProcessClientPacket(p);    }    PREPROC_PROFILE_START(smtpDetectPerfStats);    detected = _dpd.detect(p);#ifdef PERF_PROFILING    smtpDetectCalled = 1;#endif    PREPROC_PROFILE_END(smtpDetectPerfStats);    /* Turn off detection since we've already done it. */    SMTP_DisableDetect(p);         if ( detected )    {        DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "SMTP vulnerability detected\n"););    }}static void SMTP_DisableDetect(SFSnortPacket *p){    _dpd.disableAllDetect(p);    _dpd.setPreprocBit(p, PP_SFPORTSCAN);    _dpd.setPreprocBit(p, PP_PERFMONITOR);    _dpd.setPreprocBit(p, PP_STREAM4);    _dpd.setPreprocBit(p, PP_STREAM5);}

⌨️ 快捷键说明

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