ipv6: more robust ipv6 exthdr handling

Skip past Shim6, HIP and Mobility header.

Detect data after 'none' header.
    decode-event:ipv6.data_after_none_header;
pull/1088/head
Victor Julien 12 years ago
parent 938602c55e
commit bbcdb657da

@ -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;) 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 # 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;) 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 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 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 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 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;) 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

@ -82,6 +82,7 @@ enum {
IPV6_EXTHDR_RH_TYPE_0, /**< RH 0 is deprecated as per rfc5095 */ IPV6_EXTHDR_RH_TYPE_0, /**< RH 0 is deprecated as per rfc5095 */
IPV6_EXTHDR_ZERO_LEN_PADN, /**< padN w/o data (0 len) */ IPV6_EXTHDR_ZERO_LEN_PADN, /**< padN w/o data (0 len) */
IPV6_FH_NON_ZERO_RES_FIELD, /**< reserved field not zero */ 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 */ IPV6_WITH_ICMPV4, /**< IPv6 packet with ICMPv4 header */

@ -107,7 +107,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
SCEnter(); SCEnter();
uint8_t *orig_pkt = pkt; uint8_t *orig_pkt = pkt;
uint8_t nh; uint8_t nh = 0; /* careful, 0 is actually a real type */
uint16_t hdrextlen; uint16_t hdrextlen;
uint16_t plen; uint16_t plen;
char dstopts = 0; char dstopts = 0;
@ -118,6 +118,12 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
while(1) 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 */ if (plen < 2) { /* minimal needed in a hdr */
SCReturn; SCReturn;
} }
@ -535,12 +541,26 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
IPV6_SET_L4PROTO(p,nh); IPV6_SET_L4PROTO(p,nh);
DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq); DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq);
SCReturn; SCReturn;
/* none, last header */
case IPPROTO_NONE: case IPPROTO_NONE:
IPV6_SET_L4PROTO(p,nh); IPV6_SET_L4PROTO(p,nh);
SCReturn; SCReturn;
case IPPROTO_ICMP: case IPPROTO_ICMP:
ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4); ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4);
SCReturn; 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: default:
IPV6_SET_L4PROTO(p,nh); IPV6_SET_L4PROTO(p,nh);
SCReturn; SCReturn;
@ -633,6 +653,9 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
case IPPROTO_DSTOPTS: case IPPROTO_DSTOPTS:
case IPPROTO_AH: case IPPROTO_AH:
case IPPROTO_ESP: 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); DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
break; break;
case IPPROTO_ICMP: case IPPROTO_ICMP:

@ -903,6 +903,19 @@ void AddressDebugPrint(Address *);
#define IPPROTO_SCTP 132 #define IPPROTO_SCTP 132
#endif #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 */ /* pcap provides this, but we don't want to depend on libpcap */
#ifndef DLT_EN10MB #ifndef DLT_EN10MB
#define DLT_EN10MB 1 #define DLT_EN10MB 1

@ -92,6 +92,7 @@ struct DetectEngineEvents_ {
{ "ipv6.rh_type_0", IPV6_EXTHDR_RH_TYPE_0, }, { "ipv6.rh_type_0", IPV6_EXTHDR_RH_TYPE_0, },
{ "ipv6.zero_len_padn", IPV6_EXTHDR_ZERO_LEN_PADN, }, { "ipv6.zero_len_padn", IPV6_EXTHDR_ZERO_LEN_PADN, },
{ "ipv6.fh_non_zero_reserved_field", IPV6_FH_NON_ZERO_RES_FIELD, }, { "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, }, { "ipv6.icmpv4", IPV6_WITH_ICMPV4, },
/* TCP EVENTS */ /* TCP EVENTS */

Loading…
Cancel
Save