]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ipv6: add option to detect HOP/DST headers with only padding. Detect unknown DST...
authorVictor Julien <victor@inliniac.net>
Mon, 10 Dec 2012 17:34:11 +0000 (18:34 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 10 Dec 2012 17:34:11 +0000 (18:34 +0100)
rules/decoder-events.rules
src/decode-events.h
src/decode-ipv6.c
src/detect-engine-event.h

index 6ced87942f39d7ba5ba941dda4b88496fb4eb966..ab4ac0ddcec92027638d155207eadffef5cae10a 100644 (file)
@@ -26,6 +26,14 @@ alert pkthdr any any -> any any (msg:"SURICATA IPv6 invalid option lenght in hea
 alert pkthdr any any -> any any (msg:"SURICATA IPv6 wrong IP version"; decode-event:ipv6.wrong_ip_version; sid:2200022; rev:1;)
 # RFC 4302 states the reserved field should be 0.
 alert pkthdr any any -> any any (msg:"SURICATA IPv6 AH reserved field not 0"; decode-event:ipv6.exthdr_ah_res_not_null; sid:2200081; rev:1;)
+# HOP option that we don't understand
+alert pkthdr any any -> any any (msg:"SURICATA IPv6 HOPOPTS unknown option"; decode-event:ipv6.hopopts_unknown_opt; sid:2200086; rev:1;)
+# HOP header with only padding, covert channel?
+alert pkthdr any any -> any any (msg:"SURICATA IPv6 HOPOPTS only padding"; decode-event:ipv6.hopopts_only_padding; sid:2200087; rev:1;)
+# DST option that we don't understand
+alert pkthdr any any -> any any (msg:"SURICATA IPv6 DSTOPTS unknown option"; decode-event:ipv6.dstopts_unknown_opt; sid:2200088; rev:1;)
+# DST header with only padding, covert channel?
+alert pkthdr any any -> any any (msg:"SURICATA IPv6 DSTOPTS only padding"; decode-event:ipv6.dstopts_only_padding; sid:2200089; rev:1;)
 alert pkthdr any any -> any any (msg:"SURICATA ICMPv4 packet too small"; decode-event:icmpv4.pkt_too_small; sid:2200023; rev:1;)
 alert pkthdr any any -> any any (msg:"SURICATA ICMPv4 unknown type"; decode-event:icmpv4.unknown_type; sid:2200024; rev:1;)
 alert pkthdr any any -> any any (msg:"SURICATA ICMPv4 unknown code"; decode-event:icmpv4.unknown_code; sid:2200025; rev:1;)
@@ -93,5 +101,5 @@ alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 invalid protocol"; d
 alert pkthdr any any -> any any (msg:"SURICATA IPv6-in-IPv6 packet too short"; decode-event:ipv6.ipv6_in_ipv6_too_small; sid:2200084; rev:1;)
 alert pkthdr any any -> any any (msg:"SURICATA IPv6-in-IPv6 invalid protocol"; decode-event:ipv6.ipv6_in_ipv6_wrong_version; sid:2200085; rev:1;)
 
-# next sid is 2200086
+# next sid is 2200090
 
index f03b77ffd52376f3ff00a7af0ee4c754dba9b30e..c03a0af6490ea601daf4c7e5bf8e2fcd701bf21e 100644 (file)
@@ -72,6 +72,11 @@ enum {
     IPV6_WRONG_IP_VER,              /**< wrong version in ipv6 */
     IPV6_EXTHDR_AH_RES_NOT_NULL,    /**< AH hdr reserved fields not null (rfc 4302) */
 
+    IPV6_HOPOPTS_UNKNOWN_OPT,       /**< unknown HOP opt */
+    IPV6_HOPOPTS_ONLY_PADDING,      /**< all options in HOP opts are padding */
+    IPV6_DSTOPTS_UNKNOWN_OPT,       /**< unknown DST opt */
+    IPV6_DSTOPTS_ONLY_PADDING,      /**< all options in DST opts are padding */
+
     /* TCP EVENTS */
     TCP_PKT_TOO_SMALL,              /**< tcp packet smaller than minimum size */
     TCP_HLEN_TOO_SMALL,             /**< tcp header smaller than minimum size */
index 23b6fb6c400d0b4a7e70fa2af99f82828f28ebf6..b45f16f0d7c1a2e77ab4f6e583cab7e98194cb85 100644 (file)
@@ -285,12 +285,15 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
                     break;
                 }
 /** \todo move into own function to loaded on demand */
+                uint16_t padn_cnt = 0;
+                uint16_t other_cnt = 0;
                 uint16_t offset = 0;
                 while(offset < optslen)
                 {
                     if (*ptr == IPV6OPT_PADN) /* PadN */
                     {
                         //printf("PadN option\n");
+                        padn_cnt++;
                     }
                     else if (*ptr == IPV6OPT_RA) /* RA */
                     {
@@ -300,6 +303,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
                         ra->ip6ra_value = ntohs(ra->ip6ra_value);
                         //printf("RA option: type %" PRIu32 " len %" PRIu32 " value %" PRIu32 "\n",
                         //    ra->ip6ra_type, ra->ip6ra_len, ra->ip6ra_value);
+                        other_cnt++;
                     }
                     else if (*ptr == IPV6OPT_JUMBO) /* Jumbo */
                     {
@@ -321,11 +325,26 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
                         //PrintInet(AF_INET6, (char *)&(hao->ip6hao_hoa),
                         //    addr_buf,sizeof(addr_buf));
                         //printf("home addr %s\n", addr_buf);
+                        other_cnt++;
+                    } else {
+                        if (nh == IPPROTO_HOPOPTS)
+                            ENGINE_SET_EVENT(p, IPV6_HOPOPTS_UNKNOWN_OPT);
+                        else
+                            ENGINE_SET_EVENT(p, IPV6_DSTOPTS_UNKNOWN_OPT);
+
+                        other_cnt++;
                     }
                     uint16_t optlen = (*(ptr + 1) + 2);
                     ptr += optlen; /* +2 for opt type and opt len fields */
                     offset += optlen;
                 }
+                /* flag packets that have only padding */
+                if (padn_cnt > 0 && other_cnt == 0) {
+                    if (nh == IPPROTO_HOPOPTS)
+                        ENGINE_SET_EVENT(p, IPV6_HOPOPTS_ONLY_PADDING);
+                    else
+                        ENGINE_SET_EVENT(p, IPV6_DSTOPTS_ONLY_PADDING);
+                }
 
                 nh = *pkt;
                 pkt += hdrextlen;
index 5a4a56a76e8c8ee1594d2667558eaadd080689d2..c2a9cff87e29bbb0178f60cc684d724e07c456d2 100644 (file)
@@ -65,6 +65,10 @@ struct DetectEngineEvents_ {
     { "ipv6.exthdr_invalid_optlen", IPV6_EXTHDR_INVALID_OPTLEN, },
     { "ipv6.wrong_ip_version", IPV6_WRONG_IP_VER, },
     { "ipv6.exthdr_ah_res_not_null", IPV6_EXTHDR_AH_RES_NOT_NULL, },
+    { "ipv6.hopopts_unknown_opt", IPV6_HOPOPTS_UNKNOWN_OPT, },
+    { "ipv6.hopopts_only_padding", IPV6_HOPOPTS_ONLY_PADDING, },
+    { "ipv6.dstopts_unknown_opt", IPV6_DSTOPTS_UNKNOWN_OPT, },
+    { "ipv6.dstopts_only_padding", IPV6_DSTOPTS_ONLY_PADDING, },
     { "icmpv4.pkt_too_small", ICMPV4_PKT_TOO_SMALL, },
     { "icmpv4.unknown_type", ICMPV4_UNKNOWN_TYPE, },
     { "icmpv4.unknown_code", ICMPV4_UNKNOWN_CODE, },