]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode/teredo: implement port support
authorVictor Julien <victor@inliniac.net>
Mon, 23 Mar 2020 10:06:55 +0000 (11:06 +0100)
committerVictor Julien <victor@inliniac.net>
Sat, 28 Mar 2020 17:03:31 +0000 (18:03 +0100)
Implement support for limiting Teredo detection and decoding to specific
UDP ports, with 3544 as the default.

If no ports are specified, the old behaviour of detecting/decoding on any
port is still in place. This can also be forced by specifying 'any' as the
port setting.

doc/userguide/configuration/suricata-yaml.rst
src/decode-teredo.c
src/decode-teredo.h
src/decode-udp.c
suricata.yaml.in

index 70a6effdfd64c4a6b2ace47c118b176f889a5a0d..e3d82350a2d248b2177e7634ca8608c0b345cb16 100644 (file)
@@ -2246,7 +2246,13 @@ The Teredo decoder can be disabled. It is enabled by default.
       # it will sometimes detect non-teredo as teredo.
       teredo:
         enabled: true
+        # ports to look for Teredo. Max 4 ports. If no ports are given, or
+        # the value is set to 'any', Teredo detection runs on _all_ UDP packets.
+        ports: $TEREDO_PORTS # syntax: '[3544, 1234]'
 
+Using this default configuration, Teredo detection will run on UDP port
+3544. If the `ports` parameter is missing, or set to `any`, all ports will be
+inspected for possible presence of Teredo.
 
 Advanced Options
 ----------------
index 93e9711c5198dc0bb87ae3423c7ef6537904cd9a..4b8c648a16d5b6763897445ca0cbbf70d49b46a8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Open Information Security Foundation
+/* Copyright (C) 2012-2020 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
 #include "decode-teredo.h"
 #include "util-debug.h"
 #include "conf.h"
+#include "detect-engine-port.h"
 
-#define TEREDO_ORIG_INDICATION_LENGTH    8
+#define TEREDO_ORIG_INDICATION_LENGTH   8
 
 static bool g_teredo_enabled = true;
+static int g_teredo_ports[4] = { -1, -1, -1, -1 };
+static int g_teredo_ports_cnt = 0;
+static bool g_teredo_ports_any = true;
+
+bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp)
+{
+    SCLogDebug("ports %u->%u ports %d %d %d %d", sp, dp,
+            g_teredo_ports[0], g_teredo_ports[1],
+            g_teredo_ports[2], g_teredo_ports[3]);
+
+    if (g_teredo_enabled) {
+        /* no port config means we are enabled for all ports */
+        if (g_teredo_ports_any) {
+            return true;
+        }
+
+        for (int i = 0; i < g_teredo_ports_cnt; i++) {
+            if (g_teredo_ports[i] == -1)
+                return false;
+            const int port = g_teredo_ports[i];
+            if (port == (const int)sp ||
+                port == (const int)dp)
+                return true;
+        }
+    }
+    return false;
+}
+
+static void DecodeTeredoConfigPorts(const char *pstr)
+{
+    SCLogDebug("parsing \'%s\'", pstr);
+
+    if (strcmp(pstr, "any") == 0) {
+        g_teredo_ports_any = true;
+        return;
+    }
+
+    DetectPort *head = NULL;
+    DetectPortParse(NULL, &head, pstr);
+
+    g_teredo_ports_any = false;
+    g_teredo_ports_cnt = 0;
+    for (DetectPort *p = head; p != NULL; p = p->next) {
+        if (g_teredo_ports_cnt >= 4) {
+            SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY,
+                    "only 4 Teredo ports can be defined");
+            break;
+        }
+        g_teredo_ports[g_teredo_ports_cnt++] = (int)p->port;
+    }
+    DetectPortCleanupList(NULL, head);
+}
 
 void DecodeTeredoConfig(void)
 {
@@ -53,6 +106,12 @@ void DecodeTeredoConfig(void)
             g_teredo_enabled = false;
         }
     }
+    if (g_teredo_enabled) {
+        ConfNode *node = ConfGetNode("decoder.teredo.ports");
+        if (node && node->val) {
+            DecodeTeredoConfigPorts(node->val);
+        }
+    }
 }
 
 /**
index 1c414f19bfb7d9c9b6f559e52dfaf12aa82881ca..bbd9dc816383c47ab7bcf6311f310b3c6c3f8982 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Open Information Security Foundation
+/* Copyright (C) 2012-2020 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -21,5 +21,6 @@
 int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
                  const uint8_t *pkt, uint16_t len);
 void DecodeTeredoConfig(void);
+bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp);
 
 #endif
index 225a15daa7577fb24de9f96a5e4db763ba8fd5a3..436b10a132f506648b22173b14953f27d984c2bd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
+/* Copyright (C) 2007-2020 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -84,7 +84,8 @@ int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
     SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "",
         UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len);
 
-    if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len) == TM_ECODE_OK)) {
+    if (DecodeTeredoEnabledForPort(p->sp, p->dp) &&
+            likely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len) == TM_ECODE_OK)) {
         /* Here we have a Teredo packet and don't need to handle app
          * layer */
         FlowSetupPacket(p);
index 4890729498765fef320b96d4563822d25c090f66..628a3c0d47e6558a88251cf47bc316c126812dd6 100644 (file)
@@ -45,6 +45,7 @@ vars:
     FILE_DATA_PORTS: "[$HTTP_PORTS,110,143]"
     FTP_PORTS: 21
     VXLAN_PORTS: 4789
+    TEREDO_PORTS: 3544
 
 ##
 ## Step 2: Select outputs to enable
@@ -1328,6 +1329,10 @@ decoder:
   # as it will sometimes detect non-teredo as teredo.
   teredo:
     enabled: true
+    # ports to look for Teredo. Max 4 ports. If no ports are given, or
+    # the value is set to 'any', Teredo detection runs on _all_ UDP packets.
+    ports: $TEREDO_PORTS # syntax: '[3544, 1234]' or '3533' or 'any'.
+
   # VXLAN decoder is assigned to up to 4 UDP ports. By default only the
   # IANA assigned port 4789 is enabled.
   vxlan: