diff --git a/rules/decoder-events.rules b/rules/decoder-events.rules index 0e7d2c68f6..779d6ed30e 100644 --- a/rules/decoder-events.rules +++ b/rules/decoder-events.rules @@ -41,6 +41,8 @@ alert ipv6 any any -> any any (msg:"SURICATA RH Type 0"; decode-event:ipv6.rh_ty alert ipv6 any any -> any any (msg:"SURICATA zero length padN option"; decode-event:ipv6.zero_len_padn; sid:2200094; rev:1;) # Frag Header 'length' field is reserved and should be 0 alert ipv6 any any -> any any (msg:"SURICATA reserved field in Frag Header not zero"; decode-event:ipv6.fh_non_zero_reserved_field; sid:2200095; rev:1;) +# Data after the 'none' header (59) is suspicious. +alert ipv6 any any -> any any (msg:"SURICATA data after none (59) header"; decode-event:ipv6.data_after_none_header; sid:2200096; rev:1;) alert ipv6 any any -> any any (msg:"SURICATA IPv6 with ICMPv4 header"; decode-event:ipv6.icmpv4; sid:2200090; 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;) @@ -112,5 +114,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 2200096 +# next sid is 2200097 diff --git a/src/decode-events.h b/src/decode-events.h index 8c47af1799..1eceb8af7a 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -82,6 +82,7 @@ enum { IPV6_EXTHDR_RH_TYPE_0, /**< RH 0 is deprecated as per rfc5095 */ IPV6_EXTHDR_ZERO_LEN_PADN, /**< padN w/o data (0 len) */ IPV6_FH_NON_ZERO_RES_FIELD, /**< reserved field not zero */ + IPV6_DATA_AFTER_NONE_HEADER, /**< data after 'none' (59) header */ IPV6_WITH_ICMPV4, /**< IPv6 packet with ICMPv4 header */ diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index 099a7bfbc9..5424765f83 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -107,7 +107,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt SCEnter(); uint8_t *orig_pkt = pkt; - uint8_t nh; + uint8_t nh = 0; /* careful, 0 is actually a real type */ uint16_t hdrextlen; uint16_t plen; char dstopts = 0; @@ -118,6 +118,12 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt while(1) { + /* No upper layer, but we do have data. Suspicious. */ + if (nh == IPPROTO_NONE && plen > 0) { + ENGINE_SET_EVENT(p, IPV6_DATA_AFTER_NONE_HEADER); + SCReturn; + } + if (plen < 2) { /* minimal needed in a hdr */ SCReturn; } @@ -535,12 +541,26 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt IPV6_SET_L4PROTO(p,nh); DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq); SCReturn; + /* none, last header */ case IPPROTO_NONE: IPV6_SET_L4PROTO(p,nh); SCReturn; case IPPROTO_ICMP: ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4); SCReturn; + /* no parsing yet, just skip it */ + case IPPROTO_MH: + case IPPROTO_HIP: + case IPPROTO_SHIM6: + hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */ + if (hdrextlen > plen) { + ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); + SCReturn; + } + nh = *pkt; + pkt += hdrextlen; + plen -= hdrextlen; + break; default: IPV6_SET_L4PROTO(p,nh); SCReturn; @@ -633,6 +653,9 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u case IPPROTO_DSTOPTS: case IPPROTO_AH: case IPPROTO_ESP: + case IPPROTO_MH: + case IPPROTO_HIP: + case IPPROTO_SHIM6: DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); break; case IPPROTO_ICMP: diff --git a/src/decode.h b/src/decode.h index b5fa6cbb98..d99d3d4bea 100644 --- a/src/decode.h +++ b/src/decode.h @@ -903,6 +903,19 @@ void AddressDebugPrint(Address *); #define IPPROTO_SCTP 132 #endif +#ifndef IPPROTO_MH +#define IPPROTO_MH 135 +#endif + +/* Host Identity Protocol (rfc 5201) */ +#ifndef IPPROTO_HIP +#define IPPROTO_HIP 139 +#endif + +#ifndef IPPROTO_SHIM6 +#define IPPROTO_SHIM6 140 +#endif + /* pcap provides this, but we don't want to depend on libpcap */ #ifndef DLT_EN10MB #define DLT_EN10MB 1 diff --git a/src/detect-engine-event.h b/src/detect-engine-event.h index 8c55092253..288956ddf3 100644 --- a/src/detect-engine-event.h +++ b/src/detect-engine-event.h @@ -92,6 +92,7 @@ struct DetectEngineEvents_ { { "ipv6.rh_type_0", IPV6_EXTHDR_RH_TYPE_0, }, { "ipv6.zero_len_padn", IPV6_EXTHDR_ZERO_LEN_PADN, }, { "ipv6.fh_non_zero_reserved_field", IPV6_FH_NON_ZERO_RES_FIELD, }, + { "ipv6.data_after_none_header", IPV6_DATA_AFTER_NONE_HEADER, }, { "ipv6.icmpv4", IPV6_WITH_ICMPV4, }, /* TCP EVENTS */