]> 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)
committerJeff Lucovsky <jeff@lucovsky.org>
Sun, 5 Apr 2020 19:00:15 +0000 (15:00 -0400)
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.

(cherry picked from commit e97cdb48f3e32e8d76aaa2f7325a1a67e245be8e)

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

index bb24efa5f382fee54dabc0426fb66259d7f229be..3231bf3c5f910c364749c247599b9fc0a7e7ff69 100644 (file)
@@ -2326,7 +2326,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 cb9602c85e6f2644e5bd8492badead30fc1b4371..fd667fb76ad379219116a065ab955973b501b68a 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 10e596d5cd8595454dd31731ae8eae5d4156d41b..37bb9acedd0f3d23cf72c81d50a9d9a5c3dfc817 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, PacketQueue *pq);
 void DecodeTeredoConfig(void);
+bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp);
 
 #endif
index 551f8298f51ddcd8d9e78ab776303fb3c090b510..c3a8ebbfe15f498de94dd1c2d2b3720d76120f40 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, pq) == TM_ECODE_OK)) {
+    if (DecodeTeredoEnabledForPort(p->sp, p->dp) &&
+            likely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == TM_ECODE_OK)) {
         /* Here we have a Teredo packet and don't need to handle app
          * layer */
         FlowSetupPacket(p);
index 96b9b0b0d3282b355e6b8dc5aeb6629e5a41c709..f0f8ce035f82bb67f99be253ddef60229e861019 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
@@ -1333,6 +1334,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: