📄 spp_frag2.c
字号:
LogMessage(" Fragment timeout: %d seconds\n", f2data.frag_timeout); LogMessage(" Fragment memory cap: %lu bytes\n", (unsigned long)f2data.memcap); LogMessage(" Fragment min_ttl: %d\n", f2data.min_ttl); LogMessage(" Fragment ttl_limit: %d\n", f2data.ttl_limit); LogMessage(" Fragment Problems: %d\n", f2data.frag2_alerts); LogMessage(" Self preservation threshold: %d\n", f2data.sp_threshold); LogMessage(" Self preservation period: %d\n", f2data.sp_period); LogMessage(" Suspend threshold: %d\n", f2data.suspend_threshold); LogMessage(" Suspend period: %d\n", f2data.suspend_period); } return; } else { f2data.memcap = FRAG_MEMCAP; f2data.frag_timeout = FRAG_PRUNE_QUANTA; toks = mSplit(args, ",", 12, &num_toks, 0); i=0; while(i < num_toks) { index = toks[i]; while(isspace((int)*index)) index++; stoks = mSplit(index, " ", 4, &s_toks, 0); if(!strncasecmp(stoks[0], "timeout", 7)) { if(stoks[1] && isdigit((int)stoks[1][0])) { f2data.frag_timeout = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad timeout in config file, " "defaulting to %d seconds\n", file_name, file_line, FRAG_PRUNE_QUANTA); f2data.frag_timeout = FRAG_PRUNE_QUANTA; } } else if(!strncasecmp(stoks[0], "memcap", 6)) { if(stoks[1] && isdigit((int)stoks[1][0])) { f2data.memcap = atoi(stoks[1]); if(f2data.memcap < 16384) { LogMessage("WARNING %s(%d) => Ludicrous (<16k) memcap " "size, setting to default (%d bytes)\n", file_name, file_line, FRAG_MEMCAP); f2data.memcap = FRAG_MEMCAP; } } else { LogMessage("WARNING %s(%d) => Bad memcap in config file, " "defaulting to %u bytes\n", file_name, file_line, FRAG_MEMCAP); f2data.memcap = FRAG_MEMCAP; } } else if(!strcasecmp(stoks[0], "ttl_limit")) { if(s_toks > 1) { if(stoks[1] == NULL || stoks[1][0] == '\0') { FatalError("%s(%d) => ttl_limit requires an integer " "argument\n", file_name,file_line); } if(isdigit((int)stoks[1][0])) { f2data.ttl_limit = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad TTL Limit" "size, setting to default (%d\n", file_name, file_line, FRAG2_TTL_LIMIT); f2data.ttl_limit = FRAG2_TTL_LIMIT; } } else { FatalError("%s(%d) => ttl_limit requires an integer " "argument\n", file_name,file_line); } } else if(!strcasecmp(stoks[0], "min_ttl")) { if(isdigit((int)stoks[1][0])) { f2data.min_ttl = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad TTL Limit" "size, setting to default (%d\n", file_name, file_line, FRAG2_MIN_TTL); f2data.min_ttl = FRAG2_MIN_TTL; } } else if(!strcasecmp(stoks[0], "detect_state_problems")) { f2data.frag2_alerts = 1; } else if(!strcasecmp(stoks[0], "self_preservation_threshold")) { if(isdigit((int)stoks[1][0])) { f2data.sp_threshold = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad sp_threshold in config file, " "defaulting to %d new sessions/second\n", file_name, file_line, SELF_PRES_THRESHOLD); f2data.sp_threshold = SELF_PRES_THRESHOLD; } } else if(!strcasecmp(stoks[0], "self_preservation_period")) { if(isdigit((int)stoks[1][0])) { f2data.sp_period = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad sp_period in config file, " "defaulting to %d seconds\n", file_name, file_line, SELF_PRES_PERIOD); f2data.sp_period = SELF_PRES_PERIOD; } } else if(!strcasecmp(stoks[0], "suspend_threshold")) { if(isdigit((int)stoks[1][0])) { f2data.suspend_threshold = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad suspend_threshold in config file, " "defaulting to %d new sessions/second\n", file_name, file_line, SUSPEND_THRESHOLD); f2data.suspend_threshold = SUSPEND_THRESHOLD; } } else if(!strcasecmp(stoks[0], "suspend_period")) { if(isdigit((int)stoks[1][0])) { f2data.suspend_period = atoi(stoks[1]); } else { LogMessage("WARNING %s(%d) => Bad suspend_period in config file, " "defaulting to %d seconds\n", file_name, file_line, SUSPEND_PERIOD); f2data.suspend_period = SUSPEND_PERIOD; } } else if(!strcasecmp(stoks[0], "state_protection")) { f2data.state_protection = 1; } mSplitFree(&stoks, s_toks); i++; } f2data.frag_sp_data.memcap = f2data.memcap; f2data.frag_sp_data.mem_usage = 0; f2data.frag_sp_data.fault_count = 0; f2data.frag_sp_data.sp_func = Frag2SelfPreserve; mSplitFree(&toks, num_toks); LogMessage("[*] Frag2 config:\n"); LogMessage(" Fragment timeout: %d seconds\n", f2data.frag_timeout); LogMessage(" Fragment memory cap: %lu bytes\n", (unsigned long)f2data.memcap); LogMessage(" Fragment min_ttl: %d\n", f2data.min_ttl); LogMessage(" Fragment ttl_limit: %d\n", f2data.ttl_limit); LogMessage(" Fragment Problems: %d\n", f2data.frag2_alerts); LogMessage(" State Protection: %d\n", f2data.state_protection); LogMessage(" Self preservation threshold: %d\n", f2data.sp_threshold); LogMessage(" Self preservation period: %d\n", f2data.sp_period); LogMessage(" Suspend threshold: %d\n", f2data.suspend_threshold); LogMessage(" Suspend period: %d\n", f2data.suspend_period); }}void Frag2Defrag(Packet *p, void *context){ FragTracker *ft; static int alert_once_emerg = 0; static int alert_once_suspend = 0; if(!(p->preprocessors & PP_FRAG2)) { return; } if(f2_emergency.status != OPS_NORMAL) { /* Check to see if we should return to our non-emergency mode. * If we happen to stay in SUSPSEND mode, exit out */ if(p->pkth->ts.tv_sec >= f2_emergency.end_time) { f2_emergency.status = OPS_NORMAL; f2_emergency.end_time = 0; f2_emergency.new_frag_count = 0; } if(f2_emergency.status == OPS_SUSPEND) { return; } } /* make sure we're interested in this packet */ if(p == NULL || p->iph == NULL || !p->frag_flag) { return; } if(p->csum_flags & CSE_IP) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Discarding invalid IP checksum\n");); return; } if(p->packet_flags & PKT_REBUILT_FRAG) { return; } if(p->ip_options_len) { if(f2data.frag2_alerts) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_IPOPTIONS, 1, 0, 5, FRAG2_IPOPTIONS_STR, 0); return; } } if(p->iph->ip_ttl < f2data.min_ttl) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Got frag packet (mem use: %u frag " "trackers: %d p->pkt_flags: 0x%X)\n", f2data.frag_sp_data.mem_usage, ubi_trCount(FragRootPtr), p->packet_flags);); return; } if (!f2data.last_prune_time) f2data.last_prune_time = p->pkth->ts.tv_sec; DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Got frag packet (mem use: %lu frag " "trackers: %d p->pkt_flags: 0x%X)\n", f2data.frag_sp_data.mem_usage, ubi_trCount(FragRootPtr), p->packet_flags);); ft = GetFragTracker(p); if(ft == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Didn't find frag packet\n");); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Adding New FragTracker...\n");); /* * Much like keeping track of stream sessions, if someone * starts blasting us with fragments without an initial fragment, * the IDS will suffer. * * Here we will mitigate this with another two stage approach. */ if((f2_emergency.status == OPS_NORMAL) || (p->mf && p->frag_offset == 0)) { ft = NewFragTracker(p); /* * keep track of how many sessions per second we're creating vs. the number * of data packets per second we get on those sessions */ if(f2data.state_protection) ++f2_emergency.new_frag_count; } else { ft = NULL; } if(f2data.state_protection) { if(f2_emergency.new_frag_count >= f2data.suspend_threshold) { f2_emergency.status = OPS_SUSPEND; f2_emergency.end_time = p->pkth->ts.tv_sec + f2data.suspend_period; if(alert_once_suspend == 0) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_SUSPEND, 1, 0, 5, FRAG2_SUSPEND_STR, 0); alert_once_suspend = 1; } } else if (f2_emergency.new_frag_count >= f2data.sp_threshold) { f2_emergency.status = OPS_SELF_PRESERVATION; f2_emergency.end_time = p->pkth->ts.tv_sec + f2data.sp_period; if(alert_once_emerg == 0) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_EMERGENCY, 1, 0, 5, FRAG2_EMERGENCY_STR, 0); alert_once_emerg = 1; } } } if(ft == NULL) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Discarding fragment, Disabling Detection\n");); /* * Mark that this packet isn't worth doing IDS on. This * is self preservation because either our system is under * session trashing attacks. */ DisableDetect(p); } UpdateIPFragStats(&(sfPerf.sfBase), p->pkth->caplen); return; } /* ft is not NULL at this point */ if(ft->alerted == 1) { /* one alert per fragment is good enough */ return; } DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Found frag packet\n");); /* detect ttl based evasion techniques */ if(f2data.ttl_limit) { /* ft->ttl is already set in the ft a few lines above */ if(abs(ft->ttl - p->iph->ip_ttl) >= f2data.ttl_limit) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_TTL_EVASION, 1, 0, 5, FRAG2_TTL_EVASION_STR, 0); /* lets just go look at real events from now on. */ return; } } if(InsertFrag(p, ft) == -1) { if(pv.verbose_flag) { LogMessage("WARNING: Insert into Fraglist failed" ", probably duplicate fragment (offset: %u)\n", p->frag_offset); } return; } else { CompletionData compdata; compdata.complete = 0; compdata.teardrop = 0; compdata.outoforder = 0; if(FragIsComplete(ft, &compdata)) { if(compdata.teardrop) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_TEARDROP, 1, 0, 5, FRAG2_TEARDROP_STR, 0); ft->alerted = 1; DisableDetect(p); return; } else if(f2data.frag2_alerts && compdata.outoforder && !(p->packet_flags & PKT_FRAG_ALERTED)) { SnortEventqAdd(GENERATOR_SPP_FRAG2, FRAG2_OUTOFORDER, 1, 0, 5, FRAG2_OUTOFORDER_STR, 0); DisableDetect(p); p->packet_flags |= PKT_FRAG_ALERTED; return; } RebuildFrag(ft, p); } else { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Fragment not complete\n");); } UpdateIPFragStats(&(sfPerf.sfBase), p->pkth->caplen); } if( (u_int32_t)(p->pkth->ts.tv_sec) > (f2data.last_prune_time + f2data.frag_timeout)) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Prune time quanta for defrag code hit, " "pruning frag tree...\n");); PruneFragCache(ft, p->pkth->ts.tv_sec, 0); DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "Finished pruning, %lu frag trackers " "active, %lu alloc faults\n", ubi_trCount(FragRootPtr), (unsigned long) frag2_alloc_faults);); f2data.last_prune_time = p->pkth->ts.tv_sec; } return;}FragTracker *GetFragTracker(Packet *p){ FragTracker ft; FragTracker *returned; if(ubi_trCount(FragRootPtr) == 0) return NULL; if(f2data.frag_sp_data.mem_usage == 0) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG, "trCount says nodes exist but " "f2data.frag_sp_data.mem_usage = 0\n");); return NULL; } ft.sip = p->iph->ip_src.s_addr; ft.dip = p->iph->ip_dst.s_addr; ft.id = p->iph->ip_id;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -