-
-
[原创][原创]2015第2届移动安全挑战赛第二题分析
-
发表于: 2015-10-19 08:19 2827
-
第二题
分析如下:
(1)设备/dev/random,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。
对应kernelcache中汇编代码:
从源码中可以看出 cdevsw_add 函数第二个参数为cdevsw结构体地址
从汇编中算出random_cdevsw结构体地址为0x803bd360+0xb14 = 0x803BDE74
go到0x803BDE74 random_cdevsw:
/dev/random 结果为 0x800c0ea1#0x800c0e39#0x800c0e05
(2)设备/dev/pf,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。
对应kernelcache汇编代码(节选):
算出pf_cdevsw结构体地址为0x803bd360+0xbbc = 0x803BDF1C
go到0x803BDF1C pf_cdevsw:
/dev/pf 结果为 0x802873ad#0x802873ad#0x80149d19
(3)设备/dev/ptmx,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。
对应kernelcache汇编代码(节选):
算出ptmx_cdev结构体地址为0x803bd360+0xc2c = 0x803BDF8C
go到0x803BDF8C ptmx_cdev:
/dev/ptmx 结果为 0x80292251#0x80292661#0x8029298d
所以最终结果为:
环境:iPhone5C(A1529) iOS 8.4 kernelcache ,解密后的kernelcache见附件 求得下列地址(减去kaslr): (1)设备/dev/random,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。 (2)设备/dev/pf,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。 (3)设备/dev/ptmx,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。 假设上述地址的结果是: /dev/random d_read:0x80001231 d_write:0x80001253 d_ioctl:0x80001275 /dev/pf d_read:0x80201297 d_write:0x802012b9 d_ioctl:0x801012db /dev/ptmx d_read:0x802012ed d_write:0x802012ff d_ioctl:0x80201211 那么答案的格式应该是:(用#号分隔) 0x80001231#0x80001253#0x80001275#0x80201297#0x802012b9#0x801012db#0x802012ed#0x802012ff#0x80201211
分析如下:
(1)设备/dev/random,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。
xnu-2782.40.9/bsd/dev/random/randomdev.c
static struct cdevsw random_cdevsw = { random_open, /* open */ random_close, /* close */ random_read, /* read */ random_write, /* write */ random_ioctl, /* ioctl */ (stop_fcn_t *)nulldev, /* stop */ (reset_fcn_t *)nulldev, /* reset */ NULL, /* tty's */ eno_select, /* select */ eno_mmap, /* mmap */ eno_strat, /* strategy */ eno_getc, /* getc */ eno_putc, /* putc */ 0 /* type */ }; /* * Called to initialize our device, * and to register ourselves with devfs */ void random_init(void) { int ret; ret = cdevsw_add(RANDOM_MAJOR, &random_cdevsw); if (ret < 0) { panic("random_init: failed to allocate a major number!"); } devfs_make_node(makedev (ret, RANDOM_MINOR), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0666, "random", 0); /* * also make urandom * (which is exactly the same thing in our context) */ devfs_make_node(makedev (ret, URANDOM_MINOR), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0666, "urandom", 0); }
对应kernelcache中汇编代码:
================ B E G I N N I N G O F P R O C E D U R E ================ sub_800c0d88: 800c0d88 push {r4, r5, r6, r7, lr} 800c0d8a add r7, sp, #0xc 800c0d8c sub sp, #0xc 800c0d8e movw r0, #0xc5c6 800c0d92 movt r0, #0x2f 800c0d96 add r0, pc ; 0x803bd360 (_PE_poll_input + 0xaf4c) 800c0d98 addw r1, r0, #0xb14 800c0d9c mov.w r0, #0xffffffff 800c0da0 bl _cdevsw_add 800c0da4 mov r4, r0 800c0da6 cmp.w r4, #0xffffffff 800c0daa bgt 0x800c0dba 800c0dac movw r0, #0x655f 800c0db0 movt r0, #0x2b 800c0db4 add r0, pc ; "\\\"random_init: failed to allocate a major number!\\\"", argument #1 for method _panic 800c0db6 bl _panic 800c0dba movw r0, #0x657b ; XREF=sub_800c0d88+34 800c0dbe mov.w r6, #0x1b6 800c0dc2 movt r0, #0x2b 800c0dc6 movs r5, #0x0 800c0dc8 str r6, [sp] ; argument #5 for method _devfs_make_node 800c0dca add r0, pc ; "random" 800c0dcc movs r1, #0x0 ; argument #2 for method _devfs_make_node 800c0dce str r0, [sp, #0x4] ; argument #6 for method _devfs_make_node 800c0dd0 lsl.w r0, r4, #0x18 ; argument #1 for method _devfs_make_node 800c0dd4 movs r2, #0x0 ; argument #3 for method _devfs_make_node 800c0dd6 movs r3, #0x0 ; argument #4 for method _devfs_make_node 800c0dd8 str r5, [sp, #0x8] 800c0dda bl _devfs_make_node 800c0dde movw r0, #0x6560 800c0de2 movs r1, #0x0 ; argument #2 for method _devfs_make_node 800c0de4 movt r0, #0x2b 800c0de8 str r6, [sp] ; argument #5 for method _devfs_make_node 800c0dea movs r2, #0x0 ; argument #3 for method _devfs_make_node 800c0dec add r0, pc ; "urandom" 800c0dee movs r3, #0x0 ; argument #4 for method _devfs_make_node 800c0df0 str r0, [sp, #0x4] ; argument #6 for method _devfs_make_node 800c0df2 movs r0, #0x1 800c0df4 orr.w r0, r0, r4, lsl #24 ; argument #1 for method _devfs_make_node 800c0df8 str r5, [sp, #0x8] 800c0dfa bl _devfs_make_node 800c0dfe add sp, #0xc 800c0e00 pop {r4, r5, r6, r7, pc} ; endp 800c0e02 nop
从源码中可以看出 cdevsw_add 函数第二个参数为cdevsw结构体地址
从汇编中算出random_cdevsw结构体地址为0x803bd360+0xb14 = 0x803BDE74
go到0x803BDE74 random_cdevsw:
803bde74 db 0x19 ; '.' 803bde75 db 0x0e ; '.' 803bde76 db 0x0c ; '.' 803bde77 db 0x80 ; '.' 803bde78 db 0x35 ; '5' 803bde79 db 0x0e ; '.' 803bde7a db 0x0c ; '.' 803bde7b db 0x80 ; '.' 803bde7c db 0xa1 ; '.' 803bde7d db 0x0e ; '.' 803bde7e db 0x0c ; '.' 803bde7f db 0x80 ; '.' ---->random_read 0x800c0ea1 803bde80 db 0x39 ; '9' 803bde81 db 0x0e ; '.' 803bde82 db 0x0c ; '.' 803bde83 db 0x80 ; '.' ---->random_write 0x800c0e39 803bde84 db 0x05 ; '.' 803bde85 db 0x0e ; '.' 803bde86 db 0x0c ; '.' 803bde87 db 0x80 ; '.' ---->random_ioctl 0x800c0e05 803bde88 db 0xc9 ; '.' 803bde89 db 0x73 ; 's' 803bde8a db 0x28 ; '(' 803bde8b db 0x80 ; '.' 803bde8c db 0xc9 ; '.' 803bde8d db 0x73 ; 's' 803bde8e db 0x28 ; '(' 803bde8f db 0x80 ; '.' 803bde90 db 0x00 ; '.' 803bde91 db 0x00 ; '.' 803bde92 db 0x00 ; '.' 803bde93 db 0x00 ; '.' 803bde94 db 0xad ; '.' 803bde95 db 0x73 ; 's' 803bde96 db 0x28 ; '(' 803bde97 db 0x80 ; '.' 803bde98 db 0xad ; '.' 803bde99 db 0x73 ; 's' 803bde9a db 0x28 ; '(' 803bde9b db 0x80 ; '.' 803bde9c db 0xb1 ; '.' 803bde9d db 0x73 ; 's' 803bde9e db 0x28 ; '(' 803bde9f db 0x80 ; '.' 803bdea0 db 0xad ; '.' 803bdea1 db 0x73 ; 's' 803bdea2 db 0x28 ; '(' 803bdea3 db 0x80 ; '.' 803bdea4 db 0xad ; '.' 803bdea5 db 0x73 ; 's' 803bdea6 db 0x28 ; '(' 803bdea7 db 0x80 ; '.' 803bdea8 db 0x00 ; '.' 803bdea9 db 0x00 ; '.' 803bdeaa db 0x00 ; '.' 803bdeab db 0x00
/dev/random 结果为 0x800c0ea1#0x800c0e39#0x800c0e05
(2)设备/dev/pf,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。
xnu-2782.40.9/bsd/net/pf_ioctl.c:
static struct cdevsw pf_cdevsw = { /* open */ pfopen, /* close */ pfclose, /* read */ eno_rdwrt, /* write */ eno_rdwrt, /* ioctl */ pfioctl, /* stop */ eno_stop, /* reset */ eno_reset, /* tty */ NULL, /* select */ eno_select, /* mmap */ eno_mmap, /* strategy */ eno_strat, /* getc */ eno_getc, /* putc */ eno_putc, /* type */ 0 }; void pfinit(void) {...... maj = cdevsw_add(PF_CDEV_MAJOR, &pf_cdevsw); if (maj == -1) { printf("%s: failed to allocate major number!\n", __func__); return; } (void) devfs_make_node(makedev(maj, PFDEV_PF), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0600, "pf", 0); (void) devfs_make_node(makedev(maj, PFDEV_PFM), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0600, "pfm", 0); ...... }
对应kernelcache汇编代码(节选):
8024b51a movw r0, #0x1e3a 8024b51e movt r0, #0x17 8024b522 add r0, pc ; 0x803bd360 (_PE_poll_input + 0xaf4c) 8024b524 addw r1, r0, #0xbbc 8024b528 mov.w r0, #0xffffffff 8024b52c bl _cdevsw_add 8024b530 mov r5, r0 8024b532 cmp.w r5, #0xffffffff 8024b536 beq 0x8024b5ba 8024b538 movw r0, #0x4532 8024b53c mov.w r4, #0x180 8024b540 movt r0, #0x13 8024b544 mov.w r11, #0x0 8024b548 str r4, [sp] 8024b54a add r0, pc ; "pf" 8024b54c movs r1, #0x0 8024b54e str r0, [sp, #0x4] 8024b550 lsl.w r0, r5, #0x18 8024b554 movs r2, #0x0 8024b556 movs r3, #0x0 8024b558 str.w r11, [sp, #0x8] 8024b55c bl _devfs_make_node 8024b560 movw r0, #0x4555 8024b564 movs r1, #0x0 8024b566 movt r0, #0x13 8024b56a str r4, [sp] 8024b56c movs r2, #0x0 8024b56e add r0, pc ; "pfm" 8024b570 movs r3, #0x0 8024b572 str r0, [sp, #0x4] 8024b574 movs r0, #0x1 8024b576 orr.w r0, r0, r5, lsl #24 8024b57a str.w r11, [sp, #0x8] 8024b57e bl _devfs_make_node
算出pf_cdevsw结构体地址为0x803bd360+0xbbc = 0x803BDF1C
go到0x803BDF1C pf_cdevsw:
803bdf1c db 0x65 ; 'e' 803bdf1d db 0x2c ; ',' 803bdf1e db 0x15 ; '.' 803bdf1f db 0x80 ; '.' 803bdf20 db 0xf5 ; '.' 803bdf21 db 0x2b ; '+' 803bdf22 db 0x15 ; '.' 803bdf23 db 0x80 ; '.' 803bdf24 db 0xad ; '.' 803bdf25 db 0x73 ; 's' 803bdf26 db 0x28 ; '(' 803bdf27 db 0x80 ; '.' ---->eno_rdwrt 0x802873ad 803bdf28 db 0xad ; '.' 803bdf29 db 0x73 ; 's' 803bdf2a db 0x28 ; '(' 803bdf2b db 0x80 ; '.' ---->eno_rdwrt 0x802873ad 803bdf2c db 0x19 ; '.' 803bdf2d db 0x9d ; '.' 803bdf2e db 0x14 ; '.' 803bdf2f db 0x80 ; '.' ---->pfioctl 0x80149d19 803bdf30 db 0xad ; '.' 803bdf31 db 0x73 ; 's' 803bdf32 db 0x28 ; '(' 803bdf33 db 0x80 ; '.' 803bdf34 db 0xad ; '.' 803bdf35 db 0x73 ; 's' 803bdf36 db 0x28 ; '(' 803bdf37 db 0x80 ; '.' 803bdf38 db 0x00 ; '.' 803bdf39 db 0x00 ; '.' 803bdf3a db 0x00 ; '.' 803bdf3b db 0x00 ; '.' 803bdf3c db 0xad ; '.' 803bdf3d db 0x73 ; 's' 803bdf3e db 0x28 ; '(' 803bdf3f db 0x80 ; '.' 803bdf40 db 0xad ; '.' 803bdf41 db 0x73 ; 's' 803bdf42 db 0x28 ; '(' 803bdf43 db 0x80 ; '.' 803bdf44 db 0xb1 ; '.' 803bdf45 db 0x73 ; 's' 803bdf46 db 0x28 ; '(' 803bdf47 db 0x80 ; '.' 803bdf48 db 0xad ; '.' 803bdf49 db 0x73 ; 's' 803bdf4a db 0x28 ; '(' 803bdf4b db 0x80 ; '.' 803bdf4c db 0xad ; '.' 803bdf4d db 0x73 ; 's' 803bdf4e db 0x28 ; '(' 803bdf4f db 0x80 ; '.' 803bdf50 db 0x00 ; '.' 803bdf51 db 0x00 ; '.' 803bdf52 db 0x00 ; '.' 803bdf53 db 0x00
/dev/pf 结果为 0x802873ad#0x802873ad#0x80149d19
(3)设备/dev/ptmx,对应结构体cdevsw中d_read, d_write, d_ioctl在题目给出kernelcache中的地址。
/xnu-2782.40.9/bsd/kern/tty_ptmx.c:
static struct cdevsw ptmx_cdev = { ptcopen, ptcclose, ptcread, ptcwrite, ptyioctl, ptcstop, ptcreset, 0, ptcselect, eno_mmap, eno_strat, eno_getc, eno_putc, D_TTY }; int ptmx_init( __unused int config_count) { /* * We start looking at slot 10, since there are inits that will * stomp explicit slots (e.g. vndevice stomps 1) below that. */ /* Get a major number for /dev/ptmx */ if((ptmx_major = cdevsw_add(-15, &ptmx_cdev)) == -1) { printf("ptmx_init: failed to obtain /dev/ptmx major number\n"); return (ENOENT); } if (cdevsw_setkqueueok(ptmx_major, &ptmx_cdev, 0) == -1) { panic("Failed to set flags on ptmx cdevsw entry."); } /* Get a major number for /dev/pts/nnn */ if ((ptsd_major = cdevsw_add(-15, &ptsd_cdev)) == -1) { (void)cdevsw_remove(ptmx_major, &ptmx_cdev); printf("ptmx_init: failed to obtain /dev/ptmx major number\n"); return (ENOENT); } if (cdevsw_setkqueueok(ptsd_major, &ptsd_cdev, 0) == -1) { panic("Failed to set flags on ptmx cdevsw entry."); } /* * Locks to guard against races between revoke and kevents */ ptsd_kevent_lock_init(); /* Create the /dev/ptmx device {<major>,0} */ (void)devfs_make_node_clone(makedev(ptmx_major, 0), DEVFS_CHAR, UID_ROOT, GID_TTY, 0666, ptmx_clone, PTMX_TEMPLATE); _ptmx_driver.master = ptmx_major; _ptmx_driver.slave = ptsd_major; _ptmx_driver.fix_7828447 = 1; _ptmx_driver.fix_7070978 = 1; #if CONFIG_MACF _ptmx_driver.mac_notify = 1; #endif _ptmx_driver.open = &ptmx_get_ioctl; _ptmx_driver.free = &ptmx_free_ioctl; _ptmx_driver.name = &ptmx_get_name; _ptmx_driver.revoke = &ptsd_revoke_knotes; tty_dev_register(&_ptmx_driver); return (0); }
对应kernelcache汇编代码(节选):
80293330 push {r4, r5, r6, r7, lr} 80293332 add r7, sp, #0xc 80293334 push.w {r8, r10, r11} 80293338 sub sp, #0xc 8029333a movw r4, #0xa016 8029333e mvn r0, #0xe 80293342 movt r4, #0x12 80293346 add r4, pc ; 0x803bd360 (_PE_poll_input + 0xaf4c) 80293348 addw r1, r4, #0xc2c 8029334c bl _cdevsw_add 80293350 movw r8, #0x6b90 80293354 cmp.w r0, #0xffffffff 80293358 movt r8, #0x16 8029335c add r8, pc ; 0x803f9ef0 8029335e str.w r0, [r8, #0xc58] ; 0x803fab48 80293362 beq 0x80293412 80293364 cmp r0, #0x2a 80293366 bhi 0x802933a8 80293368 movw r1, #0xe0d0 8029336c rsb r2, r0, r0, lsl #3 80293370 movt r1, #0x11 80293374 add r1, pc ; _cdevsw 80293376 add.w r1, r1, r2, lsl #3 8029337a movs r2, #0x0 8029337c adds r6, r4, r2 ; XREF=sub_80293330+92 8029337e ldrb r3, [r1, r2] 80293380 ldrb.w r6, [r6, #0xc2c] 80293384 cmp r3, r6 80293386 bne 0x802933a8 80293388 adds r2, #0x1 8029338a cmp r2, #0x38 8029338c bne 0x8029337c 8029338e movw r1, #0x583c 80293392 movs r2, #0x1 80293394 movt r1, #0x16 80293398 add r1, pc ; 0x803f8bd8 8029339a str.w r2, [r1, r0, lsl #3] 8029339e add.w r0, r1, r0, lsl #3 802933a2 movs r1, #0x0 802933a4 str r1, [r0, #0x4] 802933a6 b 0x802933b6 802933a8 movw r0, #0xeb91 ; XREF=sub_80293330+54, sub_80293330+86 802933ac movt r0, #0xc 802933b0 add r0, pc ; "\\\"Failed to set flags on ptmx cdevsw entry.\\\"", argument #1 for method _panic 802933b2 bl _panic 802933b6 addw r1, r4, #0xc64 ; XREF=sub_80293330+118 802933ba mvn r0, #0xe 802933be bl _cdevsw_add
算出ptmx_cdev结构体地址为0x803bd360+0xc2c = 0x803BDF8C
go到0x803BDF8C ptmx_cdev:
803bdf8c db 0x9d ; '.' 803bdf8d db 0x1f ; '.' 803bdf8e db 0x29 ; ')' 803bdf8f db 0x80 ; '.' 803bdf90 db 0xd5 ; '.' 803bdf91 db 0x20 ; ' ' 803bdf92 db 0x29 ; ')' 803bdf93 db 0x80 ; '.' 803bdf94 db 0x51 ; 'Q' 803bdf95 db 0x22 ; '"' 803bdf96 db 0x29 ; ')' 803bdf97 db 0x80 ; '.' ---->ptcread 0x80292251 803bdf98 db 0x61 ; 'a' 803bdf99 db 0x26 ; '&' 803bdf9a db 0x29 ; ')' 803bdf9b db 0x80 ; '.' ---->ptcwrite 0x80292661 803bdf9c db 0x8d ; '.' 803bdf9d db 0x29 ; ')' 803bdf9e db 0x29 ; ')' 803bdf9f db 0x80 ; '.' ---->ptyioctl 0x8029298d 803bdfa0 db 0x59 ; 'Y' 803bdfa1 db 0x26 ; '&' 803bdfa2 db 0x29 ; ')' 803bdfa3 db 0x80 ; '.' 803bdfa4 db 0x5d ; ']' 803bdfa5 db 0x26 ; '&' 803bdfa6 db 0x29 ; ')' 803bdfa7 db 0x80 ; '.' 803bdfa8 db 0x00 ; '.' 803bdfa9 db 0x00 ; '.' 803bdfaa db 0x00 ; '.' 803bdfab db 0x00 ; '.' 803bdfac db 0x0d ; '.' 803bdfad db 0x25 ; '%' 803bdfae db 0x29 ; ')' 803bdfaf db 0x80 ; '.' 803bdfb0 db 0xad ; '.' 803bdfb1 db 0x73 ; 's' 803bdfb2 db 0x28 ; '(' 803bdfb3 db 0x80 ; '.' 803bdfb4 db 0xb1 ; '.' 803bdfb5 db 0x73 ; 's' 803bdfb6 db 0x28 ; '(' 803bdfb7 db 0x80 ; '.' 803bdfb8 db 0xad ; '.' 803bdfb9 db 0x73 ; 's' 803bdfba db 0x28 ; '(' 803bdfbb db 0x80 ; '.' 803bdfbc db 0xad ; '.' 803bdfbd db 0x73 ; 's' 803bdfbe db 0x28 ; '(' 803bdfbf db 0x80 ; '.' 803bdfc0 db 0x03 ; '.' 803bdfc1 db 0x00 ; '.' 803bdfc2 db 0x00 ; '.' 803bdfc3 db 0x00 ; '.'
/dev/ptmx 结果为 0x80292251#0x80292661#0x8029298d
所以最终结果为:
0x800c0ea1#0x800c0e39#0x800c0e05#0x802873ad#0x802873ad#0x80149d19#0x80292251#0x80292661#0x8029298d
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: