]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
streaming: randomize chunk size
authorEric Leblond <eric@regit.org>
Wed, 27 Mar 2013 13:08:37 +0000 (14:08 +0100)
committerVictor Julien <victor@inliniac.net>
Fri, 19 Apr 2013 10:16:04 +0000 (12:16 +0200)
By randomizing chunk size around the choosen value, it is possible
to escape some evasion technics that are using the fact they know
chunk size to split the attack at the correct place.
This patch activates randomization by default and set the random
interval to chunk size value +- 10%.

src/stream-tcp.c
suricata.yaml.in

index d324cc123f8387449ed5892cf287a08796c8fdee..e29637512f06b1e2c390d71501084e99569050df 100644 (file)
@@ -331,6 +331,7 @@ void StreamTcpSessionPoolCleanup(void *s)
 void StreamTcpInitConfig(char quiet)
 {
     intmax_t value = 0;
+    uint16_t rdrange = 10;
 
     SCLogDebug("Initializing Stream");
 
@@ -477,6 +478,33 @@ void StreamTcpInitConfig(char quiet)
         SCLogInfo("stream.reassembly \"depth\": %"PRIu32"", stream_config.reassembly_depth);
     }
 
+    int randomize = 0;
+    if ((ConfGetBool("stream.reassembly.randomize-chunk-size", &randomize)) == 0) {
+        /* randomize by default if value not set */
+        randomize = 1;
+    }
+
+    if (randomize) {
+        char *temp_rdrange;
+        if (ConfGet("stream.reassembly.randomize-chunk-range",
+                    &temp_rdrange) == 1) {
+            if (ParseSizeStringU16(temp_rdrange, &rdrange) < 0) {
+                SCLogError(SC_ERR_SIZE_PARSE, "Error parsing "
+                        "stream.reassembly.randomize-chunk-range "
+                        "from conf file - %s.  Killing engine",
+                        temp_rdrange);
+                exit(EXIT_FAILURE);
+            } else if (rdrange >= 100) {
+                SCLogError(SC_ERR_INVALID_VALUE,
+                           "stream.reassembly.randomize-chunk-range "
+                           "must be lower than 100");
+                exit(EXIT_FAILURE);
+            }
+        }
+        /* set a "random" seed */
+        srandom(time(0));
+    }
+
     char *temp_stream_reassembly_toserver_chunk_size_str;
     if (ConfGet("stream.reassembly.toserver-chunk-size",
                 &temp_stream_reassembly_toserver_chunk_size_str) == 1) {
@@ -492,6 +520,12 @@ void StreamTcpInitConfig(char quiet)
         stream_config.reassembly_toserver_chunk_size =
             STREAMTCP_DEFAULT_TOSERVER_CHUNK_SIZE;
     }
+
+    if (randomize) {
+        stream_config.reassembly_toserver_chunk_size +=
+            (int) (stream_config.reassembly_toserver_chunk_size *
+                   (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100);
+    }
     StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER,
             stream_config.reassembly_toserver_chunk_size);
 
@@ -510,6 +544,13 @@ void StreamTcpInitConfig(char quiet)
         stream_config.reassembly_toclient_chunk_size =
             STREAMTCP_DEFAULT_TOCLIENT_CHUNK_SIZE;
     }
+
+    if (randomize) {
+        stream_config.reassembly_toclient_chunk_size +=
+            (int) (stream_config.reassembly_toclient_chunk_size *
+                   (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100);
+    }
+
     StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT,
             stream_config.reassembly_toclient_chunk_size);
 
index c73e7901a578df937cf7804154a1f2fed8501e9b..ebf09c6bb1218b234b7498c1997d5d5cd36ccbb4 100644 (file)
@@ -598,6 +598,13 @@ flow-timeouts:
 #                               # this size.  Can be specified in kb, mb,
 #                               # gb.  Just a number indicates it's in bytes.
 #                               # The max acceptable size is 4024 bytes.
+#     randomize-chunk-size: yes # Take a random value for chunk size around the specified value.
+#                               # This lower the risk of some evasion technics but could lead
+#                               # detection change between runs. It is set to 'yes' by default.
+#     randomize-chunk-range: 10 # If randomize-chunk-size is active, the value of chunk-size is
+#                               # a random value between (1 - randomize-chunk-range/100)*randomize-chunk-size
+#                               # and (1 + randomize-chunk-range/100)*randomize-chunk-size. Default value
+#                               # of randomize-chunk-range is 10.
 
 stream:
   memcap: 32mb
@@ -608,6 +615,8 @@ stream:
     depth: 1mb                  # reassemble 1mb into a stream
     toserver-chunk-size: 2560
     toclient-chunk-size: 2560
+    randomize-chunk-size: yes
+    #randomize-chunk-range: 10
 
 # Host table:
 #