越狱检测/越狱检测绕过——xCon
     
    
一直忽略了越狱检测与越狱检测绕过的问题,因为我认为在app争抢装机率的环境下,是不会在乎对方的设备越狱与否的。但很显然,我忽略了一个问题,app在设计的时候或许会依照设备是否越狱而采取不同的流程,比如说对越狱的设备采取更多的安全措施,在这种场景下,越狱检测是否可靠就成为了关键问题。本篇文章主要介绍越狱检测的常见方法(并配有相应的测试代码),以及最流行的越狱检测绕过插件xCon(会分析该工具会绕过哪些检测方法),最后总结了个人认为的比较可靠的越狱检测方法。
一、越狱检测
(一)《Hacking and Securing iOS Applications》这本书的第13章介绍了以下方面做越狱检测
1. 沙盒完整性校验
xCon对此种方法有检测
。
 
         2. 文件系统检查
(1)检查常见的越狱文件是否存在
stat函数
来判断以下文件是否存在
          
           /Library/
          
          
           MobileSubstrate
          
          
           /
          
          
           MobileSubstrate
          
          
           .
          
          
           dylib
          
          
           最重要的越狱文件,几乎所有的越狱机都会安装
          
          
           MobileSubstrate
          
         
          
           /
          
          
           Applications
          
          
           /
          
          
           Cydia
          
          
           .
          
          
           app
          
          
           /
          
          
           /
          
          
           var
          
          
           /
          
          
           lib
          
          
           /
          
          
           cydia
          
          
           /
          
          
           绝大多数越狱机都会安装
          
         
          
           /
          
          
           var
          
          
           /
          
          
           cache
          
          
           /
          
          
           apt
          
          
           /
          
          
           var
          
          
           /
          
          
           lib
          
          
           /
          
          
           apt
          
          
           /
          
          
           etc
          
          
           /
          
          
           apt
          
         
          
           /
          
          
           bin
          
          
           /
          
          
           bash
          
          
           /
          
          
           bin
          
          
           /
          
          
           sh
          
         
          
           /
          
          
           usr
          
          
           /
          
          
           sbin
          
          
           /
          
          
           sshd
          
          
           /
          
          
           usr
          
          
           /
          
          
           libexec
          
          
           /
          
          
           ssh
          
          
           –
          
          
           keysign
          
          
           /
          
          
           etc
          
          
           /
          
          
           ssh
          
          
           /
          
          
           sshd_config
          
         
代码如下
:
          
        
错误代码:
ENOENT 参数file_name指定的文件不存在
ENOTDIR 路径中的目录存在但却非真正的目录
ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接
EFAULT 参数buf为无效指针,指向无法存在的内存空间
EACCESS 存取文件时被拒绝
ENOMEM 核心内存不足
ENAMETOOLONG 参数file_name的路径名称太长
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
使用底层的
c
函数
stat
函数
来判断以下路径名,路径名做编码处理(不要使用
base64
编码),千万不要使用
NSFileManager
类,会被
hook
掉
(2) /etc/fstab文件的大小
stat函数
获得该文件的大小。在iOS 5上,未越狱的该文件大小未80字节,越狱的一般只有65字节。
代码如下
:
 
         803705776 ;
卸载xCon后在越狱设备上运行,result的大小为
66
xCon对此种方法有检测,不能采用这种办法
(3)检查特定的文件是否是符号链接文件
lstat函数
,检测/Applications的属性,看是目录,还是符号链接。如果是符号链接,则能确定是越狱设备。
 
         代码如下:
 
         (二)http://theiphonewiki.com/wiki/index.php?title=Bypassing_Jailbreak_Detection 给出了以下6种越狱监测方法
1、检测特定目录或文件是否存在
或者采用底层的C函数,例如fopen(),
stat()
or access()
与
《Hacking and Securing iOS Applications》
的方法2文件系统检查相同
xCon对此种方法有检测
2、检测特定目录或文件的文件访问权限
检测文件系统中特定文件或目录的unix文件访问权限(还有大小),越狱设备较之未越狱设备有太多的目录或文件具备写权限
xCon对此种方法有检测
3、检测是否能创建子进程
与
《Hacking and Securing iOS Applications》
的方法1
沙盒完整性检查
相同
4、检测能否执行ssh本地连接
xCon对此种方法有检测
5、检测system()函数的返回值
 
         6、检测dylib(动态链接库)的内容
        
         
          这种方法是目前最靠谱的方法,调用
         
         
          _dyld_image_count
         
         
          ()和
         
         
          _dyld_get_image_name()来看当前有哪些dylib被加载
         
        
          
           #include
          
          
           <string.h>
          
         
          
           #import
          
          
           <mach-o/loader.h>
          
         
          
           #import
          
          
           <mach-o/dyld.h>
          
         
          
           #import
          
          
           <mach-o/arch.h>
          
         
          
           void
          
          
           printDYLD
          
          
           ()
          
         
          
           {
           
          
         
          
          
          
           //Get count of all currently loaded DYLD
          
         
          
          
          
           uint32_t
          
          
           count
          
          
           =
          
          
           _dyld_image_count
          
          
           ();
          
         
          
          
          
           for
          
          
           (
          
          
           uint32_t
          
          
           i
          
          
           =
          
          
           0
          
          
           ;
          
          
           i
          
          
           <
          
          
           count
          
          
           ;
          
          
           i
          
          
           ++)
          
         
          
          
          
           {
           
          
         
          
          
          
           //Name of image (includes full path)
          
         
          
          
          
           const
          
          
           char
          
          
           *
          
          
           dyld
          
          
           =
          
          
           _dyld_get_image_name
          
          
           (
          
          
           i
          
          
           );
          
         
          
          
         
          
          
          
           //Get name of file
          
         
          
          
          
           int
          
          
           slength
          
          
           =
          
          
           strlen
          
          
           (
          
          
           dyld
          
          
           );
          
         
          
          
         
          
          
          
           int
          
          
           j
          
          
           ;
          
         
          
          
          
           for
          
          
           (
          
          
           j
          
          
           =
          
          
           slength
          
          
           –
          
          
           1
          
          
           ;
          
          
           j
          
          
           >=
          
          
           0
          
          
           ;
          
          
           —
          
          
           j
          
          
           )
          
         
          
          
          
           if
          
          
           (
          
          
           dyld
          
          
           [
          
          
           j
          
          
           ]
          
          
           ==
          
          
           ‘/’
          
          
           )
          
          
           break
          
          
           ;
          
         
          
          
         
          
          
          
           printf
          
          
           (
          
          
           “%s\n”
          
          
           ,
          
          
           dyld
          
          
           );
          
         
          
          
          
           }
          
         
          
          
          
           printf
          
          
           (
          
          
           “\n”
          
          
           );
          
         
          
           }
          
         
          
           int
          
          
           main
          
          
           (
          
          
           int
          
          
           argc
          
          
           ,
          
          
           char
          
          
           *
          
          
           argv
          
          
           [])
          
         
          
           {
           
          
         
          
          
          
           printDYLD
          
          
           ();
          
         
          
          
          
           NSAutoreleasePool
          
          
           *
          
          
           pool
          
          
           =
          
          
           [[
          
          
           NSAutoreleasePool
          
          
           alloc
          
          
           ]
          
          
           init
          
          
           ];
          
         
          
          
          
           int
          
          
           retVal
          
          
           =
          
          
           UIApplicationMain
          
          
           (
          
          
           argc
          
          
           ,
          
          
           argv
          
          
           ,
          
          
           nil
          
          
           ,
          
          
           nil
          
          
           );
          
         
          
          
          
           [
          
          
           pool
          
          
           release
          
          
           ];
          
         
          
          
          
           return
          
          
           retVal
          
          
           ;
          
         
          
           }
          
         
下图显示了我的iOS设备当前加载的dylib的路径,最下面就可以看到xCon
 
         二、越狱检测绕过——xCon
/Library/MobileSubstrate/DynamicLibraries目录下
 
      
       
        DANI
       
       
        –
       
       
        LEE
       
       
        –
       
       
        2
       
       
        :
       
       
        iostools danqingdani$ otool
       
       
        –
       
       
        tV xCon
       
       
        .
       
       
        dylib
       
       
        >
       
       
        xContextsection
       
      
      可以根据文件中的函数名,同时结合该工具的原理以及越狱检测的一些常用手段
      
       (文章第一部分有介绍)
      
      来猜其逻辑,例如越狱检测方法中的文件系统检查,会根据特定的文件路径名来匹配,我们可以使用strings查看文件中的内容,看看会有哪些文件路径名。
     
       
        DANI
       
       
        –
       
       
        LEE
       
       
        –
       
       
        2
       
       
        :
       
       
        IAP tools danqingdani$ strings xCon
       
       
        .
       
       
        dylib
       
       
        >
       
       
        xConReadable
       
      
      
       以下是xCon中会匹配的文件名
      
     
       
        /usr/
       
       
        bin
       
       
        /
       
       
        sshd
       
       
        /
       
       
        usr
       
       
        /
       
       
        libexec
       
       
        /
       
       
        sftp
       
       
        –
       
       
        server
       
       
        /
       
       
        usr
       
       
        /
       
       
        sbin
       
       
        /
       
       
        sshd
       
      
       
        /
       
       
        bin
       
       
        /
       
       
        bash
       
       
        /
       
       
        bin
       
       
        /
       
       
        sh
       
       
        /
       
       
        bin
       
       
        /
       
       
        sw
       
       
        /
       
       
        etc
       
       
        /
       
       
        apt
       
       
        /
       
       
        etc
       
       
        /
       
       
        fstab
       
       
        /
       
       
        Applications
       
       
        /
       
       
        blackra1n
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        Cydia
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        Cydia
       
       
        .
       
       
        app
       
       
        /
       
       
        Info
       
       
        .
       
       
        plist
       
       
        /
       
       
        Applications
       
       
        /
       
       
        Cycorder
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        Loader
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        FakeCarrier
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        Icy
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        IntelliScreen
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        MxTube
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        RockApp
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        SBSettings
       
       
        .
       
       
        app
       
       
        /
       
       
        Applications
       
       
        /
       
       
        WinterBoard
       
       
        .
       
       
        app
       
       
        /
       
       
        bin
       
       
        /
       
       
        bash
       
       
        /
       
       
        Applications
       
       
        /
       
       
        Cydia
       
       
        .
       
       
        app
       
       
        /
       
       
        Library
       
       
        /
       
       
        LaunchDaemons
       
       
        /
       
       
        com
       
       
        .
       
       
        openssh
       
       
        .
       
       
        sshd
       
       
        .
       
       
        plist
       
       
        /
       
       
        Library
       
       
        /
       
       
        Frameworks
       
       
        /
       
       
        CydiaSubstrate
       
       
        .
       
       
        framework
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        DynamicLibraries
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        DynamicLibraries
       
       
        /
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        DynamicLibraries
       
       
        /
       
       
        LiveClock
       
       
        .
       
       
        plist
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        DynamicLibraries
       
       
        /
       
       
        Veency
       
       
        .
       
       
        plist
       
       
        /
       
       
        Library
       
       
        /
       
       
        MobileSubstrate
       
       
        /
       
       
        DynamicLibraries
       
       
        /
       
       
        xCon
       
       
        .
       
       
        plist
       
       
        /
       
       
        private
       
       
        /
       
       
        var
       
       
        /
       
       
        lib
       
       
        /
       
       
        apt
       
       
        /
       
       
        private
       
       
        /
       
       
        var
       
       
        /
       
       
        lib
       
       
        /
       
       
        apt
       
       
        /
       
       
        /
       
       
        private
       
       
        /
       
       
        var
       
       
        /
       
       
        lib
       
       
        /
       
       
        cydia
       
       
        /
       
       
        private
       
       
        /
       
       
        var
       
       
        /
       
       
        mobile
       
       
        /
       
       
        Library
       
       
        /
       
       
        SBSettings
       
       
        /
       
       
        Themes
       
       
        /
       
       
        private
       
       
        /
       
       
        var
       
       
        /
       
       
        stash
       
       
        /
       
       
        private
       
       
        /
       
       
        var
       
       
        /
       
       
        tmp
       
       
        /
       
       
        cydia
       
       
        .
       
       
        log
       
       
        /
       
       
        System
       
       
        /
       
       
        Library
       
       
        /
       
       
        LaunchDaemons
       
       
        /
       
       
        com
       
       
        .
       
       
        ikey
       
       
        .
       
       
        bbot
       
       
        .
       
       
        plist
       
       
        /
       
       
        System
       
       
        /
       
       
        Library
       
       
        /
       
       
        LaunchDaemons
       
       
        /
       
       
        com
       
       
        .
       
       
        saurik
       
       
        .
       
       
        Cydia
       
       
        .
       
       
        Startup
       
       
        .
       
       
        plist
       
      
       
        
         NzI0MS9MaWJyYXJ5L01vYmlsZVN1YnN0cmF0ZQ
        
        
         ==
        
        
        
        
         (
        
       
       
        
         对应
        
        
         
          7241
         
         
          /
         
         
          Library
         
         
          /
         
         
          MobileSubstrate
         
        
        
         )
        
       
      
通过分析,xCon会绕过以下越狱检测方法
       
        (1)
        
        
       
       根据是否存在特定的越狱文件,及特定文件的权限是否发生变化来判断设备是否越狱
      
       
        
         fileExistsAtPath:
        
       
      
       
        
         fileExistsAtPath:isDirectory:
        
       
      
       
        
         filePermission:
        
       
      
       
        
         fileSystemIsValid:
        
       
      
       
        checkFileSystemWithPath:forPermissions:
       
      
       
        mobileSubstrateWorkaround
       
      
       
        detectIllegalApplication:
       
      
       
        (2)
        
        
       
       根据
       
        沙箱完整性检测设备是否越狱
       
      
       
        canUseFork
       
       
       
      
       
        (3)
        
        
       
       根据文件系统的分区是否发生变化来检测设备是否越狱
      
       
        partitionsModified
       
       
       
      
       
        (4)
        
        
       
       
        根据是否安装
       
       
        ssh
       
       
        来判断设备是否越狱
       
      
       
        ssh
        
         root@127.0.0.1
        
       
      
(1)检查常见的越狱文件是否存在,使用stat(),检查以下文件是否存在
        
         /Library/
        
        
         MobileSubstrate
        
        
         /
        
        
         MobileSubstrate
        
        
         .
        
        
         dylib
        
        
         最重要的越狱文件,几乎所有的越狱机都会安装
        
        
         MobileSubstrate
        
       
        
         /
        
        
         Applications
        
        
         /
        
        
         Cydia
        
        
         .
        
        
         app
        
        
         /
        
        
         /
        
        
         var
        
        
         /
        
        
         lib
        
        
         /
        
        
         cydia
        
        
         /
        
        
         绝大多数越狱机都会安装
        
       
        
         /
        
        
         var
        
        
         /
        
        
         cache
        
        
         /
        
        
         apt
        
        
         /
        
        
         var
        
        
         /
        
        
         lib
        
        
         /
        
        
         apt
        
        
         /
        
        
         etc
        
        
         /
        
        
         apt
        
       
        
         /
        
        
         bin
        
        
         /
        
        
         bash
        
        
         /
        
        
         bin
        
        
         /
        
        
         sh
        
       
        
         /
        
        
         usr
        
        
         /
        
        
         sbin
        
        
         /
        
        
         sshd
        
        
         /
        
        
         usr
        
        
         /
        
        
         libexec
        
        
         /
        
        
         ssh
        
        
         –
        
        
         keysign
        
        
         /
        
        
         etc
        
        
         /
        
        
         ssh
        
        
         /
        
        
         sshd_config
        
       
(2)检查特定的文件是否是符号链接文件,使用lstat(),检查以下文件是否为符号链接文件
        
         /Applications
        
       
        
         /
        
        
         Library
        
        
         /
        
        
         Ringtones
        
       
        
         /
        
        
         Library
        
        
         /
        
        
         Wallpaper
        
       
        
         /
        
        
         usr
        
        
         /
        
        
         include
        
       
        
         /
        
        
         usr
        
        
         /
        
        
         libexec
        
       
        
         /
        
        
         usr
        
        
         /
        
        
         share
        
       
(3)检差dylib(动态链接库)的内容,使用
_dyld_image_count与
_dyld_get_image_name,检查是否包含越狱插件的dylib文件
 
