lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAKvVidR8TSopa=4Kvs4nKVLRGJf9hnkqFeAKkv-9o129p051qw@mail.gmail.com>
Date:   Thu, 21 Mar 2019 11:32:12 +0100
From:   Luca Moro <luca.moro@...acktiv.com>
To:     netdev@...r.kernel.org
Cc:     Nicolas Collignon <nicolas.collignon@...acktiv.com>,
        Eloi Vanderbeken <eloi.benoist-vanderbeken@...acktiv.com>,
        Corentin Bayet <corentin.bayet@...acktiv.com>
Subject: netfilter: missing correlation checks on icmp[v6] errors before
 applying IP_CT_RELATED

Hello,

During a review of OpenBSD Packet Filter, we discovered a minor
security issue that also impacts netfilter.

When handling ICMP[v6] errors that encapsulate the original IP
datagram, there is no correlation check between the inner and outer IP
layers.
So one can encapsulate an error with an inner layer matching a known
connection, while its outer layer is directed to a filtered host.
In this case the whole packet will be tagged with the IP_CT_RELATED flag.
This has various implications from a rule bypass (if a rule allows
related trafic), to a known state oracle.

Unfortunately, we could not find a real statement in a RFC on how this
case should be filtered.
The closest we found is RFC5927 (Section 4.3) but it is not very clear.

A possible fix would be to check that the inner IP source is the same
than the outer destination.

For information here is what OpenBSD applied:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf.c?rev=1.1081&content-type=text/x-cvsweb-markup
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/pf.c.diff?r1=1.1080&r2=1.1081&f=h

We are totally disposed to discuss the vulnerability and help in the fix.
If possible, we would also appreciate a citation for the discovery.

Here is the relevant code:

// /net/netfilter/nf_conntrack_proto_icmp.c

> icmp_error_message(struct nf_conn *tmpl, struct sk_buff *skb,
>            const struct nf_hook_state *state)
> {
>     // ...
>
>     /* Are they talking about one of our connections? */
>     if (!nf_ct_get_tuplepr(skb,
>                    skb_network_offset(skb) + ip_hdrlen(skb)
>                                + sizeof(struct icmphdr),
>                    PF_INET, state->net, &origtuple)) {
>         pr_debug("icmp_error_message: failed to get tuple\n");
>         return -NF_ACCEPT;
>     }
>
>     /* rcu_read_lock()ed by nf_hook_thresh */
>     innerproto = __nf_ct_l4proto_find(origtuple.dst.protonum);
>
>     /* Ordinarily, we'd expect the inverted tupleproto, but it's
>        been preserved inside the ICMP. */
>     if (!nf_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
>         pr_debug("icmp_error_message: no match\n");
>         return -NF_ACCEPT;
>     }
>
>     ctinfo = IP_CT_RELATED;
>
>     h = nf_conntrack_find_get(state->net, zone, &innertuple);
>     if (!h) {
>          pr_debug("icmp_error_message: no match\n");
>         return -NF_ACCEPT;
>     }
>
>     if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
>         ctinfo += IP_CT_IS_REPLY;
>
>     /* Update skb to refer to this connection */
>     nf_ct_set(skb, nf_ct_tuplehash_to_ctrack(h), ctinfo);
>     return NF_ACCEPT;
> }

Best Regards.

Luca Moro
Synacktiv

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ