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

📄 pp_ftp.c

📁 Snort为国际上著名的轻量型入侵防御系统,为国内多家著名“自主知识产权”网络安全公司所使用。
💻 C
📖 第 1 页 / 共 4 页
字号:
            iRet = validate_date_format(ThisFmt->format.date_fmt, &tmp_ch);            if (iRet != FTPP_SUCCESS)            {                /* Alert invalid date */                return FTPP_INVALID_PARAM;            }            if (!isspace(*tmp_ch))            {                /* Alert invalid date -- didn't make it to end of parameter.                Overflow attempt? */                return FTPP_INVALID_PARAM;            }            this_param = tmp_ch;        }        break;    case e_host_port:        /* check that this_param is #,#,#,#,#,# */        {            u_int32_t ip;            u_int16_t port=0;            int iRet;            iRet = getIP(&this_param, end, ' ', &ip, &port);            switch (iRet)            {            case FTPP_NON_DIGIT:                /* Alert on non-digit */                return FTPP_INVALID_PARAM;                break;            case FTPP_INVALID_ARG:                /* Alert on number > 255 */                return FTPP_INVALID_PARAM;                break;            case FTPP_MALFORMED_IP_PORT:                /* Alert on malformed host-port */                return FTPP_INVALID_PARAM;                break;            }            if ((Session->client_conf->bounce.on) &&                (Session->client_conf->bounce.alert))            {                if (ip != ntohl(p->ip4_header->source.s_addr))                {                    int alert = 1;                    char *ipPtr = (char *)&ip;                    FTP_BOUNCE_TO *BounceTo = ftp_bounce_lookup_find(                        Session->client_conf->bounce_lookup, ipPtr, 4, &iRet);                    if (BounceTo)                    {                        if (BounceTo->portlo)                        {                            if (BounceTo->porthi)                            {                                if ((port >= BounceTo->portlo) &&                                    (port <= BounceTo->porthi))                                    alert = 0;                            }                            else                            {                                if (port == BounceTo->portlo)                                    alert = 0;                            }                        }                    }                                        /* Alert on invalid IP address for PORT */                    if (alert)                    {                        ftp_eo_event_log(Session, FTP_EO_BOUNCE, NULL, NULL);                        /* Return here -- because we will likely want to                         * inspect the data traffic over a bounced data                         * connection */                        return FTPP_PORT_ATTACK;                    }                }            }            Session->clientIP = htonl(ip);            Session->clientPort = port;            Session->data_chan_state |= DATA_CHAN_PORT_CMD_ISSUED;            if (Session->data_chan_state & DATA_CHAN_PASV_CMD_ISSUED)            {                /*                 * If there was a PORT command previously in                 * a series of pipelined requests, this                 * cancels it.                 */                Session->data_chan_state &= ~DATA_CHAN_PASV_CMD_ISSUED;            }            Session->serverIP = 0;            Session->serverPort = 0;        }        break;    }    ThisFmt->next_param = this_param;    return FTPP_SUCCESS;}/* * Function: check_ftp_param_validity( *                            Packet *p, *                            char *params_begin, *                            char *params_end, *                            FTP_PARAM_FMT *param_format, *                            FTP_SESSION *Session) * * Purpose: Recursively determines whether each of the parameters for *          an FTP command are valid. * * Arguments: p              => Pointer to the current packet *            params_begin   => Pointer to beginning of parameters *            params_end     => End of params buffer *            param_format   => Parameter format specifier for this command *            Session        => Pointer to the session info * * Returns: int => return code indicating error or success * */int check_ftp_param_validity(SFSnortPacket *p,                             char *params_begin,                             char *params_end,                             FTP_PARAM_FMT *param_format,                             FTP_SESSION *Session){    int iRet = FTPP_ALERT;    FTP_PARAM_FMT *ThisFmt = param_format;    FTP_PARAM_FMT *NextFmt;    char *this_param = params_begin;    if (!param_format)        return FTPP_INVALID_ARG;    if (!params_begin)        return FTPP_INVALID_ARG;    if ((!ThisFmt->next_param_fmt) && (params_begin >= params_end))        return FTPP_SUCCESS;    ThisFmt->next_param = params_begin;    if (ThisFmt->optional_fmt)    {        /* Check against optional */        iRet = validate_param(p, this_param, params_end,                              ThisFmt->optional_fmt, Session);        if (iRet == FTPP_SUCCESS)        {            char *next_param;            NextFmt = ThisFmt->optional_fmt;            next_param = NextFmt->next_param+1;            iRet = check_ftp_param_validity(p, next_param, params_end,                                            NextFmt, Session);            if (iRet == FTPP_SUCCESS)            {                this_param = NextFmt->next_param+1;            }        }    }    if ((iRet != FTPP_SUCCESS) && (ThisFmt->choices))    {        /* Check against choices -- one of many */        int i;        int valid = 0;        for (i=0;i<ThisFmt->numChoices && !valid;i++)        {            /* Try choice [i] */            iRet = validate_param(p, this_param, params_end,                              ThisFmt->choices[i], Session);            if (iRet == FTPP_SUCCESS)            {                char *next_param;                NextFmt = ThisFmt->choices[i];                next_param = NextFmt->next_param+1;                iRet = check_ftp_param_validity(p, next_param, params_end,                                                NextFmt, Session);                if (iRet == FTPP_SUCCESS)                {                    this_param = NextFmt->next_param+1;                    valid = 1;                    break;                }            }        }    }    else if ((iRet != FTPP_SUCCESS) && (ThisFmt->next_param_fmt))    {        /* Check against next param */        iRet = validate_param(p, this_param, params_end,                          ThisFmt->next_param_fmt, Session);        if (iRet == FTPP_SUCCESS)        {            char *next_param;            NextFmt = ThisFmt->next_param_fmt;            next_param = NextFmt->next_param+1;            iRet = check_ftp_param_validity(p, next_param, params_end,                                            NextFmt, Session);            if (iRet == FTPP_SUCCESS)            {                this_param = NextFmt->next_param+1;            }        }    }    if (iRet == FTPP_SUCCESS)    {        ThisFmt->next_param = this_param;    }    return iRet;}/* * Function: initialize_ftp(FTP_SESSION *Session, Packet *p, int iMode) * * Purpose: Initializes the state machine for checking an FTP packet. *          Does normalization checks. *  * Arguments: Session        => Pointer to session info *            p              => pointer to the current packet struct *            iMode          => Mode indicating server or client checks * * Returns: int => return code indicating error or success * */int initialize_ftp(FTP_SESSION *Session, SFSnortPacket *p, int iMode){    int iRet;    unsigned char *read_ptr = p->payload;    FTP_CLIENT_REQ *req;    /* Normalize this packet ala telnet */    iRet = normalize_telnet(Session->global_conf, NULL, p, iMode);    if (iRet != FTPP_SUCCESS && iRet != FTPP_NORMALIZED)    {        if (iRet == FTPP_ALERT)        {            if (Session->global_conf->global_telnet.detect_anomalies)            {                ftp_eo_event_log(Session, FTP_EO_EVASIVE_TELNET_CMD, NULL, NULL);        }   }        return iRet;    }        if (p->flags & FLAG_ALT_DECODE)    {        /* Normalized data will always be in decode buffer */        if ( ((Session->client_conf->telnet_cmds.alert) &&              (iMode == FTPP_SI_CLIENT_MODE)) ||             ((Session->server_conf->telnet_cmds.alert) &&              (iMode == FTPP_SI_SERVER_MODE)) )        {            /* alert -- FTP channel with telnet commands */            ftp_eo_event_log(Session, FTP_EO_TELNET_CMD, NULL, NULL);            return FTPP_ALERT; /* Nothing else to do since we alerted */        }        read_ptr = _dpd.altBuffer;    }    if (iMode == FTPP_SI_CLIENT_MODE)        req = &Session->client.request;    else if (iMode == FTPP_SI_SERVER_MODE)        req = (FTP_CLIENT_REQ *)&Session->server.response;    else        return FTPP_INVALID_ARG;    /* Set the beginning of the pipeline to the start of the     * (normalized) buffer */    req->pipeline_req = read_ptr;    return FTPP_SUCCESS;}#ifdef MAINTAIN_DIR_STATE/* * Function: adjust_dir(FTP_SESSION *Session, int cmd, *                      char *result, int resultLen) * * Purpose: Updates the state information that tracks the FTP *          directory. *  * Arguments: Session        => Pointer to session info *            cmd            => CDUP, CWD, or PWD *            result         => Pointer to response for PWD *            resultLen      => Length of above * * Returns: void => None * */void adjust_dir(FTP_SESSION *Session, int cmd, char *result, int resultLen){    char *dirPtr;    int iLen;    switch (cmd)    {    case CDUP_CMD_ISSUED:        if (Session->curr_directory)        {            FTP_DIR_NODE *old = Session->curr_directory;            Session->curr_directory = Session->curr_directory->parent;            FTPFreeDirectory(old);            if (Session->curr_directory)                Session->curr_directory->next = NULL;            else                Session->head_directory = NULL;        }        else        {            /* CD beyond root... problem */            /* TODO: set an alert here... ? */            Session->dir_state = LOST_STATE;        }        break;    case CWD_CMD_ISSUED:        if (Session->dir_adjust[0] == '/')        {            FTPFreeDirectory(Session->head_directory);            Session->head_directory = Session->curr_directory = NULL;        }        else if (Session->dir_adjust[0] == '~')        {            /* Can't really guess at the home dir for user x... */            Session->dir_state = LOST_STATE;        }        dirPtr = strtok(Session->dir_adjust, "/");        while (dirPtr)        {            FTP_DIR_NODE *thisNode;            /* Trying to include . as a directory.             * Nothing to do... */            if (!strcmp(dirPtr, "."))            {                dirPtr = strtok(NULL, "/");                continue;            }            /* Trying to include .. as a directory.             * Go up one */            if (!strcmp(dirPtr, ".."))            {                if (Session->curr_directory)                {                    FTP_DIR_NODE *old = Session->curr_directory;                    Session->curr_directory = Session->curr_directory->parent;                    FTPFreeDirectory(old);                    if (Session->curr_directory)                        Session->curr_directory->next = NULL;                    else                        Session->head_directory = NULL;                }                else                {                    /* CD beyond root... problem */                    /* TODO: set an alert here... ? */                    Session->dir_state = LOST_STATE;                }                dirPtr = strtok(NULL, "/");                continue;            }            iLen = strlen(dirPtr);            thisNode = malloc(sizeof(FTP_DIR_NODE));            thisNode->name = calloc(sizeof(char), iLen + 1);            memcpy(thisNode->name, dirPtr, iLen);            if (!Session->curr_directory)            {                Session->curr_directory = thisNode;                Session->head_directory = thisNode;                thisNode->parent = NULL;                thisNode->next = NULL;            }            else            {                thisNode->parent = Session->curr_directory;                thisNode->next = NULL;                Session->curr_directory->next = thisNode;                Session->curr_directory = thisNode;            }            dirPtr = strtok(NULL, "/");        }        break;    case PWD_CMD_ISSUED:        /* This is a special case -- we can check state and/or         * reset, as necessary.  Start at head, check.  If         * we find a mismatch, update current dir.  :)         */        {            char normalizedDir[1024];            int i = 0 ,j = 0;            int quotes_seen = 0;            FTP_DIR_NODE *thisNode = Session->head_directory;            int reset = 0;            memset(&normalizedDir[0], 0, 1024);            /* First normalize the directory name from the response             * to eliminate the escaped " -- noted by a "".  The             * directory name is encapsulated in quotes.             */                      for (i=0;i<resultLen && quotes_seen < 2 && j < 1024; )            {                if (result[i] == '\"')                {                    if ((i < resultLen -1) && (result[i+1] == '\"'))                    {                        normalizedDir[j++] = result[i++];                        i++; /* Skip the 2nd " */                    }                    else                    {                        quotes_seen++;                        i++;                    }                }                else                {                    normalizedDir[j++] = result[i++];                }            }            /* Now search for each dir component in turn */            dirPtr = strtok(normalizedDir, "/");            while (dirPtr && !reset)            {                if (!thisNode)                {                    reset = 1;                    break;                }                if (strcmp(thisNode->name, dirPtr))                {                    /* Uh, lost state, kill everything below here */                    FTPFreeDirectory(thisNode->next);                    free(thisNode->name);                    iLen = strlen(dirPtr);                    thisNode->name = calloc(sizeof(char), iLen + 1);                    memcpy(thisNode->name, dirPtr, iLen);                    reset = 1;                }                thisNode = thisNode->next;

⌨️ 快捷键说明

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