[Oisf-devel] Problems with UDP fragments and latest (GIT) Suricata.

Nikolay Denev ndenev at gmail.com
Tue Sep 20 14:26:27 UTC 2011


Hello,

While trying to catch a bug regarding pass rules in suricata with the help of Peter Manev,
I've upgraded to the GIT version and found a new in it regarding fragment handling.

Immediately when I switched to the GIT version I started to receive alerts about snmp traps from the following rule:

alert udp $EXTERNAL_NET any -> $HOME_NET 162 (msg:"GPL SNMP trap udp"; classtype:attempted-recon; reference:bugtraq,4088; reference:bugtraq,4089; reference:bugtraq,4132; reference:cve,2002-0012; reference:cve,2002-0013; sid:1419; rev:9;)

And here is the alert :

[**] [1:1419:9] GPL SNMP trap udp [**] [Classification: Attempted Information Leak] [Priority: 2] {UDP} XX.XX.64.3:0 -> YY.YY.47.8:0

 You can notice that there are no ports in the alert, but the rule has the destination port specified.
When I investigated further it turned out that this alert was triggered by fragments from fragmented UDP packets from port 53 (DNSSEC UDP packets over 1500 bytes).

I even recored one of these fragmented packets and I'm able to trigger this rule every time with it. The original suricata version from the FreeBSD ports that I used (1.0.3) do not generate alerts for these fragments.

While looking at the code I noticed some recent changes regarding iponly rules and found this commit :

https://redmine.openinfosecfoundation.org/projects/suricata/repository/revisions/e13181496c435f5a6b401faf7d40298608d3314c/diff/src/detect-engine-iponly.c

In the code fragment from this commit :

                    if (DetectProtoContainsProto(&s->proto, IP_GET_IPPROTO(p)) == 0) {
                        SCLogDebug("proto didn't match");
                        continue;
                    }

                    /* check the source & dst port in the sig */
                    if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
                        if (!(s->flags & SIG_FLAG_DP_ANY)) {
                            DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp);
                            if (dport == NULL) {
                                SCLogDebug("dport didn't match.");
                                continue;
                            }
                        }
                        if (!(s->flags & SIG_FLAG_SP_ANY)) {
                            DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp);
                            if (sport == NULL) {
                                SCLogDebug("sport didn't match.");
                                continue;
                            }
                        }
                    }

IP_GET_IPPROTO() properly returns the protocol (17 for UDP), but the next check agains
p->proto does not work as p->proto is zero.

It seems that p->proto should be set to IPPROTO_UDP in decode-udp.c::DecodeUDPPacket(),
but in my testing with only one recorded fragment in pcap format, we never get there 
because the packet probably can't be reassembled.

I'm still digging and adding debug printfs to understand the code better and see where the problem is
but I decided to share what I have so far in case some more familiar with the code has idea why this is happening.

To me it seems like that the fragment is being processed instead of being dropped.

Regards,
Nikolay
 


More information about the Oisf-devel mailing list