Detecting Fragmentation Attacks and Fragment Reassembly with Frag2
Problem
How can Snort help me detect attacks that try to use small fragmented packet streams or fragmented network scans to try and get through my weak ACLs?
Solution
Use the frag2 preprocessor to help detect fragmentation attacks. These are DoS attacks from tools like Teardrop or Jolt to a network probe using hping2 or fragroute. The frag2 preprocessor isn't very useful for a more in-depth analysis, but here are a couple examples you might find useful. In Example 4-13, the time that packets are kept in the preprocessor has been shortened, as well as the memory allocated to this preprocessor. This might be used on a high-speed sensor, such as at a perimeter sensor where fragmented attacks such a denial of service (Dos) might happen. Another example of this type of configuration is at a core or network aggregation point, such as a speed throttling or proxy point, as shown in Example 4-12.
Example 4-12. Tweak the time limit and memory size for a core or high-traffic sensor
# Default timeout 60 seconds and memory buffer of 4MB Preprocessor frag2: timeout 15, memcap 2097152
Example 4-13 would be good for sensors deep inside a network core that only should have certain packets coming and going through it.
Example 4-13. Tweak the TTL limit to alarm if packets are outside a set range
Preprocessor frag2: min_ttl 5, ttl_limit 15
The preprocessor sets the default minimum TTL to 0 to help detect even local network attacks. This also sets the default highest count on the TTL that it will count as 55 hops away. If you are monitoring a specific network segment that should be accepting packets only from certain route points, you can use this limit to automatically detect when packets are not coming through your specific route points.
Preprocessor frag2:ttl_limit 10, min_ttl 5
Example 4-14 will help us detect use of probing tools, such as fragroute and hping2. However, as this can be a very noisy alarm on most high-speed or asynchronous networks, this is disabled by default in the Snort configuration.
Example 4-14. Turn on detect_state_problems
preprocessor frag2: detect_state_problems
Discussion
Attack tools such as Teardrop, Jolt, and fragroute all had one similarity: they all used some form of fragmentation or irregular packet lengths to successfully exploit and/or identify their targets. The frag2 preprocessor detects this type of attack by analyzing the fragmented packets in terms of TTL, time, and even duration of the flow. However, another form of attack that can slip by border firewalls is a fragmented network scan. This sends fragmented packets that are either smaller than usual or otherwise out of spec to gain entry past a border firewall and get responses back from internal hosts. Hping2 is one tool that can launch this type of attack. However, for simplicity, the following example uses the Teardrop exploit itself.
This is what the example attacker might launch "./teardrop_frag.exec 10.0.4.100 10.0.4.2 -s 4321 -t 80 -n 80"
With the frag2 preprocessor enabled, Snort would detect the attack and send out the following alarm.
"[**] [113:2:1] (spp_frag2) Teardrop attack [**] 08/16-01:19:44.445492 10.0.4.100 -> 10.0.4.2 UDP TTL:64 TOS:0x0 ID:242 IpLen:20 DgmLen:24 Frag Offset: 0x0003 Frag Size: 0x0004"
These tools are widely available and actively in use "in the wild." Having seen several of the tools, what they can do to bypass a Cisco router ACL with a simple RST scan is pretty scary. However, with this preprocessor and several other signatures to help identify this type of attack, you can protect your network.
The rose attack is one method of attacking an entire range of network devices, from workstations to routers and switches. This attack would come in the form of a two-packet attack, so the response time is severely limited. The attacker can also modify the original code to make detection much harder. However, there is a small patch to the frag2 preprocessor that enables the preprocessor to detect this type of attack. The following patch file will enable you to add an option to the frag2 preprocessor in your snort.conf file causing several alarms for rose like attacks. (Special thanks to Marty Roesch, who developed this patch, along with helping to bring it up to Snort 2.2.x version support.) To install this patch, simply copy the following code into a file, and then follow the instructions.
# The rose_attack_detection.patch ----------START OF PATCH ----------------------- diff -ur snort-2.2.0/src/generators.h snort-2.2.0.rose/src/generators.h --- snort-2.2.0/src/generators.h Mon Oct 20 11:03:19 2003 +++ snort-2.2.0.rose/src/generators.h Fri Apr 9 21:54:26 2004 @@ -109,6 +109,7 @@ #define FRAG2_IPOPTIONS 8 #define FRAG2_EMERGENCY 9 #define FRAG2_SUSPEND 10 +#define FRAG2_ROSE_ATTACK 11 #define GENERATOR_SPP_FNORD 114 #define FNORD_NOPSLED 1 @@ -240,6 +241,7 @@ #define FRAG2_TTL_EVASION_STR "(spp_frag2) TTL Limit Exceeded (reassemble) detection" #define FRAG2_EMERGENCY_STR "(spp_frag2) Shifting to Emergency Session Mode" #define FRAG2_SUSPEND_STR "(spp_frag2) Shifting to Suspend Mode" +#define FRAG2_ROSE_STR "(spp_frag2) Interfragment gap threshold exceeded, possible Rose attack" diff -ur snort-2.2.0/src/preprocessors/spp_frag2.c snort-2.2.0.rose/src/ preprocessors/spp_frag2.c --- snort-2.2.0/src/preprocessors/spp_frag2.c Mon Oct 20 11:03:37 2003 +++ snort-2.2.0.rose/src/preprocessors/spp_frag2.c Fri Apr 9 22:58:18 2004 @@ -134,6 +134,8 @@ char state_protection; + int gap_threshold; /* alerting threshold for max gap (rose attack) */ + SPMemControl frag_sp_data; /* self preservation data */ } Frag2Data; @@ -175,6 +177,7 @@ u_int8_t complete; u_int8_t teardrop; u_int8_t outoforder; + int max_gap; } CompletionData; typedef struct _F2Emergency @@ -343,8 +346,14 @@ else if(frag->offset > next_offset) { DEBUG_WRAP(DebugMessage(DEBUG_FRAG2, "Holes in completion check... (%u > %u) ", - frag->offset, next_offset);); + frag->offset, next_offset);); comp->complete = 0; + + if(comp->max_gap < (frag->offset - next_offset)) + { + comp->max_gap = frag->offset - next_offset; + printf("recomputing maxgap! size: %d ", comp->max_gap); + } } return; @@ -468,6 +477,7 @@ f2data.frag_sp_data.mem_usage = 0; f2data.frag_sp_data.fault_count = 0; f2data.frag_sp_data.sp_func = Frag2SelfPreserve; + f2data.gap_threshold = 0; if(!pv.quiet_flag) { @@ -483,6 +493,7 @@ LogMessage(" Self preservation period: %d ", f2data.sp_period); LogMessage(" Suspend threshold: %d ", f2data.suspend_threshold); LogMessage(" Suspend period: %d ", f2data.suspend_period); + LogMessage(" Max frag gap threshold: %d ", f2data.gap_threshold); } @@ -647,7 +658,13 @@ { f2data.state_protection = 1; } - + else if(!strcasecmp(stoks[0], "gap_threshold")) + { + if(isdigit((int)stoks[1][0])) + { + f2data.gap_threshold = atoi(stoks[1]); + } + } mSplitFree(&stoks, s_toks); @@ -674,6 +691,7 @@ LogMessage(" Self preservation period: %d ", f2data.sp_period); LogMessage(" Suspend threshold: %d ", f2data.suspend_threshold); LogMessage(" Suspend period: %d ", f2data.suspend_period); + LogMessage(" Max frag gap threshold: %d ", f2data.gap_threshold); } } @@ -876,6 +894,7 @@ compdata.complete = 0; compdata.teardrop = 0; compdata.outoforder = 0; + compdata.max_gap = 0; if(FragIsComplete(ft, &compdata)) { @@ -903,7 +922,23 @@ } RebuildFrag(ft, p); - } else { + } + else + { + if(((ft->frag_flags & (FRAG_GOT_FIRST|FRAG_GOT_LAST)) = = + (FRAG_GOT_FIRST|FRAG_GOT_LAST)) && + (f2data.gap_threshold != 0) && + (compdata.max_gap > 0) && + (compdata.max_gap > f2data.gap_threshold)) + { + SetEvent(&event, GENERATOR_SPP_FRAG2, + FRAG2_ROSE_ATTACK, 1, 0, 5, 0); + CallAlertFuncs(p, FRAG2_ROSE_STR, NULL, &event); + CallLogFuncs(p, FRAG2_ROSE_STR, NULL, &event); + ft->alerted = 1; + DisableDetect(p); + } + DEBUG_WRAP(DebugMessage(DEBUG_FRAG2, "Fragment not complete ");); } }
If you would like to enable snort-2.2.x to use this patch, you are only going to be able to:
- Compile Snort from source code
- Use it on a Linux or BSD sensor
Next, to build this patch, simply follow the instructions. Create a directory for the patch file and the Snort source code.
Root# pwd /opt/ROSE Root# ls Rose_attack.patch snort-2.2.x.tar.gz
Extract the Snort code and, using the patch command, apply the rose attack file.
Root# tar xvfz snort-2.2.x.tar.gz Root# patch -p < Rose_attack.patch
If you get no errors, simply compile Snort as you would normally.
Finally, add the following extra options to your snort.conf file:
# Snort.conf file example Preprocessor frag2: gap_threshold 32768
These options are the default number of bytes that are in the proof-of-concept code outlining the use of the rose attack. You can change or adjust the gap_threshold value as you want, however, as this attack has yet to be seen in the wild. There is little need to adjust this setting.
See Also
The author of the rose attack proof-of-concept code and the creator of the attack, available at http://digital.net/~gandalf/Rose_Frag_Attack_Explained.htm
Snort-devel mailing list
Detecting and Normalizing HTTP Traffic
|