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

📄 snort_smtp.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 5 页
字号:
    *mime_boundary_len = 2 + boundary_len;    mime_boundary[*mime_boundary_len] = '\0';    return 0;}/* * Handle COMMAND state * * @param   p       standard Packet structure * @param   ptr     pointer into p->payload buffer to start looking at data * @param   end     points to end of p->payload buffer * * @return          pointer into p->payload where we stopped looking at data *                  will be end of line or end of packet */static const u_int8_t * SMTP_HandleCommand(SFSnortPacket *p, const u_int8_t *ptr, const u_int8_t *end){    const u_int8_t *eol;   /* end of line */    const u_int8_t *eolm;  /* end of line marker */    int cmd_line_len;    int ret;    int cmd_found;    char alert_long_command_line = 0;    /* get end of line and end of line marker */    SMTP_GetEOL(ptr, end, &eol, &eolm);    /* calculate length of command line */    cmd_line_len = eol - ptr;    /* check for command line exceeding maximum      * do this before checking for a command since this could overflow     * some server's buffers without the presence of a known command */    if ((_smtp_config.max_command_line_len != 0) &&        (cmd_line_len > _smtp_config.max_command_line_len))    {        alert_long_command_line = 1;    }    /* TODO If the end of line marker coincides with the end of payload we can't be     * sure that we got a command and not a substring which we could tell through     * inpsection of the next packet. Maybe a command pending state where the first     * char in the next packet is checked for a space and end of line marker */    /* do not confine since there could be space chars before command */    _smtp_current_search = &_smtp_cmd_search[0];    cmd_found = _dpd.searchAPI->search_find(SEARCH_CMD, (const char *)ptr, eolm - ptr,                                            0, SMTP_SearchStrFound);    /* see if we actually found a command and not a substring */    if (cmd_found > 0)    {        const u_int8_t *tmp = ptr;        const u_int8_t *cmd_start = ptr + _smtp_search_info.index;        const u_int8_t *cmd_end = cmd_start + _smtp_search_info.length;        /* move past spaces up until start of command */        while ((tmp < cmd_start) && isspace((int)*tmp))            tmp++;        /* if not all spaces before command, we found a          * substring */        if (tmp != cmd_start)            cmd_found = 0;                /* if we're before the end of line marker and the next         * character is not whitespace, we found a substring */        if ((cmd_end < eolm) && !isspace((int)*cmd_end))            cmd_found = 0;        /* there is a chance that end of command coincides with the end of payload         * in which case, it could be a substring, but for now, we will treat it as found */    }    /* if command not found, alert and move on */    if (!cmd_found)    {        /* If we missed one or more packets we might not actually be in the command         * state.  Check to see if we're encrypted */        if (_smtp->state == STATE_UNKNOWN)        {            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Command not found, but state is "                                    "unknown - checking for SSL\n"););            /* check for encrypted */            if ((_smtp->session_flags & SMTP_FLAG_CHECK_SSL) &&                (SMTP_IsSSL(ptr, end - ptr, p->flags)))            {                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Packet is SSL encrypted\n"););                _smtp->state = STATE_TLS_DATA;                /* Ignore data */                if (_smtp_config.ignore_tls_data)                {                    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Ignoring encrypted data\n"););                    p->normalized_payload_size = 0;                    p->flags |= FLAG_ALT_DECODE;                }                return end;            }            else            {                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Not SSL - try data state\n"););                /* don't check for ssl again in this packet */                if (_smtp->session_flags & SMTP_FLAG_CHECK_SSL)                    _smtp->session_flags &= ~SMTP_FLAG_CHECK_SSL;                _smtp->state = STATE_DATA;                _smtp->data_state = STATE_DATA_UNKNOWN;                return ptr;            }        }        else        {            DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "No known command found\n"););            if (_smtp_config.alert_unknown_cmds)            {                SMTP_GenerateAlert(SMTP_UNKNOWN_CMD, "%s", SMTP_UNKNOWN_CMD_STR);            }            if (alert_long_command_line)            {                SMTP_GenerateAlert(SMTP_COMMAND_OVERFLOW, "%s: more than %d chars",                                   SMTP_COMMAND_OVERFLOW_STR, _smtp_config.max_command_line_len);            }            /* if normalizing, copy line to alt buffer */            if (_smtp_normalizing)            {                ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);                if (ret == -1)                    return NULL;            }            return eol;        }    }    /* At this point we have definitely found a legitimate command */    DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "%s\n", _smtp_cmds[_smtp_search_info.id].name););    /* check if max command line length for a specific command is exceeded */    if (_smtp_cmd_config[_smtp_search_info.id].max_line_len != 0)    {        if (cmd_line_len > _smtp_cmd_config[_smtp_search_info.id].max_line_len)        {            SMTP_GenerateAlert(SMTP_SPECIFIC_CMD_OVERFLOW, "%s: %s, %d chars",                               SMTP_SPECIFIC_CMD_OVERFLOW_STR,                               _smtp_cmd_search[_smtp_search_info.id].name, cmd_line_len);        }    }    else if (alert_long_command_line)    {        SMTP_GenerateAlert(SMTP_COMMAND_OVERFLOW, "%s: more than %d chars",                           SMTP_COMMAND_OVERFLOW_STR, _smtp_config.max_command_line_len);    }    /* Are we alerting on this command? */    if (_smtp_cmd_config[_smtp_search_info.id].alert)    {        SMTP_GenerateAlert(SMTP_ILLEGAL_CMD, "%s: %s",                           SMTP_ILLEGAL_CMD_STR, _smtp_cmds[_smtp_search_info.id].name);    }    switch (_smtp_search_info.id)    {        /* unless we do our own parsing of MAIL and RCTP commands we have to assume they         * are ok unless we got a server error in which case we flush and if this is a         * reassembled packet, the last command in this packet will be the command that         * caused the error */        case CMD_MAIL:            _smtp->state_flags |= SMTP_FLAG_GOT_MAIL_CMD;            break;        case CMD_RCPT:            if ((_smtp->state_flags & SMTP_FLAG_GOT_MAIL_CMD) ||                _smtp->state == STATE_UNKNOWN)            {                _smtp->state_flags |= SMTP_FLAG_GOT_RCPT_CMD;            }            break;        case CMD_RSET:        case CMD_HELO:        case CMD_EHLO:        case CMD_QUIT:            _smtp->state_flags &= ~(SMTP_FLAG_GOT_MAIL_CMD | SMTP_FLAG_GOT_RCPT_CMD);            break;#if 0        case CMD_BDAT:            {                const u_int8_t *begin_chunk;                const u_int8_t *end_chunk;                const u_int8_t *last;                const u_int8_t *tmp;                int num_digits;                int ten_power;                u_int32_t bdat_chunk;                begin_chunk = ptr + _smtp_search_info.index + _smtp_search_info.length;                while ((begin_chunk < eolm) && isspace((int)*begin_chunk))                    begin_chunk++;                /* bad BDAT command - needs chunk argument */                if (begin_chunk == eolm)                    break;                                    end_chunk = begin_chunk;                while ((end_chunk < eolm) && isdigit((int)*end_chunk))                    end_chunk++;                /* didn't get all digits */                if ((end_chunk < eolm) && !isspace((int)*end_chunk))                    break;                /* get chunk size */                num_digits = end_chunk - begin_chunk;                /* more than 9 digits could potentially overflow a 32 bit integer                 * this allows for one less than a billion bytes which most servers                 * won't accept */                if (num_digits > 9)                    break;                tmp = end_chunk;                for (ten_power = 1, tmp--; tmp >= begin_chunk; ten_power *= 10, tmp--)                {                    bdat_chunk += (*tmp - '0') * ten_power;                }                /* bad bdat chunk size */                if (bdat_chunk == 0)                    break;                /* got a valid chunk size - check to see if this is the last chunk */                last = end_chunk;                while ((last < eolm) && isspace((int)*last))                    last++;                /* TODO need an ESMTP argument search */                if (last < eolm)                {                    /* must have at least 4 chars for 'last' */                    if ((eolm - last) >= 4)                    {                        if (*last == 'l' || *last == 'L')                        {                            last++;                            if (*last == 'a' || *last == 'A')                            {                                last++;                                if (*last == 's' || *last == 'S')                                {                                    last++;                                    if (*last == 't' || *last == 'T')                                    {                                        last++;                                        while ((last < eolm) && isspace((int)*last))                                            last++;                                        if (last != eolm)                                        {                                            break;                                        }                                                                                _smtp->bdat_last = 1;                                    }                                }                            }                        }                    }                }                _smtp->state = STATE_BDAT;                _smtp->bdat_chunk = bdat_chunk;            }            break;#endif        case CMD_BDAT:        case CMD_DATA:            if ((_smtp->state_flags & SMTP_FLAG_GOT_RCPT_CMD) ||                _smtp->state == STATE_UNKNOWN)            {                DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Set to data state.\n"););                _smtp->state = STATE_DATA;                _smtp->state_flags &= ~(SMTP_FLAG_GOT_MAIL_CMD | SMTP_FLAG_GOT_RCPT_CMD);            }            else            {                 DEBUG_WRAP(DebugMessage(DEBUG_SMTP, "Didn't get MAIL -> RCPT command sequence - "                                                     "stay in command state.\n"););            }            break;        case CMD_STARTTLS:            /* if reassembled we flush after seeing a 220 so this should be the last             * command in reassembled packet and if not reassembled it should be the             * last line in the packet as you can't pipeline the tls hello */            if (eol == end)                _smtp->state = STATE_TLS_CLIENT_PEND;            break;                case CMD_X_LINK2STATE:             if (_smtp_config.alert_xlink2state)                ParseXLink2State(p, ptr + _smtp_search_info.index);            break;                    default:            break;    }    /* Since we found a command, if state is still unknown,     * set to command state */    if (_smtp->state == STATE_UNKNOWN)        _smtp->state = STATE_COMMAND;    /* normalize command line */    if (_smtp_config.normalize == NORMALIZE_ALL ||        _smtp_cmd_config[_smtp_search_info.id].normalize)    {        ret = SMTP_NormalizeCmd(p, ptr, eolm, eol);        if (ret == -1)            return NULL;    }                            else if (_smtp_normalizing) /* Already normalizing */    {        ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);        if (ret == -1)            return NULL;    }    return eol;}static const u_int8_t * SMTP_HandleData(SFSnortPacket *p, const u_int8_t *ptr, const u_int8_t *end){    const u_int8_t *data_end_marker = NULL;    const u_int8_t *data_end = NULL;    int data_end_found;    int ret;    /* if we've just entered the data state, check for a dot + end of line     * if found, no data */    if ((_smtp->data_state == STATE_DATA_INIT) ||        (_smtp->data_state == STATE_DATA_UNKNOWN))    {        if ((ptr < end) && (*ptr == '.'))        {            const u_int8_t *eol = NULL;            const u_int8_t *eolm = NULL;            SMTP_GetEOL(ptr, end, &eol, &eolm);            /* this means we got a real end of line and not just end of payload              * and that the dot is only char on line */            if ((eolm != end) && (eolm == (ptr + 1)))            {                /* if we're normalizing and not ignoring data copy data end marker                 * and dot to alt buffer */                if (!_smtp_config.ignore_data && _smtp_normalizing)                {                    ret = SMTP_CopyToAltBuffer(p, ptr, eol - ptr);                    if (ret == -1)                        return NULL;                }                SMTP_ResetState();                return eol;            }        }        if (_smtp->data_state == STATE_DATA_INIT)            _smtp->data_state = STATE_DATA_HEADER;

⌨️ 快捷键说明

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