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

📄 hi_norm.c

📁 snort-2.1.0入侵检测
💻 C
📖 第 1 页 / 共 3 页
字号:
        **  This means that we have an invalid first sequence byte for        **  a unicode sequence.  So we just return the byte and move on.        */        return iFirst;    }    /*    **  This is the main loop for UTF-8 decoding.  We check for the only    **  valid sequence after the first byte whish is 0x80.  Otherwise,    **  it was invalid and we setnd a NON_ASCII_CHAR and continue on    **  with our processing.    */    for(iCtr = 0; iCtr < iNumBytes; iCtr++)    {        iByte = GetChar(Session, start, end, ptr, &iBareByte);        if(iByte == END_OF_BUFFER || iBareByte)            return NON_ASCII_CHAR;        if((iByte & 0xc0) == 0x80)        {            iNorm <<= 6;            iNorm |= (iByte & 0x3f);        }        else        {            /*            **  This means that we don't have a valid unicode sequence, so            **  we just bail.            */            return NON_ASCII_CHAR;        }    }    /*    **  Check for unicode as ASCII and if there is not an ASCII char then    **  we return the space holder char.    */    if(iNorm > 0x7f)    {        if(ServerConf->iis_unicode.on)        {            iNorm = ServerConf->iis_unicode_map[iNorm];            if(iNorm == HI_UI_NON_ASCII_CODEPOINT)            {                iNorm = NON_ASCII_CHAR;            }            if(hi_eo_generate_event(Session, ServerConf->iis_unicode.alert))            {                hi_eo_client_event_log(Session, HI_EO_CLIENT_IIS_UNICODE,                                       NULL, NULL);            }            return iNorm;        }        else        {            iNorm = NON_ASCII_CHAR;        }    }    if(hi_eo_generate_event(Session, ServerConf->utf_8.alert))    {        hi_eo_client_event_log(Session, HI_EO_CLIENT_UTF_8,                               NULL, NULL);    }    return iNorm;}/***  NAME**    UnicodeDecode::*//****  Checks for the ServerConf values before we actually decode.**  **  This function is really a ServerConf wrapper for UTF8Decode.****  @param ServerConf  the server configuration**  @param start       the start of the URI**  @param end         the end of the URI**  @param ptr         the current pointer into the URI**  **  @return integer**  **  @retval char       the decode/undecoded byte.**  **  @see GetByte()*/static int UnicodeDecode(HI_SESSION *Session, u_char *start,                          u_char *end, u_char **ptr, int iFirst){    HTTPINSPECT_CONF *ServerConf = Session->server_conf;    int iNorm = iFirst;    if(ServerConf->iis_unicode.on || ServerConf->utf_8.on)    {        iNorm = UTF8Decode(Session, start, end, ptr, iFirst);    }    return iNorm;}/***  NAME**    GetByte::*//****  Handles the first stage of URI decoding for the case of IIS double**  decoding.**  **  The first stage consists of ASCII decoding and unicode decoding.  %U**  decoding is handled in the ASCII decoding.**  **  @param ServerConf  the server configuration**  @param start       the start of the URI**  @param end         the end of the URI**  @param ptr         the current pointer into the URI**  **  @return integer**  **  @retval END_OF_BUFFER means that we've reached the end of buffer in**                        GetChar.**  @retval iChar         this is the character that was decoded.*/static int GetByte(HI_SESSION *Session, u_char *start, u_char *end,                   u_char **ptr){    int iChar;    int iBareByte;    iChar = GetChar(Session, start, end, ptr, &iBareByte);    if(iChar == END_OF_BUFFER)        return END_OF_BUFFER;    /*    **  We now check for unicode bytes    */    if((iChar & 0x80) && (iChar != NON_ASCII_CHAR) && !iBareByte)    {        iChar = UnicodeDecode(Session, start, end, ptr, iChar);    }    return iChar;}/***  NAME**    DoubleDecode::*//****  The double decoding routine for IIS good times.**  **  Coming into this function means that we just decoded a % or that**  we just saw two percents in a row.  We know which state we are**  in depending if the first char is a '%' or not.****  In the IIS world, there are two decodes, but only some of the decode**  options are valid.  All options are valid in the first decode**  stage, but the second decode stage only supports:**  -  %u encoding**  -  ascii****  Knowing this, we can decode appropriately.**  **  @param ServerConf  the server configuration**  @param start       the start of the URI**  @param end         the end of the URI**  @param ptr         the current pointer into the URI**  @param norm_state  the ptr to the URI norm state**  **  @return integer**  **  @retval NON_ASCII_CHAR  End of buffer reached while decoding**  @retval char            The decoded char*/static int DoubleDecode(HI_SESSION *Session, u_char *start,                        u_char *end, u_char **ptr,                        URI_NORM_STATE *norm_state){    HTTPINSPECT_CONF *ServerConf = Session->server_conf;    int iByte;    int iNorm;    u_char *orig_ptr;    orig_ptr = *ptr;    /*    **  We now know that we have seen a previous % and that we need to    **  decode the remaining bytes.  We are in one of multiple cases:    **    **  -  %25xxxx    **  -  %%xx%xx    **  -  %u0025xxxx    **  -  etc.    **    **  But, the one common factor is that they each started out with a    **  % encoding of some type.    **    **  So now we just get the remaining bytes and do the processing    **  ourselves in this routine.    */    iByte = GetByte(Session, start, end, ptr);    if(iByte == END_OF_BUFFER)        return NON_ASCII_CHAR;    if(valid_lookup[(u_char)iByte] < 0)    {        if(ServerConf->u_encoding.on && (toupper(iByte) == 'U'))        {            iNorm = UDecode(Session, start, end, ptr, GetByte);                        if(iNorm == END_OF_BUFFER)            {                /*                **  We have reached the end of the buffer while                **  processing a U encoding.  We keep the current                **  pointer and return a NON_ASCII char for the                **  bad encoding.                */                return NON_ASCII_CHAR;            }            return iNorm;        }        return iByte;    }    iNorm = (hex_lookup[(u_char)iByte]<<4);    iByte = GetByte(Session, start, end, ptr);    if(iByte == END_OF_BUFFER)        return NON_ASCII_CHAR;    if(valid_lookup[(u_char)iByte] < 0)    {        return iByte;    }    iNorm = (iNorm | (hex_lookup[(u_char)iByte])) & 0xff;    if(hi_eo_generate_event(Session, ServerConf->double_decoding.alert) &&       (norm_state->param == NULL))    {        hi_eo_client_event_log(Session, HI_EO_CLIENT_DOUBLE_DECODE,                               NULL, NULL);    }    return iNorm;}/***  NAME**    GetDecodedByte::*//****  This is the final GetByte routine.  The value that is returned from this**  routine is the final decoded byte, and normalization can begin.  This**  routine handles the double phase of decoding that IIS is fond of.**  **  So to recap all the decoding up until this point.**  **  The first phase is to call GetByte().  GetByte() returns the first stage**  of decoding, which handles the UTF-8 decoding.  If we have decoded a**  % of some type, then we head into DoubleDecode() if the ServerConf**  allows it.**  **  What returns from DoubleDecode is the final result.**  **  @param ServerConf  the server configuration**  @param start       the start of the URI**  @param end         the end of the URI**  @param ptr         the current pointer into the URI**  @param norm_state  the pointer to the URI norm state**  **  @return integer**  **  @retval END_OF_BUFFER  While decoding, the end of buffer was reached.**  @retval char           The resultant decoded char.**  **  @see DoubleDecode();**  @see GetByte();*/static int GetDecodedByte(HI_SESSION *Session, u_char *start,                          u_char *end, u_char **ptr,                           URI_NORM_STATE *norm_state){    HTTPINSPECT_CONF *ServerConf = Session->server_conf;    int iChar;    iChar = GetByte(Session,start,end,ptr);    if(iChar == END_OF_BUFFER)        return END_OF_BUFFER;    if(ServerConf->double_decoding.on && (u_char)iChar == '%')    {        iChar = DoubleDecode(Session,start,end,ptr, norm_state);    }    /*    **  Let's change '\' to '/' if possible    */    if(ServerConf->iis_backslash.on && (u_char)iChar == 0x5c)    {        if(hi_eo_generate_event(Session, ServerConf->iis_backslash.alert))        {            hi_eo_client_event_log(Session, HI_EO_CLIENT_IIS_BACKSLASH,                                    NULL, NULL);        }        iChar = 0x2f;    }    return iChar;}/***  NAME**    DirTrav::*//****  Set the ub_ptr and update the URI_NORM_STATE.**  **  The main point of this function is to take care of the details in**  updating the directory stack and setting the buffer pointer to the**  last directory.**  **  @param norm_state pointer to the normalization state struct**  @param ub_ptr     double pointer to the normalized buffer**  **  @return integer**  **  @retval HI_SUCCESS function successful**  **  @see hi_norm_uri()*/static int DirTrav(URI_NORM_STATE *norm_state,u_char *ub_start,u_char **ub_ptr){    if(norm_state->dir_count)    {        *ub_ptr = norm_state->dir_track[norm_state->dir_count - 1];                /*        **  Check to make sure that we aren't at the beginning        */        if(norm_state->dir_count  > 1)            norm_state->dir_count--;    }    else    {        /*        **  This is a special case where there was no / seen before        **  we see a /../.  When this happens, we just reset the ub_ptr        **  back to the beginning of the norm buffer and let the slash        **  get written on the next iteration of the loop.        */        *ub_ptr = ub_start;    }    return HI_SUCCESS; }/***  NAME**    DirSet::*//****  Set the directory by writing a '/' to the normalization buffer and**  updating the directory stack.**  **  This gets called after every slash that isn't a directory traversal.  We**  just write a '/' and then update the directory stack to point to the**  last directory, in the case of future directory traversals.**  **  @param norm_state pointer to the normalization state struct**  @param ub_ptr     double pointer to the normalized buffer**  **  @return integer**  **  @retval HI_SUCCESS function successful**  **  @see hi_norm_uri()*/static int DirSet(URI_NORM_STATE *norm_state, u_char **ub_ptr){    /*    **  Write the '/'.  Even if iDir is the END_OF_BUFFER we still    **  write it because the '/' came before the END_OF_BUFFER.    */    **ub_ptr = '/';    if(!norm_state->param)    {        norm_state->dir_track[norm_state->dir_count] = *ub_ptr;        if(norm_state->dir_count < MAX_DIRS)            norm_state->dir_count++;    }    (*ub_ptr)++;    return HI_SUCCESS;}/***  NAME**    DirNorm::*//****  The main function for dealing with multiple slashes, self-referential**  directories, and directory traversals.**  **  This routine does GetDecodedByte() while looking for directory foo.  It's**  called every time that we see a slash in the main hi_norm_uri.  Most of**  the time we just enter this loop, find a non-directory-foo char and **  return that char.  hi_norm_uri() takes care of the directory state**  updating and so forth.**  **  But when we run into trouble with directories, this function takes care**  of that.  We loop through multiple slashes until we get to the next**  directory.  We also loop through self-referential directories until we**  get to the next directory.  Then finally we deal with directory **  traversals.**  **  With directory traversals we do a kind of "look ahead".  We verify that**  there is indeed a directory traversal, and then set the ptr back to**  the beginning of the '/', so when we iterate through hi_norm_uri() we**  catch it.**  **  The return value for this function is usually the character after**  the directory.  When there was a directory traversal, it returns the**  value DIR_TRAV.  And when END_OF_BUFFER is returned, it means that we've**  really hit the end of the buffer, or we were looping through multiple**  slashes and self-referential directories until the end of the URI**  buffer.**  **  @param ServerConf   pointer to the Server configuration**  @param start        pointer to the start of the URI buffer**  @param end          pointer to the end of the URI buffer**  @param ptr          pointer to the index in the URI buffer**  **  @return integer**  **  @retval END_OF_BUFFER   we've reached the end of buffer**  @retval DIR_TRAV        we found a directory traversal**  @retval char            return the next char after the directory**  **  @see hi_norm_uri()**  @see GetDecodedByte()*/static int DirNorm(HI_SESSION *Session, u_char *start, u_char *end,                   u_char **ptr, URI_NORM_STATE *norm_state){    HTTPINSPECT_CONF *ServerConf = Session->server_conf;    int iChar;    int iDir;    u_char *orig_ptr;    u_char *dir_ptr;    while((iChar = GetDecodedByte(Session, start, end, ptr, norm_state)) !=          END_OF_BUFFER)    {        orig_ptr = *ptr;        /*        **  This is kind of a short cut to get out of here as soon as we        **  can.  If the character is over 0x2f then we know that is can't        **  be either the '.' or the '/', so we break and return the        **  char.        */        if((u_char)iChar < 0x30)        {            /*            **  We check for multiple slashes.  If we find multiple slashes            **  then we just continue on until we find something interesting.            */            if(ServerConf->multiple_slash.on && (u_char)iChar == '/')            {                if(hi_eo_generate_event(Session,                                        ServerConf->multiple_slash.alert))                {                    hi_eo_client_event_log(Session,                                           HI_EO_CLIENT_MULTI_SLASH,                                           NULL, NULL);                }                continue;            }            /*            **  This is where we start looking for self-referential dirs            **  and directory traversals.            */            else if(ServerConf->directory.on && (u_char)iChar == '.' &&                    !norm_state->param)            {                iDir = GetDecodedByte(Session,start,end,ptr,norm_state);                if(iDir != END_OF_BUFFER)                {                    if((u_char)iDir == '.')                    {                        /*                        **  This sets the dir_ptr to the beginning of the                        **  byte that may be a dir.  So if it is a slash,                        **  we can get back to that slash and continue                        **  processing.                        */                        dir_ptr = *ptr;                        iDir = GetDecodedByte(Session,start,end,ptr,norm_state);                        if(iDir != END_OF_BUFFER)                        {

⌨️ 快捷键说明

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