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

@ -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 */

@ -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:

@ -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

@ -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 */

Loading…
Cancel
Save