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

📄 snort_smtp.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* XXX A line starting with a '.' that isn't followed by a '.' is         * deleted (RFC 821 - 4.5.2.  TRANSPARENCY).  If data starts with         * '. text', i.e a dot followed by white space then text, some         * servers consider it data header and some data body.         * Postfix and Qmail will consider the start of data:         * . text\r\n         * .  text\r\n         * to be part of the header and the effect will be that of a          * folded line with the '.' deleted.  Exchange will put the same         * in the body which seems more reasonable. */    }    /* get end of data body     * TODO check last bytes of previous packet to see if we had a partial     * end of data */    _smtp_current_search = &_smtp_data_end_search[0];    data_end_found = _dpd.searchAPI->search_find(SEARCH_DATA_END, (const char *)ptr,                                                 end - ptr, 0, SMTP_SearchStrFound);    if (data_end_found > 0)    {        data_end_marker = ptr + _smtp_search_info.index;        data_end = data_end_marker + _smtp_search_info.length;    }    else    {        data_end_marker = data_end = end;    }    if ((_smtp->data_state == STATE_DATA_HEADER) ||        (_smtp->data_state == STATE_DATA_UNKNOWN))    {#ifdef DEBUG        if (_smtp->data_state == STATE_DATA_HEADER)        {            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA HEADER STATE ~~~~~~~~~~~~~~~~~~~~~~\n"););        }        else        {            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA UNKNOWN STATE ~~~~~~~~~~~~~~~~~~~~~\n"););        }#endif        ptr = SMTP_HandleHeader(p, ptr, data_end_marker);        if (ptr == NULL)            return NULL;    }    /* if we're ignoring data and not already normalizing, copy everything     * up to here into alt buffer so detection engine doesn't have     * to look at the data; otherwise, if we're normalizing and not     * ignoring data, copy all of the data into the alt buffer */    if (_smtp_config.ignore_data && !_smtp_normalizing)    {        ret = SMTP_CopyToAltBuffer(p, p->payload, ptr - p->payload);        if (ret == -1)            return NULL;    }    else if (!_smtp_config.ignore_data && _smtp_normalizing)    {        ret = SMTP_CopyToAltBuffer(p, ptr, data_end - ptr);        if (ret == -1)            return NULL;    }    /* now we shouldn't have to worry about copying any data to the alt buffer     * only mime headers if we find them and only if we're ignoring data */    while ((ptr != NULL) && (ptr < data_end_marker))    {        switch (_smtp->data_state)        {            case STATE_MIME_HEADER:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "MIME HEADER STATE ~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleHeader(p, ptr, data_end_marker);                break;            case STATE_DATA_BODY:                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "DATA BODY STATE ~~~~~~~~~~~~~~~~~~~~~~~~\n"););                ptr = SMTP_HandleDataBody(p, ptr, data_end_marker);                break;        }    }    /* if we got the data end reset state, otherwise we're probably still in the data     * to expect more data in next packet */    if (data_end_marker != end)    {        SMTP_ResetState();    }    return data_end;}/* * Handle Headers - Data or Mime * * @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_HandleHeader(SFSnortPacket *p, const u_int8_t *ptr,                                          const u_int8_t *data_end_marker){    const u_int8_t *eol;    const u_int8_t *eolm;    const u_int8_t *colon;    const u_int8_t *content_type_ptr = NULL;    int header_line_len;    int header_found;    int ret;    const u_int8_t *start_hdr;    int header_name_len;    start_hdr = ptr;    /* if we got a content-type in a previous packet and are     * folding, the boundary still needs to be checked for */    if (_smtp->state_flags & SMTP_FLAG_IN_CONTENT_TYPE)        content_type_ptr = ptr;    while (ptr < data_end_marker)    {        SMTP_GetEOL(ptr, data_end_marker, &eol, &eolm);        /* got a line with only end of line marker should signify end of header */        if (eolm == ptr)        {            /* reset global header state values */            _smtp->state_flags &=                ~(SMTP_FLAG_FOLDING | SMTP_FLAG_IN_CONTENT_TYPE | SMTP_FLAG_DATA_HEADER_CONT);            _smtp->data_state = STATE_DATA_BODY;            /* if no headers, treat as data */            if (ptr == start_hdr)                return eolm;            else                return eol;        }        /* if we're not folding, see if we should interpret line as a data line          * instead of a header line */        if (!(_smtp->state_flags & (SMTP_FLAG_FOLDING | SMTP_FLAG_DATA_HEADER_CONT)))        {            char got_non_printable_in_header_name = 0;            /* if we're not folding and the first char is a space or             * colon, it's not a header */            if (isspace((int)*ptr) || *ptr == ':')            {                _smtp->data_state = STATE_DATA_BODY;                return ptr;            }            /* look for header field colon - if we're not folding then we need             * to find a header which will be all printables (except colon)              * followed by a colon */            colon = ptr;            while ((colon < eolm) && (*colon != ':'))            {                if (((int)*colon < 33) || ((int)*colon > 126))                    got_non_printable_in_header_name = 1;                colon++;            }            /* Check for Exim 4.32 exploit where number of chars before colon is greater than 64 */            header_name_len = colon - ptr;            if ((_smtp->data_state != STATE_DATA_UNKNOWN) &&                (colon < eolm) && (header_name_len > MAX_HEADER_NAME_LEN))            {                SMTP_GenerateAlert(SMTP_HEADER_NAME_OVERFLOW, "%s: %d chars before colon",                                   SMTP_HEADER_NAME_OVERFLOW_STR, header_name_len);            }            /* If the end on line marker and end of line are the same, assume             * header was truncated, so stay in data header state */            if ((eolm != eol) &&                ((colon == eolm) || got_non_printable_in_header_name))            {                /* no colon or got spaces in header name (won't be interpreted as a header)                 * assume we're in the body */                _smtp->state_flags &=                    ~(SMTP_FLAG_FOLDING | SMTP_FLAG_IN_CONTENT_TYPE | SMTP_FLAG_DATA_HEADER_CONT);                _smtp->data_state = STATE_DATA_BODY;                return ptr;            }            _smtp_current_search = &_smtp_hdr_search[0];            header_found = _dpd.searchAPI->search_find(SEARCH_HDR, (const char *)ptr,                                                       eolm - ptr, 1, SMTP_SearchStrFound);            /* Headers must start at beginning of line */            if ((header_found > 0) && (_smtp_search_info.index == 0))            {                switch (_smtp_search_info.id)                {                    case HDR_CONTENT_TYPE:                        /* for now we're just looking for the boundary in the data                         * header section */                        if (_smtp->data_state != STATE_MIME_HEADER)                        {                            content_type_ptr = ptr + _smtp_search_info.length;                            _smtp->state_flags |= SMTP_FLAG_IN_CONTENT_TYPE;                        }                        break;                                            default:                        break;                }            }        }        else        {            _smtp->state_flags &= ~SMTP_FLAG_DATA_HEADER_CONT;        }                /* get length of header line */        header_line_len = eol - ptr;        if ((_smtp_config.max_header_line_len != 0) &&            (header_line_len > _smtp_config.max_header_line_len))        {            if (_smtp->data_state != STATE_DATA_UNKNOWN)            {                SMTP_GenerateAlert(SMTP_DATA_HDR_OVERFLOW, "%s: %d chars",                                   SMTP_DATA_HDR_OVERFLOW_STR, header_line_len);            }            else            {                /* assume we guessed wrong and are in the body */                _smtp->data_state = STATE_DATA_BODY;                _smtp->state_flags &=                    ~(SMTP_FLAG_FOLDING | SMTP_FLAG_IN_CONTENT_TYPE | SMTP_FLAG_DATA_HEADER_CONT);                return ptr;            }        }        /* XXX Does VRT want data headers normalized?         * currently the code does not normalize headers */        if (_smtp_normalizing)        {            ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);            if (ret == -1)                return NULL;        }        /* check for folding          * if char on next line is a space and not \n or \r\n, we are folding */        if ((eol < data_end_marker) && isspace((int)eol[0]) && (eol[0] != '\n'))        {            if ((eol < (data_end_marker - 1)) && (eol[0] != '\r') && (eol[1] != '\n'))            {                _smtp->state_flags |= SMTP_FLAG_FOLDING;            }            else            {                _smtp->state_flags &= ~SMTP_FLAG_FOLDING;            }        }        else if (eol != eolm)        {            _smtp->state_flags &= ~SMTP_FLAG_FOLDING;        }        /* check if we're in a content-type header and not folding. if so we have the whole         * header line/lines for content-type - see if we got a multipart with boundary         * we don't check each folded line, but wait until we have the complete header         * because boundary=BOUNDARY can be split across mulitple folded lines before         * or after the '=' */        if ((_smtp->state_flags &             (SMTP_FLAG_IN_CONTENT_TYPE | SMTP_FLAG_FOLDING)) == SMTP_FLAG_IN_CONTENT_TYPE)        {            /* we got the full content-type header - look for boundary string */            ret = SMTP_GetBoundary((const char *)content_type_ptr, eolm - content_type_ptr);            if (ret != -1)            {                ret = SMTP_BoundarySearchInit();                if (ret != -1)                {                    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Got mime boundary: %s\n",                                                         _smtp->mime_boundary.boundary););                    _smtp->state_flags |= SMTP_FLAG_GOT_BOUNDARY;                }            }            _smtp->state_flags &= ~SMTP_FLAG_IN_CONTENT_TYPE;            content_type_ptr = NULL;        }        /* if state was unknown, at this point assume we know */        if (_smtp->data_state == STATE_DATA_UNKNOWN)            _smtp->data_state = STATE_DATA_HEADER;        ptr = eol;        if (ptr == data_end_marker)            _smtp->state_flags |= SMTP_FLAG_DATA_HEADER_CONT;    }    return ptr;}/* * 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 = p->payload;    const u_int8_t *end = p->payload + p->payload_size;    if (_smtp->state == STATE_CONNECT)        _smtp->state = STATE_COMMAND;    while ((ptr != NULL) && (ptr < end))    {        switch (_smtp->state)        {

⌨️ 快捷键说明

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