[Snort-devel] Decoder: 'DECODE_IPV6_TRUNCATED' alert on DNS query (false positive)

Victor Roemer vroemer at ...402...
Fri Sep 6 11:30:17 EDT 2013


Thanks Bram,

I agree that we should handle this better; I'll open a bug to track this
issue.


On Fri, Sep 6, 2013 at 8:32 AM, Bram <bram-fabeg at ...3414...> wrote:

> Hi,
>
>
> The attached dump is a dns query (over IPv4) which generates the alert
> 'DECODE_IPV6_TRUNCATED'.
> This is unexpected and feels like a false positive.
>
>
> Config:
>         dynamicpreprocessor directory /usr/lib/snort_**
> dynamicpreprocessor/
>
>         output log_null
>
>         output alert_fast: stdout
>
>         alert ( msg:"DECODE_IPV6_TRUNCATED"; sid:273; gid:116; rev:1;
> metadata:rule-type decode; )
>
>
> Running:
>         $ snort -v -l /var/log -c /etc/ips/snort.conf --daq-dir /lib/daq/
>   -r /tmp/116_273.cap 2>&1  | grep '116:'
>         07/16-14:38:58.547143  [**] [116:273:1] (snort decoder) WARNING:
> IPV6 truncated header [**] [Priority: 0] {UDP} 10.10.1.1:3544 ->
> 8.8.8.8:53
>
> Version:
>         $ snort -V
>
>            ,,_     -*> Snort! <*-
>           o"  )~   Version 2.9.5.3 GRE (Build 132)
>            ''''    By Martin Roesch & The Snort Team:
> http://www.snort.org/snort/**snort-team<http://www.snort.org/snort/snort-team>
>                    Copyright (C) 1998-2013 Sourcefire, Inc., et al.
>                    Using libpcap version 1.3.0
>                    Using PCRE version: 8.32 2012-11-30
>                    Using ZLIB version: 1.2.8
>
>
> Running it under gdb and breaking on 'DecodeIPV6' shows:
>         Breakpoint 2, DecodeIPV6 (pkt=0x8f914a2 "mX\001", len=35,
> p=0x8765fe0 <s_packet>) at decode.c:3672
>         3672    in decode.c
>         (gdb) bt
>         #0  DecodeIPV6 (pkt=0x8f914a2 "mX\001", len=35, p=0x8765fe0
> <s_packet>) at decode.c:3672
>         #1  0x080541bf in DecodeTeredo (pkt=0x8f914a2 "mX\001", len=35,
> p=0x8765fe0 <s_packet>) at decode.c:4234
>         #2  0x08055852 in DecodeUDP (pkt=0x8f9149a "\r\330", len=43,
> p=0x8765fe0 <s_packet>) at decode.c:5111
>         #3  0x080506d5 in DecodeIPv4Proto (proto=17 '\021', pkt=0x8f9149a
> "\r\330", len=43, p=0x8765fe0 <s_packet>) at decode.c:2198
>         #4  0x08051293 in DecodeIP (pkt=0x8f91486 "E", len=63, p=0x8765fe0
> <s_packet>) at decode.c:2585
>         #5  0x0804dfee in DecodeEthPkt (p=0x8765fe0 <s_packet>,
> pkthdr=0xbffff880, pkt=0x8f91478 "\030\357cc\350`h\005\312\b\**353\b\b")
> at decode.c:709
>         #6  0x08077d6c in ProcessPacket (p=0x8765fe0 <s_packet>,
> pkthdr=0xbffff880, pkt=0x8f91478 "\030\357cc\350`h\005\312\b\**353\b\b",
> ft=0x0) at snort.c:1800
>         #7  0x08077a95 in PacketCallback (user=0x0, pkthdr=0xbffff880,
> pkt=0x8f91478 "\030\357cc\350`h\005\312\b\**353\b\b") at snort.c:1685
>         ...
>
> Looking at the code shows why it is attempting to parse the packet as IPv6:
>
> It seems to assume that this is a 'Teredo' connection/packe (RFC 4380).
> That is: an IPv6 packet tunneled over IPv4 UDP.
>
>
> The conditions in which it makes this assumption:
> * the UDP data is at least 2 bytes
> * the first 4 bits of data is '6'
>
> When the conditions are true then it checks:
>         if (ScDeepTeredoInspection() && (p->sp != TEREDO_PORT) && (p->dp
> != TEREDO_PORT))
>             p->packet_flags |= PKT_UNSURE_ENCAP;
>
> => 'PKT_UNSURE_ENCAP' is set when:
> * 'enable_deep_teredo_**inspection' is included in the config
> * the source port is not port 3544
> * the desination port is not port 3544
>
> The 'PKT_UNSURE_ENCAP' flag is checked in DecodeIPV6, relevant code:
>     if(len < IP6_HDR_LEN)
>     {
>         if ((p->packet_flags & PKT_UNSURE_ENCAP) == 0)
>             DecoderEvent(p, DECODE_IPV6_TRUNCATED,
> DECODE_IPV6_TRUNCATED_STR,
>                          1, 1);
>
>         goto decodeipv6_fail;
>     }
>
>
> Looking at the config: 'enable_deep_teredo_**inspection' is not set
>
> Looking at the dump:
> * the soucre port is set to 3544,
> * the first 4 bits of the udp data is 6.
>
>
> This source port was randomly chosen by the dns client.
> The first 4 bits of the udp data happens to be 6 because the transaction
> id (also chosen by the dns client) is set to 0x6d58.
> The total length of the udp data is 35 bytes.
>
> => 'IP6_HDR_LEN' is set to 40 bytes.
>
> For larger DNS query the following happens:
> * it first checks the length (OK)
> * it checks the first 4 bits to see if these are set to 6 (OK - same check
> as in DecodeTeredo)
> * it checks 'p->family' (not sure about this one)
> * it compares the payload length with the length set in the IPv6 header,
> for this it uses the first part of the DNS flags. (alert is given when the
> length in the header is larger then the UDP length)
> * it calls 'CheckTeredoPrefix' to check the data, when this fails it
> aborts the IPv6 checking without generating an alert
>
>
> This means that the false positives are limited to DNS queries:
> * which are smaller then 40 bytes
> * which use a port 3544
> * which use a transaction id that starts with 0x6...
>
>
> For larger DNS queries false positives may also be triggered depending on
> the flags in the dns query.. (no attempt was made to reproduce this)
>
>
> Best regards,
>
> Bram
>
>
> ------------------------------**------------------------------**----
> This message was sent using IMP, the Internet Messaging Program.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.snort.org/pipermail/snort-devel/attachments/20130906/34400d2f/attachment.html>


More information about the Snort-devel mailing list