首页
社区
课程
招聘
[原创][原创]2015第2届移动安全挑战赛第二题分析
2015-10-19 08:19 2756

[原创][原创]2015第2届移动安全挑战赛第二题分析

2015-10-19 08:19
2756
第二题
环境: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

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回