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

📄 hi_client.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 5 页
字号:
    **    **  If there is a function, we call that function and process.  It's    **  important to note that the function that is called is responsible    **  for incrementing the ptr to the next char to be inspected.  The    **  loop does not increment the pointer when a function is called to    **  allow the maximum flexibility to the functions.    */    while(hi_util_in_bounds(start, end, ptr))    {        /* isascii returns non-zero if it is ascii */        if (isascii((int)*ptr) == 0)        {            /* Possible post data or something else strange... */            iRet = URI_END;            break;        }        if(lookup_table[*ptr] || ServerConf->whitespace[*ptr])        {            if(lookup_table[*ptr])            {                iRet = (lookup_table[*ptr])(Session, start, end,                            &ptr, uri_ptr);            }            else            {                iRet = NextNonWhiteSpace(Session, start, end, &ptr, uri_ptr);            }            if(iRet)            {                if(iRet == URI_END)                {                    /*                    **  You found a URI, let's break and check it out.                    */                    break;                }                else if(iRet == HI_OUT_OF_BOUNDS)                {                    /*                    **  Means you've reached the end of the buffer.  THIS                    **  DOESN'T MEAN YOU HAVEN'T FOUND A URI.                    */                    break;                }                else /* NO_URI */                {                    /*                    **  Check for chunk encoding, because the delimiter can                    **  also be a space, which would look like a pipeline request                    **  to us if we don't do this first.                    */                    if(Session->server_conf->chunk_length)                            CheckChunkEncoding(Session, start, end);                    /*                    **  We only inspect the packet for another pipeline                    **  request if there wasn't a previous pipeline request.                    **  The reason that we do this is because                     */                      if(!Client->request.pipeline_req)                    {                        /*                        **  Just because there was no URI in the first part                        **  the packet, doesn't mean that this isn't a                        **  pipelined request that has been segmented.                        */                        if(!ServerConf->no_pipeline)                        {                            Client->request.pipeline_req = FindPipelineReq(Session, ptr, end);                            if(Client->request.pipeline_req)                            {                                return HI_SUCCESS;                            }                        }                    }                    return HI_NONFATAL_ERR;                }            }            else            {                /*                **  This means that we found the next non-whitespace char                **  and since we are already pointed there, so we just                **  continue.                */                continue;            }        }        ptr++;    }    return iRet;}/***  NAME**    hi_client_extract_header::*//****  Catch multiple requests per packet, by returning pointer to after the**  end of the request header if there is another request.**  **  There are 4 types of "valid" delimiters that we look for.  They are:**  "\r\n\r\n"**  "\r\n\n"**  "\n\r\n"**  "\n\n"**  The only patterns that we really only need to look for are:**  "\n\r\n"**  "\n\n"**  The reason being that these two patterns are suffixes of the other **  patterns.  So once we find those, we are all good.**  **  @param Session pointer to the session**  @param start pointer to the start of text**  @param end   pointer to the end of text**  **  @return pointer**  **  @retval NULL  Did not find pipeline request**  @retval !NULL Found another possible request.*/static INLINE const u_char *hi_client_extract_header(    HI_SESSION *Session, HTTPINSPECT_CONF *ServerConf,     HI_CLIENT * Client, HEADER_PTR *header_ptr,    const u_char *start, const u_char *end){    int iRet = HI_SUCCESS;    const u_char *p;    const u_char *offset;    URI_PTR version_string;    COOKIE_PTR *cookie_ptr = NULL;    if(!start || !end)        return NULL;    p = start;    /*    **  We say end - 6 because we need at least six bytes to verify that    **  there is an end to the URI and still a request afterwards.  To be    **  exact, we should only subtract 1, but we are not interested in a    **  1 byte method, uri, etc.    **    **  a.k.a there needs to be data after the initial request to inspect    **  to make it worth our while.    */     if (p > (end - 6 ))    {        header_ptr->header.uri = NULL;        return p;    }    /* This is to skip past the HTTP/1.0 (or 1.1) version string */    if (IsHttpVersion(&p, end))    {        memset(&version_string, 0, sizeof(URI_PTR));        version_string.uri = p;        while (hi_util_in_bounds(start, end, p))        {            if(lookup_table[*p] || ServerConf->whitespace[*p])            {                if(lookup_table[*p])                {                    iRet = (lookup_table[*p])(Session, start, end, &p, &version_string);                }                else                {                    iRet = NextNonWhiteSpace(Session, start, end, &p, &version_string);                }                if(iRet == URI_END)                {                    if (*p == '\n')                    {                        p++;                        if (hi_util_in_bounds(start, end, p))                        {                            version_string.uri_end = p;                        }                        else                        {                            return p;                        }                    }                    break;                }                else if(iRet == HI_OUT_OF_BOUNDS)                {                    return p;                }            }            p++;        }        if (iRet == URI_END)        {            header_ptr->header.uri = version_string.uri_end + 1;            offset = (u_char *)p;        }        else        {            return p;        }    }    offset = (u_char*)p;    header_ptr->header.uri = p;    while (hi_util_in_bounds(start, end, p))    {        if(*p == '\n')        {            if(hi_eo_generate_event(Session, Session->server_conf->max_hdr_len)               && ((p - offset) >= Session->server_conf->max_hdr_len))            {                hi_eo_client_event_log(Session, HI_EO_CLIENT_LONG_HDR, NULL, NULL);            }            p++;            offset = (u_char*)p;            if (!hi_util_in_bounds(start, end, p))            {                header_ptr->header.uri_end = p;                return p;            }            /* As performance ugly as this may be, need to bounds check p in each of the             * if blocks below to prevent read beyond end of buffer */            if (*p < 0x0E)            {                if(*p == '\r')                {                    p++;                    if(hi_util_in_bounds(start, end, p) && (*p == '\n'))                    {                        header_ptr->header.uri_end = p;                        return ++p;                    }                }                else if(*p == '\n')                {                    header_ptr->header.uri_end = p;                    return ++p;                }            }            else if (((p - offset) == 0) && ((*p == 'C') || (*p == 'c')))            {                /* Search for 'Cookie' at beginning, starting from current *p */                if (hi_util_in_bounds(start, end, p+6))                {                    if (!strncasecmp((const char *)p, "Cookie", 6))                    {                        if (header_ptr->cookie.cookie)                        {                            /* unusal, multiple cookies... alloc new cookie pointer */                            COOKIE_PTR *extra_cookie = calloc(1, sizeof(COOKIE_PTR));                            if (!extra_cookie)                            {                                /* Failure to allocate, stop where we are... */                                header_ptr->header.uri_end = p;                                return p;                            }                            cookie_ptr->next = extra_cookie;                            cookie_ptr = extra_cookie;                            /* extra_cookie->next = NULL; */ /* removed, since calloc NULLs this. */                        }                        else                        {                            cookie_ptr = &header_ptr->cookie;                        }                        cookie_ptr->cookie = p;                                                   {                            const u_char *crlf = (u_char *)SnortStrnStr((const char *)p, end - p, "\r\n");                            //const u_char *crlf = (const u_char *)strstr((const char *)p, "\r\n");                            /* find a \r\n (CRLF) */                            if (crlf) /* && hi_util_in_bounds(start, end, crlf+1)) bounds is checked in SnortStrnStr */                            {                                cookie_ptr->cookie_end = crlf + 2;                                p = crlf;                            }                            else                            {                                header_ptr->header.uri_end = cookie_ptr->cookie_end = end;                                                     return end;                            }                        }                    }                }            }        }        p++;    }    /* Never observed an end-of-field.  Maybe it's not there, but the header is long anyway: */    if(hi_eo_generate_event(Session, Session->server_conf->max_hdr_len)       && ((p - start) >= Session->server_conf->max_hdr_len))    {        hi_eo_client_event_log(Session, HI_EO_CLIENT_LONG_HDR, NULL, NULL);    }    header_ptr->header.uri_end = p;    return p;}#define CLR_POST(Client) \    do { \                Client->request.post_raw = NULL;\                Client->request.post_raw_size = 0;\                Client->request.post_norm = NULL; \    } while(0);#define CLR_HEADER(Client) \    do { \                Client->request.header_raw = NULL;\                Client->request.header_raw_size = 0;\                Client->request.header_norm = NULL; \                Client->request.cookie.cookie = NULL;\                Client->request.cookie.cookie_end = NULL;\                Client->request.cookie.next = NULL;\    } while(0);/***  NAME**    StatelessInspection::*//****  Find the URI and determine whether the URI needs to be normalized.**  **  This is a big step in stateless inspection, because we need to reliably**  find the URI and when possible filter out non-URIs.  We do this using a**  simple state machine that is based on characters found in the data**  buffer.**  **  Another important aspect of the stateless inspection is the ability to**  track and inspect pipelined requests.  It is VERY IMPORTANT to reset the**  pipeline_req pointer, since we don't memset the whole structure.  This**  pointer is reset in the hi_si_session_inspection() function.  Check there**  for more details.**  **  Normalization is detected when we are looking at the packet for the URI.**  We look for the following issues:**      - ////**      - /../**      - /./**      - non-ascii charss**      - %**      - \**  When these things are seen we point to the first occurence in the URI, or**  where we have to start normalizing.  If the URI is updated to a new**  pointer, then the normalization pointer is reset and we start over.**  Using this method should cut down the memcpy()s per URI, since most**  URIs are not normalized.**  **  If this function returns HI_NONFATAL_ERR, we return out of mode_inspection**  with an error and abort HttpInspect processing, and continue on with**  any other processing we do.  The Session parameters that we use here are**  reset in the next time that we do session_inspection, so we don't do**  any initialization here.**  **  @param Session pointer to the HTTP session**  @param data    pointer to the start of the packet payload**  @param dsize   size of the payload**  **  @return integer**  **  @retval HI_INVALID_ARG  invalid argument**  @retval HI_NONFATAL_ERR no URI detected**  @retval HI_SUCCESS      URI detected and Session pointers updated*/static int StatelessInspection(HI_SESSION *Session, const unsigned char *data,        int dsize){    HTTPINSPECT_CONF *ServerConf;    HTTPINSPECT_CONF *ClientConf;    HI_CLIENT *Client;    URI_PTR method_ptr;    URI_PTR uri_ptr;    URI_PTR post_ptr;    HEADER_PTR header_ptr;    const u_char *start;    const u_char *end;    const u_char *ptr, *mthd;    const u_char *method_end = NULL;    int method_len;    int iRet;    int len;    char non_ascii_mthd = 0;    char sans_uri = 0;    if(!Session || !data || dsize < 1)    {        return HI_INVALID_ARG;    }    ServerConf = Session->server_conf;    if(!ServerConf)    {        return HI_INVALID_ARG;    }    ClientConf = Session->client_conf;    if(!ClientConf)    {        return HI_INVALID_ARG;    }    Client = &Session->client;    memset(&uri_ptr, 0x00, sizeof(URI_PTR));    memset(&post_ptr, 0x00, sizeof(URI_PTR));    memset(&header_ptr, 0x00, sizeof(HEADER_PTR));    memset(&method_ptr, 0x00, sizeof(URI_PTR));    /*    **  We set the starting boundary depending on whether this request is    **  a normal request or a pipeline request.  The end boundary is always    **  the same whether it is a pipeline request or other.    */    if(Client->request.pipeline_req)    {        start = Client->request.pipeline_req;    }    else    {        start = data;    }

⌨️ 快捷键说明

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