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

📄 hi_norm.c

📁 snort-2.1.0入侵检测
💻 C
📖 第 1 页 / 共 3 页
字号:
                            if((u_char)iDir == '/')                            {                                /*                                **  We found a real live directory traversal                                **  so we reset the pointer to before the                                **  '/' and finish up after the return.                                */                                if(hi_eo_generate_event(Session,                                                 ServerConf->directory.alert))                                {                                    hi_eo_client_event_log(Session,                                                         HI_EO_CLIENT_DIR_TRAV,                                                         NULL, NULL);                                }                                *ptr = dir_ptr;                                return DIR_TRAV;                            }                        }                        *ptr = orig_ptr;                        return iChar;                    }                    else if((u_char)iDir == '/')                    {                        /*                        **  We got a self-referential directory traversal.                        **                        **  Keep processing until we stop seeing self                        **  referential directories.                        */                        if(hi_eo_generate_event(Session,                                                ServerConf->directory.alert))                        {                            hi_eo_client_event_log(Session,                                                   HI_EO_CLIENT_SELF_DIR_TRAV,                                                   NULL, NULL);                        }                        continue;                    }                }                  /*                **  This means that we saw '.' and then another char, so                **  it was just a file/dir that started with a '.'.                */                *ptr = orig_ptr;                return iChar;            }        }        /*        **  This is where we write the chars after the slash        */        return iChar;    }    return END_OF_BUFFER;}/***  NAME**    CheckLongDir::*//****  This function checks for long directory names in the request URI.**  **  @param Session    pointer to the session**  @param norm_state pointer to the directory stack**  @param ub_ptr     current pointer in normalization buffer**  **  @return integer**  **  @retval HI_SUCCESS*/static int CheckLongDir(HI_SESSION *Session, URI_NORM_STATE *norm_state,                         u_char *ub_ptr){    int    iDirLen;    u_char *LastDir;    /*    **  First check that we are alerting on long directories and then    **  check that we've seen a previous directory.    */    if(Session->server_conf->long_dir && norm_state->dir_count &&       !norm_state->param)    {        LastDir = norm_state->dir_track[norm_state->dir_count - 1];        iDirLen = ub_ptr - LastDir;        if(iDirLen > Session->server_conf->long_dir)            hi_eo_client_event_log(Session, HI_EO_CLIENT_OVERSIZE_DIR,                                   NULL, NULL);    }    return HI_SUCCESS;}/***  NAME**    InspectUriChar::*//****  This function inspects the normalized chars for any other processing**  that we need to do, such as directory traversals.**  **  The main things that we check for here are '/' and '?'.  There reason**  for '/' is that we do directory traversals.  If it's a slash, we call**  the routine that will normalize mutli-slashes, self-referential dirs,**  and dir traversals.  We do all that processing here and call the**  appropriate functions.**  **  The '?' is so we can mark the parameter field, and check for oversize**  directories one last time.  Once the parameter field is set, we don't**  do any more oversize directory checks since we aren't in the url**  any more.**  **  @param Session      pointer to the current session**  @param iChar        the char to inspect**  @param norm_state   the normalization state**  @param start        the start of the URI buffer**  @param end          the end of the URI buffer**  @param ptr          the address of the pointer index into the URI buffer**  @param ub_start     the start of the norm buffer**  @param ub_end       the end of the norm buffer**  @param ub_ptr       the address of the pointer index into the norm buffer**  **  @return integer**  **  @retval END_OF_BUFFER    we've reached the end of the URI or norm buffer**  @retval HI_NONFATAL_ERR  no special char, so just write the char and**                           increment the ub_ptr.**  @retval HI_SUCCESS       normalized the special char and already**                           incremented the buffers.*/static INLINE int InspectUriChar(HI_SESSION *Session, int iChar,                                 URI_NORM_STATE *norm_state,                                 u_char *start, u_char *end, u_char **ptr,                                 u_char *ub_start, u_char *ub_end,                                 u_char **ub_ptr){    HTTPINSPECT_CONF *ServerConf = Session->server_conf;    int iDir;    /*    **  Let's add absolute URI/proxy support everyone.    */    if(!norm_state->dir_count && (u_char)iChar == ':' &&       hi_util_in_bounds(start, end, ((*ptr)+2)))    {        if(**ptr == '/' && *((*ptr)+1) == '/')        {            /*            **  We've found absolute vodka.            */            if(!hi_util_in_bounds(ub_start, ub_end, ((*ub_ptr)+2)))                return END_OF_BUFFER;            /*            **  Write the :            */            **ub_ptr = (u_char)iChar;            (*ub_ptr)++;            /*            **  This increments us past the first slash, so at the next            **  slash we will track a directory.            **            **  The reason we do this is so that an attacker can't trick            **  us into normalizing a directory away that ended in a :.            **  For instance, if we got a URL that was separated in by a            **  packet boundary like this, and we were looking for the            **  URL real_dir:/file.html:            **    real_dir://obfuscate_dir/../file.html            **  we would normalize it with proxy support to:            **    /file.html            **  because we never tracked the :// as a valid directory.  So            **  even though this isn't the best solution, it is the best            **  we can do given that we are working with stateless            **  inspection.            */            (*ptr)++;            return HI_SUCCESS;        }    }    /*    **  Now that we have the "true" byte, we check this byte for other    **  types of normalization:    **    -  directory traversals    **    -  multiple slashes    */    if((u_char)iChar == '/')    {        /*        **  First thing we do is check for a long directory.        */        CheckLongDir(Session, norm_state, *ub_ptr);        iDir = DirNorm(Session, start, end, ptr, norm_state);        if(iDir == DIR_TRAV)        {            /*            **  This is the case where we have a directory traversal.            **            **  The DirTrav function will reset the ub_ptr to the previous            **  slash.  After that, we just continue through the loop because            **  DirNorm has already set ptr to the slash, so we can just            **  continue on.            */            DirTrav(norm_state, ub_start, ub_ptr);        }        else        {            /*            **  This is the case where we didn't have a directory traversal,            **  and we are now just writing the char after the '/'.            **            **  We call DirSet, because all this function does is write a            **  '/' into the buffer and increment the ub_ptr.  We then            **  check the return code and return END_OF_BUFFER if            **  needed.            */            DirSet(norm_state, ub_ptr);            if(iDir == END_OF_BUFFER)                return END_OF_BUFFER;            /*            **  We check the bounds before we write the next byte            */            if(!hi_util_in_bounds(ub_start, ub_end, *ub_ptr))                return END_OF_BUFFER;                        /*            **  Set the char to what we got in DirNorm()            */            /*            **  Look for user-defined Non-Rfc chars.  If we find them            **  then log an alert.            */            if(ServerConf->non_rfc_chars[(u_char)iDir])            {                hi_eo_client_event_log(Session, HI_EO_CLIENT_NON_RFC_CHAR,                                       NULL, NULL);            }            **ub_ptr = (u_char)iDir;            (*ub_ptr)++;        }        return HI_SUCCESS;    }    if((u_char)iChar == '?')    {        /*        **  We assume that this is the beginning of the parameter field,         **  and check for a long directory following.  Event though seeing        **  a question mark does not guarantee the parameter field, thanks        **  IIS.        */        CheckLongDir(Session, norm_state, *ub_ptr);        norm_state->param = *ub_ptr;    }    /*    **  This is neither char, so we just bail and let the loop finish    **  for us.    */    return HI_NONFATAL_ERR;}/***  NAME**    hi_norm_uri::*//****  Normalize the URI into the URI normalize buffer.**  **  This is the routine that users call to normalize the URI.  It iterates**  through the URI buffer decoding the next character and is then checked**  for any directory problems before writing the decoded character into the**  normalizing buffer.**  **  We return the length of the normalized URI buffer in the variable,**  uribuf_size.  This value is passed in as the max size of the normalization**  buffer, which we then set in iMaxUriBufSize for later reference.**  **  If there was some sort of problem during normalizing we set the normalized**  URI buffer size to 0 and return HI_NONFATAL_ERR.**  **  @param ServerConf   the pointer to the server configuration**  @param uribuf       the pointer to the normalize uri buffer**  @param uribuf_size  the size of the normalize buffer**  @param uri          the pointer to the unnormalized uri buffer**  @param uri_size     the size of the unnormalized uri buffer**  **  @return integer**  **  @retval HI_NONFATAL_ERR there was a problem during normalizing, the**                          uribuf_size is also set to 0**  @retval HI_SUCCESS      Normalizing the URI was successful*/int hi_norm_uri(HI_SESSION *Session, u_char *uribuf, int *uribuf_size,                u_char *uri, int uri_size){    HTTPINSPECT_CONF *ServerConf;    int iChar;    int iRet;    int iMaxUriBufSize;    URI_NORM_STATE norm_state;    u_char *ub_ptr;    u_char *ptr;    u_char *start;    u_char *end;    u_char *ub_start;    u_char *ub_end;    ServerConf = Session->server_conf;    iMaxUriBufSize = *uribuf_size;    start = uri;    end   = uri + uri_size;    ub_start = uribuf;    ub_end   = uribuf + iMaxUriBufSize;    ub_ptr = uribuf;    ptr    = uri;    /*    **  Initialize the URI directory normalization state    */    norm_state.dir_count = 0;    norm_state.param     = NULL;    while(hi_util_in_bounds(ub_start, ub_end, ub_ptr))    {        iChar = GetDecodedByte(Session, start, end, &ptr, &norm_state);        if(iChar == END_OF_BUFFER)            break;        /*        **  Look for user-defined Non-Rfc chars.  If we find them        **  then log an alert.        */        if(ServerConf->non_rfc_chars[(u_char)iChar])        {            hi_eo_client_event_log(Session, HI_EO_CLIENT_NON_RFC_CHAR,                                   NULL, NULL);        }        if((iRet=InspectUriChar(Session, iChar, &norm_state, start, end, &ptr,                           ub_start, ub_end, &ub_ptr)))        {            if(iRet == END_OF_BUFFER)                break;            /*            **  This is the default case when we don't want anything to do with            **  the char besides writing the value into the buffer.            */            *ub_ptr = (u_char)iChar;            ub_ptr++;        }    }    /*    **  Now that we are done, let's make sure that we didn't just have a    **  single large directory, with the rest in the next packet.    */    CheckLongDir(Session, &norm_state, ub_ptr);    /*    **  This means that we got to the end of the URI, so we set the length,    **  check it, and move on.    */    *uribuf_size = ub_ptr - ub_start;    if(*uribuf_size > uri_size || *uribuf_size < 1)        return HI_NONFATAL_ERR;    return HI_SUCCESS;}/***  NAME**    hi_norm_init::*//****  Initialize the arrays neccessary to normalize the HTTP protocol fields.**  **  Currently, we set a hex_lookup array where we can convert the hex encoding**  that we encounter in the URI into numbers we deal with.**  **  @param GlobalConf  pointer to the global configuration of HttpInspect**  **  @return HI_SUCCESS  function successful*/int hi_norm_init(HTTPINSPECT_GLOBAL_CONF *GlobalConf){    int iCtr;    int iNum;    memset(hex_lookup, NO_HEX_VAL, sizeof(hex_lookup));    memset(valid_lookup, NO_HEX_VAL, sizeof(valid_lookup));    /*    **  Set the decimal number values    */    iNum = 0;    for(iCtr = 48; iCtr < 58; iCtr++)    {        hex_lookup[iCtr] = iNum;        valid_lookup[iCtr] = HEX_VAL;        iNum++;    }    /*    **  Set the upper case values.    */    iNum = 10;    for(iCtr = 65; iCtr < 71; iCtr++)    {        hex_lookup[iCtr] = iNum;        valid_lookup[iCtr] = HEX_VAL;        iNum++;    }    iNum = 16;    for(iCtr = 71; iCtr < 91; iCtr++)    {        hex_lookup[iCtr] = iNum;        valid_lookup[iCtr] = BASE36_VAL;        iNum++;    }    /*    **  Set the lower case values.    */    iNum = 10;    for(iCtr = 97; iCtr < 103; iCtr++)    {        hex_lookup[iCtr] = iNum;        valid_lookup[iCtr] = HEX_VAL;        iNum++;    }    iNum = 16;    for(iCtr = 103; iCtr < 123; iCtr++)    {        hex_lookup[iCtr] = iNum;        valid_lookup[iCtr] = BASE36_VAL;        iNum++;    }    return HI_SUCCESS;}/***  NAME**    hi_normalization::*//****  Wrap the logic for normalizing different inspection modes.**  **  We call the various normalization modes here, and adjust the appropriate**  Session constructs.**  **  @param Session      pointer to the session structure.**  @param iInspectMode the type of inspection/normalization to do**  **  @return integer**  **  @retval HI_SUCCESS      function successful**  @retval HI_INVALID_ARG  invalid argument*/int hi_normalization(HI_SESSION *Session, int iInspectMode){    int iRet;    if(!Session)    {        return HI_INVALID_ARG;    }    /*    **  Depending on the mode, we normalize the packet differently.    **  Currently, we only have normalization routines for the client    **  URI, so that's all we are interested in.    **    **  HI_SI_CLIENT_MODE:    **    Inspect for HTTP client communication.    */    if(iInspectMode == HI_SI_CLIENT_MODE)    {        if((iRet = hi_client_norm((void *)Session)))        {            return iRet;        }    }    return HI_SUCCESS;}

⌨️ 快捷键说明

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