?? snort_httpinspect.c
字號:
#else Ip = inet_addr(pcToken); if(Ip == INADDR_NONE)#endif { SnortSnprintf(ErrorString, ErrStrLen, "Invalid IP to '%s' token.", SERVER); return -1; } /* ** allocate the memory for the server configuration */ ServerConf = (HTTPINSPECT_CONF *)calloc(1, sizeof(HTTPINSPECT_CONF)); if(!ServerConf) { SnortSnprintf(ErrorString, ErrStrLen, "Could not allocate memory for server configuration."); return -1; } iRet = ProcessServerConf(GlobalConf, ServerConf, ErrorString, ErrStrLen); if (iRet) { return iRet; } iRet = hi_ui_config_add_server(GlobalConf, Ip, ServerConf); if (iRet) { /* ** Check for already added servers */ if(iRet == HI_NONFATAL_ERR) { SnortSnprintf(ErrorString, ErrStrLen, "Duplicate server configuration."); return -1; } else { SnortSnprintf(ErrorString, ErrStrLen, "Error when adding server configuration."); return -1; } } /* ** Print out the configuration header */#ifdef SUP_IP6 LogMessage(" SERVER: %s\n", sfip_ntoa(Ip));#else ip_addr.s_addr = Ip; LogMessage(" SERVER: %s\n", inet_ntoa(ip_addr));#endif } /* ** Finish printing out the server configuration */ PrintServerConf(ServerConf); return 0;}static int PrintGlobalConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf){ LogMessage("HttpInspect Config:\n"); LogMessage(" GLOBAL CONFIG\n"); LogMessage(" Max Pipeline Requests: %d\n", GlobalConf->max_pipeline_requests); LogMessage(" Inspection Type: %s\n", GlobalConf->inspection_type ? "STATEFUL" : "STATELESS"); LogMessage(" Detect Proxy Usage: %s\n", GlobalConf->proxy_alert ? "YES" : "NO"); LogMessage(" IIS Unicode Map Filename: %s\n", GlobalConf->iis_unicode_map_filename); LogMessage(" IIS Unicode Map Codepage: %d\n", GlobalConf->iis_unicode_codepage); return 0;}/*** NAME** HttpInspectSnortConf::*//**** This function takes the HttpInspect configuration line from the ** snort.conf and creats an HttpInspect configuration.**** This routine takes care of the snort specific configuration processing** and calls the generic routines to add specific server configurations.** It sets the configuration structure elements in this routine.**** The ErrorString is passed in as a pointer, and the ErrStrLen tells** us the length of the pointer.**** @param GlobalConf a pointer to the global configuration.** @param args a pointer to argument string.** @param iGlobal whether this is the global configuration or a server** @param ErrorString a pointer for an error string.** @param ErrStrLen the length of the error string.**** @return an error code integer ** (0 = success, >0 = non-fatal error, <0 = fatal error)**** @retval 0 success** @retval 1 generic non-fatal error** @retval -1 generic fatal error** @retval -2 ErrorString is undefined*/static int s_iGlobal = 0;int HttpInspectSnortConf(HTTPINSPECT_GLOBAL_CONF *GlobalConf, char *args, int iGlobal, char *ErrorString, int ErrStrLen){ char *pcToken; int iRet; /* ** Check input variables */ if(ErrorString == NULL) { return -2; } if(GlobalConf == NULL) { SnortSnprintf(ErrorString, ErrStrLen, "Global configuration variable undefined."); return -1; } if(args == NULL) { SnortSnprintf(ErrorString, ErrStrLen, "No arguments to HttpInspect configuration."); return -1; } /* ** Find out what is getting configured */ pcToken = strtok(args, CONF_SEPARATORS); if(pcToken == NULL) { SnortSnprintf(ErrorString, ErrStrLen, "No arguments to HttpInspect configuration."); return -1; } /* ** Global Configuration Processing ** We only process the global configuration once, but always check for ** user mistakes, like configuring more than once. That's why we ** still check for the global token even if it's been checked. */ if((s_iGlobal || iGlobal) && !strcmp(pcToken, GLOBAL)) { /* ** Don't allow user to configure twice */ if(s_iGlobal) { SnortSnprintf(ErrorString, ErrStrLen, "Cannot configure '%s' settings more than once.", GLOBAL); return -1; } iRet = ProcessGlobalConf(GlobalConf, ErrorString, ErrStrLen); if (iRet) { return iRet; } s_iGlobal = 1; /* ** Let's print out the global config */ PrintGlobalConf(GlobalConf); } /* ** Server Configuration */ else if(!iGlobal && !strcmp(pcToken, SERVER)) { iRet = ProcessUniqueServerConf(GlobalConf, ErrorString, ErrStrLen); if (iRet) { return iRet; } } /* ** Invalid configuration keyword */ else { if(iGlobal) { SnortSnprintf(ErrorString, ErrStrLen, "Invalid configuration token '%s'. " "The first configuration must start with a '%s' " "configuration type.", pcToken, GLOBAL); } else { SnortSnprintf(ErrorString, ErrStrLen, "Invalid configuration token '%s'. Must be a '%s' " "configuration.", pcToken, SERVER); } return -1; } return 0;}/*** NAME** HttpInspectCheckConfig::*//**** This function verifies the HttpInspect configuration is complete**** @return none*/void HttpInspectCheckConfig(void){ if (s_iGlobal && !s_iDefaultServer) FatalError("HttpInspectConfigCheck() default server configuration " "not specified\n"); /* So we don't have to check it every time we use it */ if (s_iGlobal) { if ((!stream_api) || (stream_api->version < STREAM_API_VERSION4)) FatalError("HttpInspectConfigCheck() Streaming & reassembly " "must be enabled\n"); }}/*** 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; u_int32_t uiMask = 0; int iGenerator; int iStackCnt; int iEvent; int iCtr; u_int32_t httpflags = 0; /* ** Set the session ptr, if applicable */ 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(p->ssnptr) { httpflags = (u_int32_t)(uintptr_t)stream_api->get_application_data(p->ssnptr, PP_HTTPINSPECT); } if (httpflags & uiMask) { return 0; } SnortEventqAdd(iGenerator, iEvent, 1, 0, 3, HiEvent->event_info->alert_str,0); /* ** Set the http_flag (preproc_specific data) bit so we don't log the event on a reassembled ** stream. */ if(p->ssnptr) { httpflags |= uiMask; stream_api->set_application_data(p->ssnptr, PP_HTTPINSPECT, (void *)(uintptr_t)httpflags, NULL); } /* ** 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){ IP_COPY_VALUE(SiInput->sip, GET_SRC_IP(p)); IP_COPY_VALUE(SiInput->dip, GET_DST_IP(p)); SiInput->sport = p->sp; SiInput->dport = p->dp; /* ** We now set the packet direction */ if(p->ssnptr && stream_api->get_session_flags(p->ssnptr) & 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 successfu
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -