美文网首页iOSiOS 开发随笔iOS Developer
【原创】2015第2届移动安全挑战赛iOS第二题分析

【原创】2015第2届移动安全挑战赛iOS第二题分析

作者: crean | 来源:发表于2015-10-21 19:40 被阅读505次

    creantan/P.Y.G 转载请注明出处

    第二题题目如下

    环境: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
    

    我们知道iOS内核是基于XNU内核改的,XNU for mac的代码可以从苹果官方下载到:
    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);
    
    }
    

    将kernercache拖到IDA或者hopper中分析,找到该代码段:

    ================ 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
    

    相关文章

      网友评论

        本文标题:【原创】2015第2届移动安全挑战赛iOS第二题分析

        本文链接:https://www.haomeiwen.com/subject/rwqthttx.html