Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Sun, 26 Feb 2017 01:45:54 +0100
From: Andrey Konovalov <andreyknvl@...gle.com>
To: oss-security@...ts.openwall.com
Subject: Re: Linux kernel: CVE-2017-6074: DCCP double-free vulnerability
 (local root)

I've uploaded the proof-of-concept exploit here:
https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074

It includes a SMEP/SMAP bypass, however it's not very reliable. The
exploit was tested on Ubuntu 16.04 with 4.4.0-62-generic kernel. It
will most likely crash on anything else, unless you at least update
the offsets.

A little detail that's missing from the initial announcement is that
this bug is technically a use-after-free followed by a double-free.
The kernel frees skb in dccp_rcv_state_process and then again when
destroying the socket due to inet6_destroy_sock. There's actually a
lot more stuff going on under the hood, but that's the essential part.

The use-after-free happens on skb and skb->data (they are allocated
and freed separately though one right after another). Exploiting this
would allow us to overwrite skb or skb->data with arbitrary data. The
double-free, however, allows us to control what object we overwrite by
doing the trick I mentioned in the previous email.

To get execution control we can overwrite skb->data, since it has
skb_shared_info struct at the end, and
shinfo->destructor_arg->callback is a function pointer, which is
triggered by skb_release_data. The exploit puts ubuf_info struct and
the payload to get root in userspace, so this will be detected by SMAP
and SMEP.

To disable SMEP and SMAP I used the idea from the CVE-2016-8655
exploit by Philip Pettersson. We can overwrite packet_sock struct,
which has a timer_list field deep inside it, which contains a callback
and it's argument. We allocate this struct, overwrite the time_list
field and schedule the timer. I used native_write_cr4 as the callback
and a value with SMEP and SMAP bits disabled for it's argument. Note,
that CVE-2016-8655 by itself resulted in a use-after-free on the
packet_sock struct, but in this case we make a use-after-free happen
by exploiting a double-free.

As I mentioned, the exploit is not very reliable, but I don't want to
spend any more time on it. The kernel can crash due to a memory
corruption if we fail to reallocate some objects in time or in the
correct order. However I've managed to make it work on three different
environments I have set up (including two vms and a real machine).

On Wed, Feb 22, 2017 at 2:28 PM, Andrey Konovalov <andreyknvl@...gle.com> wrote:
> Hi,
>
> This is an announcement about CVE-2017-6074 [1] which is a double-free
> vulnerability I found in the Linux kernel. It can be exploited to gain
> kernel code execution from an unprivileged processes.
>
> Fixed on Feb 17, 2017:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5edabca9d4cff7f1f2b68f0bac55ef99d9798ba4
>
> The oldest version that was checked is 2.6.18 (Sep 2006), which is
> vulnerable. However, the bug was introduced before that, probably in
> the first release with DCCP support (2.6.14, Oct 2005).
>
> The kernel needs to be built with CONFIG_IP_DCCP for the vulnerability
> to be present. A lot of modern distributions enable this option by
> default.
>
> The bug was found with syzkaller [2].
>
> ### Bug details
>
> In the current DCCP implementation an skb for a DCCP_PKT_REQUEST
> packet is forcibly freed via __kfree_skb in dccp_rcv_state_process if
> dccp_v6_conn_request successfully returns [3].
>
> However, if IPV6_RECVPKTINFO is set on a socket, the address of the
> skb is saved to ireq->pktopts and the ref count for skb is incremented
> in dccp_v6_conn_request [4], so skb is still in use. Nevertheless, it
> still gets freed in dccp_rcv_state_process.
>
> The fix is to call consume_skb, which accounts for skb->users,
> instead of doing goto discard and therefore calling __kfree_skb.
>
> To exploit this double-free, it can be turned into a use-after-free:
>
> //  The first free:
> kfree(dccp_skb)
> // Another object allocated on the same place as dccp_skb:
> some_object = kmalloc()
> // The second free, effectively frees some_object
> kfree(dccp_skb)
>
> As this point we have a use-after-free on some_object. An attacker can
> control what object that would be and overwrite it's content with
> arbitrary data by using some of the kernel heap spraying techniques.
> If the overwritten object has any triggerable function pointers, an
> attacker gets to execute arbitrary code within the kernel.
>
> I'll publish an exploit in a few days, giving people time to update.
>
> New Ubuntu kernels are out so please update as soon as possible.
>
> ### Timeline
>
> 2017-02-15: Bug reported to security@...nel.org
> 2017-02-16: Patch submitted to netdev
> 2017-02-17: Patch committed to mainline kernel
> 2017-02-18: Notification sent to linux-distros
> 2017-02-22: Public announcement
>
> ### Links
>
> [1] http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2017-6074
> [2] https://github.com/google/syzkaller
> [3] http://lxr.free-electrons.com/source/net/dccp/input.c?v=4.9#L606
> [4] http://lxr.free-electrons.com/source/net/dccp/ipv6.c?v=4.9#L351
> [5] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5edabca9d4cff7f1f2b68f0bac55ef99d9798ba4

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ