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

📄 pp_ftp.c

📁 Snort为国际上著名的轻量型入侵防御系统,为国内多家著名“自主知识产权”网络安全公司所使用。
💻 C
📖 第 1 页 / 共 4 页
字号:
                    }                    if (!ftpssn->global_conf->check_encrypted_data)                    {                        /* Mark this session & packet as one to ignore */                        _dpd.streamAPI->stop_inspection(p->stream_session_ptr, p,                                                SSN_DIR_BOTH, -1, 0);                    }                    DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                        "FTP client stream is now encrypted\n"););                }                break;            }            else            {                /*                  * Check the list of valid FTP commands as                 * supplied in ftpssn.                 */                if (req->cmd_size > 4)                {                    /* Alert, cmd not found */                    ftp_eo_event_log(ftpssn, FTP_EO_INVALID_CMD, NULL, NULL);                    state = FTP_CMD_INV;                }                else                {                    CmdConf = ftp_cmd_lookup_find(ftpssn->server_conf->cmd_lookup,                                              req->cmd_begin,                                              req->cmd_size,                                              &iRet);                    if ((iRet == FTPP_NOT_FOUND) || (CmdConf == NULL))                    {                        /* Alert, cmd not found */                        ftp_eo_event_log(ftpssn, FTP_EO_INVALID_CMD, NULL, NULL);                        state = FTP_CMD_INV;                    }                    else                    {                        /* In case we were encrypted, but aren't now */                        ftpssn->encr_state = 0;                    }                }            }        }        else if (iMode == FTPP_SI_SERVER_MODE)        {            if ( (req->cmd_size != 3) || (state == FTP_RESPONSE_INV) )            {                /* Uh, something is very wrong...                 * nondigit char seen or resp code is not 3 chars.                 * See if this might be encrypted, ie, non-alpha bytes. */                char *ptr = req->cmd_begin;                while (ptr < req->cmd_end)                {                    if (!isdigit(*ptr))                    {                        encrypted = 1;                        break;                    }                    ptr++;                }            }            if (encrypted)            {                /* If the session wasn't already marked as encrypted...                 * Don't want to double-alert if we've already                 * determined the session is encrypted and we're                 * checking encrypted sessions.                 */                if (ftpssn->encr_state == 0)                {                    ftpssn->encr_state = AUTH_UNKNOWN_ENCRYPTED;                    if (ftpssn->global_conf->encrypted.alert)                    {                        /* Alert on encrypted channel */                        ftp_eo_event_log(ftpssn, FTP_EO_ENCRYPTED,                            NULL, NULL);                    }                    if (!ftpssn->global_conf->check_encrypted_data)                    {                        /* Mark this session & packet as one to ignore */                        _dpd.streamAPI->stop_inspection(p->stream_session_ptr, p,                                                SSN_DIR_BOTH, -1, 0);                    }                    DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                        "FTP server stream is now encrypted\n"););                }                break;            }            else            {                /* In case we were encrypted, but aren't now */                ftpssn->encr_state = 0;            }            if (*read_ptr != DASH)            {                unsigned char *resp_begin = req->cmd_begin;                unsigned char *resp_end = req->cmd_end;                if (resp_end - resp_begin >= 3)                {                    if (isdigit(*(resp_begin)) &&                        isdigit(*(resp_begin+1)) &&                        isdigit(*(resp_begin+2)) )                    {                        rsp_code = ( (*(resp_begin) - '0') * 100 +                                      (*(resp_begin+1) - '0') * 10 +                                      (*(resp_begin+2) - '0') );                        if (rsp_code == ftpssn->server.response.state)                        {                            /* End of continued response */                            state = FTP_RESPONSE_ENDCONT;                            ftpssn->server.response.state = 0;                        }                        else                        {                            /* Single line response */                            state = FTP_RESPONSE;                        }                    }                }                if (ftpssn->server.response.state != 0)                {                    req->cmd_begin = NULL;                    req->cmd_end = NULL;                    if (*read_ptr != SP)                        read_ptr--;                    state = FTP_RESPONSE_CONT;                }            }            else if ((state == FTP_RESPONSE) && (*read_ptr == DASH))            {                unsigned char *resp_begin = req->cmd_begin;                if (isdigit(*(resp_begin)) &&                    isdigit(*(resp_begin+1)) &&                    isdigit(*(resp_begin+2)) )                {                    int resp_code = ( (*(resp_begin) - '0') * 100 +                                       (*(resp_begin+1) - '0') * 10 +                                       (*(resp_begin+2) - '0') );                    if (resp_code == ftpssn->server.response.state)                    {                        /* Continuation of previous response */                        state = FTP_RESPONSE_CONT;                    }                    else                    {                        /* Start of response, state stays as -2 */                        state = FTP_RESPONSE_2BCONT;                        ftpssn->server.response.state = resp_code;                        rsp_code = resp_code;                    }                }                else                {                    DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                        "invalid FTP response code."););                    ftpssn->server.response.state = FTP_RESPONSE_INV;                }            }        }        if (*read_ptr == SP)        {            space = 1;        }        read_ptr++; /* Move past the space, dash, or CR */        /* If there is anything left... */                if (read_ptr < end)        {            /* Look for an LF --> implies no parameters/message */            if (*read_ptr == LF)            {                read_ptr++;                req->param_begin = NULL;                req->param_end = NULL;            }            else if (!space && ftpssn->server.response.state == 0)            {                DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                    "Missing LF from end of FTP command\n"););            }            else            {                    /* Now grab the command parameters/response message */                if (read_ptr < end)                {                    req->param_begin = read_ptr;                    while ((*read_ptr != CR) && (read_ptr < end))                    {                        read_ptr++;                    }                    req->param_end = read_ptr;                    read_ptr++;                }                if (read_ptr < end)                {                    /* Cool, got the end of the parameters, move past                     * the LF, so we can process the next one in                     * the pipeline.                     */                    if (*read_ptr == LF)                    {                       read_ptr++;                    }                    else                    {                        DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                            "Missing LF from end of FTP command with params\n"););                    }                }            }        }        else        {            /* Nothing left --> no parameters/message.  Not even an LF */            req->param_begin = NULL;            req->param_end = NULL;            DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                "Missing LF from end of FTP command sans params\n"););        }            /* Set the pointer for the next request/response         * in the pipeline. */        if (read_ptr < end)            req->pipeline_req = read_ptr;        else            req->pipeline_req = NULL;        req->param_size = req->param_end - req->param_begin;        switch (state)        {        case FTP_CMD_INV:            DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                "Illegal FTP command found: %.*s\n",                req->cmd_size, req->cmd_begin));            iRet = FTPP_ALERT;            break;        case FTP_RESPONSE: /* Response */            DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                "FTP response: code: %.*s : M len %d : M %.*s\n",                req->cmd_size, req->cmd_begin, req->param_size,                req->param_size, req->param_begin));            if ((ftpssn->client_conf->max_resp_len > 0) &&                 (req->param_size > ftpssn->client_conf->max_resp_len))            {                /* Alert on response message overflow */                ftp_eo_event_log(ftpssn, FTP_EO_RESPONSE_LENGTH_OVERFLOW,                    NULL, NULL);                iRet = FTPP_ALERT;            }            if (ftpssn->global_conf->inspection_type ==                FTPP_UI_CONFIG_STATEFUL)            {                int newRet = do_stateful_checks(ftpssn, p, req, rsp_code);                if (newRet != FTPP_SUCCESS)                    iRet = newRet;            }            break;        case FTP_RESPONSE_CONT: /* Response continued */            DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                "FTP response: continuation of code: %d : M len %d : M %.*s\n",                ftpssn->server.response.state, req->param_size,                req->param_size, req->param_begin));            if ((ftpssn->client_conf->max_resp_len > 0) &&                 (req->param_size > ftpssn->client_conf->max_resp_len))            {                /* Alert on response message overflow */                ftp_eo_event_log(ftpssn, FTP_EO_RESPONSE_LENGTH_OVERFLOW,                    NULL, NULL);                iRet = FTPP_ALERT;            }            break;        case FTP_RESPONSE_ENDCONT: /* Continued response end */            DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET,                "FTP response: final continue of code: %.*s : M len %d : "                "M %.*s\n", req->cmd_size, req->cmd_begin,                req->param_size, req->param_size, req->param_begin));            if ((ftpssn->client_conf->max_resp_len > 0) &&                 (req->param_size > ftpssn->client_conf->max_resp_len))            {                /* Alert on response message overflow */                ftp_eo_event_log(ftpssn, FTP_EO_RESPONSE_LENGTH_OVERFLOW,                    NULL, NULL);                iRet = FTPP_ALERT;            }            break;        default:            DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET, "FTP command: CMD: %.*s : "                "P len %d : P %.*s\n", req->cmd_size, req->cmd_begin,                req->param_size, req->param_size, req->param_begin));            if (CmdConf)            {                if ((CmdConf->max_param_len >= 0) &&                    (req->param_size > CmdConf->max_param_len))                {                    /* Alert on param length overrun */                    ftp_eo_event_log(ftpssn, FTP_EO_PARAMETER_LENGTH_OVERFLOW,                        NULL, NULL);                    DEBUG_WRAP(_dpd.debugMsg(DEBUG_FTPTELNET, "FTP command: %.*s"                        "parameter length overrun %d > %d \n",                        req->cmd_size, req->cmd_begin, req->param_size,                        CmdConf->max_param_len));                    iRet = FTPP_ALERT;                    break;                }                if (CmdConf->data_chan_cmd)                {                    ftpssn->data_chan_state |= DATA_CHAN_PASV_CMD_ISSUED;                    ftpssn->data_chan_index = ftp_cmd_pipe_index;                    if (ftpssn->data_chan_state & DATA_CHAN_PORT_CMD_ISSUED)                    {                        /*                         * If there was a PORT command previously in                         * a series of pipelined requests, this                         * cancels it.                         */                        ftpssn->data_chan_state &= ~DATA_CHAN_PORT_CMD_ISSUED;                    }                }                else if (CmdConf->data_xfer_cmd)                {                    ftpssn->data_chan_state |= DATA_CHAN_XFER_CMD_ISSUED;                    ftpssn->data_xfer_index = ftp_cmd_pipe_index;                }                else if (CmdConf->encr_cmd)                {                    if ((req->param_begin[0] == 'T') ||                        (req->param_begin[0] == 't'))                        ftpssn->encr_state = AUTH_TLS_CMD_ISSUED;                    else if ((req->param_begin[0] == 'S') ||                        (req->param_begin[0] == 's'))                        ftpssn->encr_state = AUTH_SSL_CMD_ISSUED;                    else                        ftpssn->encr_state = AUTH_UNKNOWN_CMD_ISSUED;                }#ifdef MAINTAIN_USER_STATE                if (CmdConf->login_cmd)                {                    if (ftpssn->user_state == NO_STATE)                    {                        ftpssn->user_state = USER_CMD_ISSUED;                        /* Save username -- malloc/memcpy */                        ftpssn->user = calloc(sizeof(char),                                               req->param_size+1);                        memcpy(ftpssn->user, req->param_begin,                            req->param_size);                    }                    else if (ftpssn->user_state == PASS_REQUIRED)                    {                        ftpssn->user_state = PASS_CMD_ISSUED;                    }                }#endif#ifdef MAINTAIN_DIR_STATE                if (CmdConf->dir_response)                {                    if ((req->cmd_begin[0] == 'P') ||                        (req->cmd_begin[0] == 'p'))                    {                        ftpssn->dir_state = PWD_CMD_ISSUED;                        ftpssn->expected_dir_response = CmdConf->dir_response;                    }                    else if (ftpssn->dir_state != LOST_STATE)                    {                        if ((req->cmd_begin[1] == 'W') ||                            (req->cmd_begin[1] == 'w'))                        {                            ftpssn->dir_state = CWD_CMD_ISSUED;                            ftpssn->expected_dir_response =                                CmdConf->dir_response;                            /* Save directory adjustment -- malloc/memcpy */                            ftpssn->dir_adjust = calloc(sizeof(char),                                                         req->param_size+1);                            memcpy(ftpssn->dir_adjust, req->param_begin,                                   req->param_size);                        }                        else                        {                            ftpssn->dir_state = CDUP_CMD_ISSUED;                            ftpssn->expected_dir_response =                                CmdConf->dir_response;                        }                    }                }#endif                if (CmdConf->check_validity)                {                    iRet = check_ftp_param_validity(p, req->param_begin,                                    req->param_end, CmdConf->param_format,                                    ftpssn);                    /* If negative, haven't already alerted on violation */                    if (iRet < 0)                    {                        /* Set Alert on malformatted parameter */                        ftp_eo_event_log(ftpssn, FTP_EO_MALFORMED_PARAMETER,                            NULL, NULL);                        iRet = FTPP_ALERT;                        break;                    }                    else if (iRet > 0)                    {                        /* Already alerted -- ie, string format attack. */                        break;                    }                }            }            break;        }        if (iMode == FTPP_SI_CLIENT_MODE)            ftp_cmd_pipe_index++;        else if ((rsp_code != 226) && (rsp_code != 426))        {             /*              * In terms of counting responses, ignore              * 226 response saying transfer complete              * 426 response saying transfer aborted              * The 226 may or may not be sent by the server.              * Both are 2nd response to a transfer command.              */            ftp_cmd_pipe_index++;        }    }    if (iMode == FTPP_SI_CLIENT_MODE)    {        ftp_cmd_pipe_index = 0;    }    if (encrypted)        return FTPP_ALERT;    return iRet;}

⌨️ 快捷键说明

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