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

📄 snort_httpinspect.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        /*        **  Let's print out the global config        */        PrintGlobalConf(GlobalConf);    }    /*    **  Server Configuration    */    else if(!iGlobal && !strcmp(pcToken, SERVER))    {        if((iRet = ProcessUniqueServerConf(GlobalConf,                                            ErrorString, ErrStrLen)))        {            return iRet;        }    }    /*    **  Invalid configuration keyword    */    else    {        if(iGlobal)        {            snprintf(ErrorString, ErrStrLen,                    "Invalid configuration token '%s'.  "                     "The first configuration must start with a '%s' "                    "configuration type.", pcToken, GLOBAL);        }        else        {            snprintf(ErrorString, ErrStrLen,                    "Invalid configuration token '%s'.  Must be a '%s' "                    "configuration.", pcToken, SERVER);        }        return -1;    }    return 0;}/***  NAME**    LogEvents::*//****  This is the routine that logs HttpInspect alerts through Snort.**  **  Every Session gets looked at for any logged events, and if there are**  events to be logged then we select the one with the highest priority.**  **  We use a generic event structure that we set for each different event**  structure.  This way we can use the same code for event logging regardless**  of what type of event strucure we are dealing with.**  **  The important things to know about this function is how to work with**  the event queue.  The number of unique events is contained in the**  stack_count variable.  So we loop through all the unique events and**  find which one has the highest priority.  During this loop, we also**  re-initialize the individual event counts for the next iteration, saving**  us time in a separate initialization phase.**  **  After we've iterated through all the events and found the one with the**  highest priority, we then log that event through snort.**  **  We've mapped the HttpInspect and the Snort alert IDs together, so we**  can access them directly instead of having a more complex mapping**  function.  It's the only good way to do this.**  **  @param Session          pointer to Session construct**  @param p                pointer to the Snort packet construct**  @param iInspectMode     inspection mode to take event queue from**  **  @return integer**  **  @retval 0 this function only return success*/static inline int LogEvents(HI_SESSION *hi_ssn, Packet *p, int iInspectMode){    HI_GEN_EVENTS GenEvents;    HI_EVENT      *OrigEvent;    HI_EVENT      *HiEvent = NULL;    Session       *ssn = NULL;    u_int32_t     uiMask = 0;    int           iGenerator;    int           iStackCnt;    int           iEvent;    int           iCtr;    /*    **  Set the session ptr, if applicable    */    if(p && p->ssnptr)        ssn = (Session *)p->ssnptr;        if(iInspectMode == HI_SI_CLIENT_MODE)    {        GenEvents.stack =       hi_ssn->client.event_list.stack;        GenEvents.stack_count = &(hi_ssn->client.event_list.stack_count);        GenEvents.events =      hi_ssn->client.event_list.events;        iGenerator = GENERATOR_SPP_HTTP_INSPECT_CLIENT;    }    else if(iInspectMode == HI_SI_SERVER_MODE)    {        /*        **  We have no server events right now, so we just return.        */        return 0;    }    else    {        GenEvents.stack =       hi_ssn->anom_server.event_list.stack;        GenEvents.stack_count = &(hi_ssn->anom_server.event_list.stack_count);        GenEvents.events =      hi_ssn->anom_server.event_list.events;        iGenerator = GENERATOR_SPP_HTTP_INSPECT_ANOM_SERVER;    }    /*    **  Now starts the generic event processing    */    iStackCnt = *(GenEvents.stack_count);    /*    **  IMPORTANT::    **  We have to check the stack count of the event queue before we process    **  an log.    */    if(iStackCnt == 0)    {        return 0;    }    /*    **  Cycle through the events and select the event with the highest    **  priority.    */    for(iCtr = 0; iCtr < iStackCnt; iCtr++)    {        iEvent = GenEvents.stack[iCtr];        OrigEvent = &(GenEvents.events[iEvent]);        /*        **  Set the event to start off the comparison        */        if(!HiEvent)        {            HiEvent = OrigEvent;        }        /*        **  This is our "comparison function".  Log the event with the highest        **  priority.        */        if(OrigEvent->event_info->priority < HiEvent->event_info->priority)        {            HiEvent = OrigEvent;        }        /*        **  IMPORTANT:        **    This is how we reset the events in the event queue.        **    If you miss this step, you can be really screwed.        */        OrigEvent->count = 0;    }    /*    **  We use the iEvent+1 because the event IDs between snort and    **  HttpInspect are mapped off-by-one.  Don't ask why, drink Bud    **  Dry . . . They're mapped off-by one because in the internal    **  HttpInspect queue, events are mapped starting at 0.  For some    **  reason, it appears that the first event can't be zero, so we    **  use the internal value and add one for snort.    */    iEvent = HiEvent->event_info->alert_id + 1;    uiMask = (u_int32_t)(1 << (iEvent & 31));    /*    **  If we've already logged this event for this stream, then    **  don't log it again.    */    if(ssn && (ssn->http_alert_flags & uiMask))    {        return 0;    }    SnortEventqAdd(iGenerator, iEvent, 1, 0, 3, HiEvent->event_info->alert_str,0);    /*    **  Set the http_flag bit so we don't log the event on a reassembled    **  stream.    */    if(ssn)        ssn->http_alert_flags |= uiMask;    /*    **  Reset the event queue stack counter, in the case of pipelined    **  requests.    */    *(GenEvents.stack_count) = 0;    return 0;}static inline int SetSiInput(HI_SI_INPUT *SiInput, Packet *p){    Session *ssnptr = NULL;    SiInput->sip   = p->iph->ip_src.s_addr;    SiInput->dip   = p->iph->ip_dst.s_addr;    SiInput->sport = p->sp;    SiInput->dport = p->dp;    if(p->ssnptr)    {        ssnptr = (Session *)p->ssnptr;    }    /*    **  We now set the packet direction    */    if(ssnptr && ssnptr->session_flags & SSNFLAG_MIDSTREAM)    {        SiInput->pdir = HI_SI_NO_MODE;    }    else if(p->packet_flags & PKT_FROM_SERVER)    {        SiInput->pdir = HI_SI_SERVER_MODE;    }    else if(p->packet_flags & PKT_FROM_CLIENT)    {        SiInput->pdir = HI_SI_CLIENT_MODE;    }    else    {        SiInput->pdir = HI_SI_NO_MODE;    }    return HI_SUCCESS;}/***  NAME**    SnortHttpInspect::*//****  This function calls the HttpInspect function that processes an HTTP **  session.****  We need to instantiate a pointer for the HI_SESSION that HttpInspect **  fills in.  Right now stateless processing fills in this session, which **  we then normalize, and eventually detect.  We'll have to handle **  separately the normalization events, etc.**  **  This function is where we can see from the highest level what the**  HttpInspect flow looks like.****  @param GlobalConf pointer to the global configuration**  @param p          pointer to the Packet structure****  @return integer****  @retval  0 function successful**  @retval <0 fatal error**  @retval >0 non-fatal error*/int SnortHttpInspect(HTTPINSPECT_GLOBAL_CONF *GlobalConf, Packet *p){    extern HttpUri UriBufs[URI_COUNT];    extern int     do_detect;    extern OptTreeNode *otn_tmp;    HI_SESSION  *Session;    HI_SI_INPUT SiInput;    int iInspectMode = 0;    int iRet;    int iCallDetect = 1;        if(!p->iph || !p->tcph)    {        return 1;    }    /*    **  Set up the HI_SI_INPUT pointer.  This is what the session_inspection()    **  routines use to determine client and server traffic.  Plus, this makes    **  the HttpInspect library very independent from snort.    */    SetSiInput(&SiInput, p);    /*    **  HTTPINSPECT PACKET FLOW::    **    **  Session Inspection Module::    **    The Session Inspection Module retrieves the appropriate server    **    configuration for sessions, and takes care of the stateless    **    vs. stateful processing in order to do this.  Once this module    **    does it's magic, we're ready for the primetime.    **    **  HTTP Inspection Module::    **    This isn't really a module in HttpInspect, but more of a helper    **    function that sends the data to the appropriate inspection    **    routine (client, server, anomalous server detection).    **    **  HTTP Normalization Module::    **    This is where we normalize the data from the HTTP Inspection    **    Module.  The Normalization module handles what type of normalization    **    to do (client, server).    **    **  HTTP Detection Module::    **    This isn't being used in the first iteration of HttpInspect, but    **    all the HTTP detection components of signatures will be.    **    **  HTTP Event Output Module::    **    The Event Ouput Module handles any events that have been logged    **    in the inspection, normalization, or detection phases.    */         /*    **  Session Inspection Module::    */    if((iRet = hi_si_session_inspection(GlobalConf, &Session, &SiInput,                     &iInspectMode)))    {        return iRet;    }        /*    **  HTTP Inspection Module::    **    **  This is where we do the client/server inspection and find the    **  various HTTP protocol fields.  We then normalize these fields and    **  call the detection engine.    **    **  The reason for the loop is for pipelined requests.  Doing pipelined    **  requests in this way doesn't require any memory or tracking overhead.    **  Instead, we just process each request linearly.    */    do    {        /*        **  INIT:        **  We set this equal to zero (again) because of the pipelining        **  requests.  We don't want to bail before we get to setting the        **  URI, so we make sure here that this can't happen.        */        p->uri_count = 0;        UriBufs[0].decode_flags = 0;	if(iInspectMode == HI_SI_SERVER_MODE)	{	    /* Don't do server inspection */	    if (Session->server_conf->flow_depth == -1)	    {                do_detect = 0;                p->preprocessors = 0;                p->preprocessors |= PP_PORTSCAN;                p->preprocessors |= PP_STREAM4;                return 0;	    }	}        if((iRet = hi_mi_mode_inspection(Session, iInspectMode, p->data,                                         p->dsize)))        {            LogEvents(Session,p,iInspectMode);            return iRet;        }        if((iRet = hi_normalization(Session, iInspectMode)))        {            LogEvents(Session,p,iInspectMode);            return iRet;        }        /*        **  Let's setup the pointers for the detection engine, and        **  then go for it.        */        if(iInspectMode == HI_SI_CLIENT_MODE)        {            if(!iCallDetect || Session->server_conf->uri_only)            {                UriBufs[0].decode_flags |= HTTPURI_PIPELINE_REQ;            }            if(Session->client.request.uri_norm)            {                UriBufs[0].uri    = Session->client.request.uri_norm;                UriBufs[0].length = Session->client.request.uri_norm_size;                p->uri_count = 1;                p->packet_flags |= PKT_HTTP_DECODE;            }            else if(Session->client.request.uri)            {                UriBufs[0].uri    = Session->client.request.uri;                UriBufs[0].length = Session->client.request.uri_size;                p->uri_count = 1;                p->packet_flags |= PKT_HTTP_DECODE;            }        }        else if(iInspectMode == HI_SI_SERVER_MODE)        {            /*            **  We set the header length and detect the normal way.            */            p->dsize = Session->server.header_size;            /*            **  If dsize is 0, we only get here because dsize was set to 0            **  by the server module by the flow_depth inspection.            **            **  We check here to see whether this was a server response            **  header or not.  If the dsize is 0 then, we know that this            **  is not the header and don't do any detection.            */            if(p->dsize == 0)            {                do_detect = 0;                p->preprocessors = 0;                p->preprocessors |= PP_PORTSCAN;                p->preprocessors |= PP_STREAM4;                return 0;            }        }        else        {            /*            **  We log events before doing detection because every non-HTTP            **  packet is possible an anomalous server.  So we still want to            **  go through the regular detection engine, and just log any            **  alerts here before returning.             **            **  Return normally if this isn't either HTTP client or server            **  traffic.            */            if(Session->anom_server.event_list.stack_count)                LogEvents(Session, p, iInspectMode);            return 0;        }        /*        **  If we get here we either had a client or server request/response.        **  We do the detection here, because we're starting a new paradigm        **  about protocol decoders.        **        **  Protocol decoders are now their own detection engine, since we are        **  going to be moving protocol field detection from the generic        **  detection engine into the protocol module.  This idea scales much        **  better than having all these Packet struct field checks in the        **  main detection engine for each protocol field.        */        Detect(p);        otn_tmp = NULL;        /*        **  Handle event stuff after we do detection.        **        **  Here's the reason why:        **    - since snort can only handle one logged event per packet,         **      we only log HttpInspect events if there wasn't one in the 

⌨️ 快捷键说明

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