According to the image above, certain types(like type=9/code=0, router advertisement) of ICMPv4 do not use expansion headers.
But now due to fixed header recognition length(8), Cur Hop Limit ~ Routetr Lifetime field cannot be detected in Suricata.
So I changed the protocol type of the rule Header ICMP to IP, but it was also recognized by ICMP finally I couldn’t detect it anyway.
ICMPv6 was not an issue because it recognized the variable header length for the six types specified in RFC 4884.
How can I detect ICMPv4 without extension header first four bytes Body payload?
And I also attach the test packet. icmpv4_mobile_ip_advert.pcap (100 Bytes)
I checked all the types of ICMPv4 notified to the IANA(https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml), It has been found that it is extremely rare to treat ICMPv4 headers only 4 bytes in NIDS. Because most of them(after 4 bytes) are unused field or id or sequence number.
So, I found an example after much consideration. But I’m not sure if this is a good example for the bug above. The reason I’m not sure is that Snort, which is specifically classifed for each ICMPv4 type, does not detect this field.
Anyway the ICMPv4 type I want to talk about is Redirect message(ICMPv4 type is 5).
Suricata cannot detect the subsequent Gateway IP field because the ICMPv4 header is fixed at 8 bytes (although the reason is unknown, Snort also recognizes it as 8 bytes for that type).
I am not sure if this is appropriate for the example, but I will attach the packet first. icmpv4_redirect.pcap (110 Bytes)
I’m thinking of adding a sticky buffer icmpv4.hdr to provide access to the ICMP v4 header (we already have a sticky buffer for the ICMPv6 header.
This would allow a rule like:
alert icmp any any -> any any (msg:"icmp hdr test"; icmpv4.hdr; content:"|0a 0e 50 54 42|"; sid:1; rev:1;)
The sticky buffer provides access to the complete IP header; here’s the header from the mobile advertisement pcap header (as displayed in gdb with x/16b data – data points to the beginning of the ICMP header)
Hello @Jeff_Lucovsky! Thanks for your creative replying.
I understood your response. To sum up what you said, You mean ICMPv4’s header length is fixed at 8 as it is in the current Suricata version, but your team add a sticky buffer option(icmpv6.hdr) like icmpv6, right?
This seems to be a pretty good way of not affecting the existing ICMPv4 rules.
This is not what I exactly thought, but it would be nice to add this option to the existing Suricata.
And there’s one more question about your example rules.
I understand that the icmpv6.hdr option is precisely limited to ICMPv6 headers.
As with the source code and Suricata 6.0.0 traffic test.
But Your sample rule extends beyond the header area to the body (|0e 50 54 42|) and is being detected in the buffer.
As far as I know, after |0a|, it’s not right to be detected.
So I’d like to ask you if I’m mistaken or if the icmpv4.hdr option works differently than icmpv6.hdr.
Both icmpv6.hdr and icmpv4.hdr (proposed) will return data, starting from the beginning of the ICMP section.
The v6 version returns the first 8 bytes while the v4 version will return the first N bytes, where N matches the length of the ICMP message type. The “length” for the router advertisement is variable and computed per the RFC.
Many v4 messages are 8 (or less) bytes and a few are longer (timestamp related, router advertisement).
“Body” and “header” are synonymous with the (proposed) addition. I’ll be posting a PR soon so you can view the actual changes and provide an opportunity to try these out in your environment.
I understood your meaning. It means yor’re going to extend the length of the header and decode it, and detect it with the ipv4.hdr option.
Okay. I got it. Let me ask you one more question.
You say “The v6 version returns the first 8 bytes”.
So all ICMPv6 now recognize 8 bytes of header length regardless of type?
When I looked at the decode-icmpv6.c source code, it looked at only 6 type defined in RFC 4884 as 8 and the rest as 4(if full_hdr flag set FALSE).
Will this also add a variable header length later like icmpv4 decode does?