From: Victor Julien Date: Mon, 10 Dec 2012 17:34:11 +0000 (+0100) Subject: ipv6: add option to detect HOP/DST headers with only padding. Detect unknown DST... X-Git-Tag: suricata-1.4~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=150b0c5ae040b5bb31940f332f0b1eb1af66268b;p=thirdparty%2Fsuricata.git ipv6: add option to detect HOP/DST headers with only padding. Detect unknown DST/HOP opts. --- diff --git a/rules/decoder-events.rules b/rules/decoder-events.rules index 6ced87942f..ab4ac0ddce 100644 --- a/rules/decoder-events.rules +++ b/rules/decoder-events.rules @@ -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 diff --git a/src/decode-events.h b/src/decode-events.h index f03b77ffd5..c03a0af649 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -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 */ diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index 23b6fb6c40..b45f16f0d7 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -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; diff --git a/src/detect-engine-event.h b/src/detect-engine-event.h index 5a4a56a76e..c2a9cff87e 100644 --- a/src/detect-engine-event.h +++ b/src/detect-engine-event.h @@ -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, },