美文网首页
iOS逆向工程(十一):iOS签名机制

iOS逆向工程(十一):iOS签名机制

作者: 冰风v落叶 | 来源:发表于2020-05-13 20:31 被阅读0次

    前言

    想把逆向之后的APP安装到非越狱的手机上,就需要研究一下iOS的签名机制了,了解了原理之后,就可以使用codesign对APP的动态库、AppExtension、APP包进行重签名了,然后就可以安装到非越狱手机上了
    一、签名基础知识 - 对称加密
      1. 对称加密,就是加密、解密使用的是同一个密钥,如下图所示,常见的对称加密算法有DES、3DES、AES,目前AES已经逐步取代DES、3DES,成为首选的对称加密算法了。
      对称加密
      1. 使用对称加密,一定会碰到密钥配送问题,例如: A将加密后的信息发给B,B想解密的话,就需要拿到密钥,但是B应该怎么在保证安全的前提下拿到密钥呢?
      1. 解决密钥配送问题的几种办法:事先共享密钥、密钥配送中心、Diffie-Hellman密钥交换、非对称加密
    二、签名基础知识 - 非对称加密
      1. 非对称加密,也称公钥密码,非对称加密的密钥分为加密密钥、解密密钥两种,并不是同一个密钥,如下图所示,目前使用最广泛的非对称加密算法是:RSA非对称加密算法
        非对称加密
      1. 公钥可以公开,私钥不能公开,私钥和公钥都可以用来加密解密,公钥加密,就必须用私钥解密,私钥加密就必须用公钥解密
      1. 公钥和私钥是一一对应的,不能单独生成,一对公钥和私钥统称为密钥对
      1. 私钥加密的密文,必须用对应的公钥才能解密
      1. 公钥加密的密文,必须用对应的私钥才能解密
    三、混合密码系统
      1. 对称加密不能很好的解决密钥配送问题 ,非对称加密的加密解密速度又慢,我们可以将对称加密和非对称加密混合使用,就可以解决这两个缺点,思路如下,如今网络上的密码通信所用的SSL/TLS都运用了混合密码系统
    混合密码系统
      1. 消息接收者受到上述组合消息后,就可以拿出自己的私钥解密出对称密码的密钥,然后用此密钥解密消息
      1. 混合密码系统不仅解决了密钥配送问题,还解决了非对称加密解密速度慢的问题
    四、签名基础知识 - 单向散列函数
      1. 单向散列函数,又被称为消息摘要函数、哈希函数,根据数据内容计算出散列值,散列值具备以下特点:
      • 对于任意长度的消息,用同一个散列函数,得出的散列值的长度是相同的

      • 计算速度快,能快速计算出散列值

      • 消息不同,散列值也不同,对数据很敏感,哪怕只有一位不同,最后得出的散列值也完全不同

      • 具备单向性,可以用消息算出散列值,但是很难从散列值回推出消息

      1. 常见的几种单向散列函数:
      • MD4、MD5,产生128bit的散列值,目前已经不安全了

      • SHA-1产生160bit的散列值,目前已经不安全了

      • SHA-2是SHA-1的继任者,包括SHA-256、SHA-384、SHA-512等等,目前还是安全的

      • SHA-3,第三代安全散列算法,目前是安全的

      1. 单向散列函数的几个应用:对比散列值防篡改、密码散列做加密
    五、签名基础知识 - 数字签名
      1. 数字签名,就是消息发送者用自己的私钥,对消息的散列值进行加密,消息接受者用公钥解密,这样做,主要为了证明消息是从发送者手里发出去的,没有被篡改过,因为私钥只有消息发送者才有。
      1. 数字签名的整个流程,如下图所示:


        数字签名
      1. 数字签名的作用:确认消息的完整性和是否被篡改,防止消息发送人否认,单纯的数字签名并不能保证机密性
      1. 要想正确的使用签名,前提是验证签名的公钥必须属于发送者,如果上图中的Bob是个攻击者伪装的假Bob,那么这个攻击者就可以自己生成新的密钥对,然后将攻击者的公钥给真Bob,从而伪造信息,所以使用签名前,必须验证公钥的合法性
    六、签名基础知识 - 证书
      1. 如何验证公钥的合法性呢?答案就是使用证书,证书是指:权威机构(CA)用自己的私钥对别人合法的公钥的散列值进行加密,也就是对别人的公钥进行数字签名,然后生成一个证书,来证明这个公钥是合法的,证书里面一般会包含:姓名、邮箱等个人信息;还有合法的公钥;以及CA施加的数字签名
      1. 证书的使用过程,如下图所示:


        证书的使用过程
    • 3. 基础知识总结:
      • (1). 对称加密,加密解密用的同一个密钥,加密解密速度快 ,但是无法解决密钥配送问题
      • (2). 非对称加密,加密解密用的密钥不同,用公钥加密需用私钥解密,私钥加密用公钥解密,加密解密速度慢,可以解决密钥配送问题
      • (3). 单向散列函数,根据消息生成固定长度的散列值,可以用来防止数据被篡改
      • (4). 数字签名,用私钥加密消息的散列值,生成密文,接受者用公钥解密,进行对比
      • (5). 证书,用CA的私钥,对其他人的合法公钥生成数字签名,也就是用私钥对别人的合法公钥的散列值进行加密
    七、iOS签名机制
      1. 基础知识学完了,我们正式开始学习iOS的签名机制,iOS签名机制的作用就是:保证安装到用户手机上的APP,都是经过苹果官方允许的
      1. 真机调试和打包应用的时候,都会经历以下步骤:
      • 生成.certSigningRequest文件

      • 获得ios_development.cer \ ios_distribution.cer证书文件

      • 注册device、添加App ID

      • 获得*.mobileprovision文件

      1. 上述的步骤每一步都做了什么事情呢?生成的这些文件包含了什么呢?听我娓娓道来:
      • CertificateSigningRequest.certSigningRequest文件,其实就是Mac设备的公钥
        .certSigningRequest.png
    • ios_development.cer、ios_distribution.cer文件,其实就是用Apple后台的私钥,对Mac设备的公钥进行签名后的证书文件

      证书.png
    • .mobileprovision文件就是把.cer、devices设备ID、App ID、entitlements权限文件放在一起,用Apple的私钥做了一次数字签名

    mobileprovision文件
      1. iOS签名机制的整个流程如下:(每台iPhone上都会有Apple的公钥)
        iOS签名机制流程图
      1. 如果App是通过打包或者真机调试安装到手机上的话,都会经历以下的安全检测,如果有一项不匹配,就无法安装
        安全检测.png
      1. 如果App是从AppStore下载安装的,你会发现里面是没有mobileprovision文件的,它的验证流程会简单很多,如下所示:
        AppStore下载的验证流程.png
    八、iOS重签名
      1. 我们使用codesign命令,对App进行重签名,步骤如下:
      • (1). 准备一个embedded.mobileprovision文件,必须是付费证书产生的,appid、device一定要匹配,准备好后,放入.app包中
        • 可以通过Xcode自动生成,然后再编译后的APP包中找到
        • 也可以通过开发者证书网站生成下载
      • (2). 从embedded.mobileprovision文件中提取出entitlements.plist权限文件,命令如下:
    security cms -D -i embedded.mobileprovision > temp.plist
    /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist  > entitlements.plist
    
    • (3). 通过以下命令,查看可用的证书,并拿到证书ID
    security find-identity -v -p codesigning
    
    • (4). 对.app内部的动态库、AppExtension等进行签名
    codesign -fs 证书ID xxx.dylib
    
    • (5). 对.app包进行重签名
    codesign -fs 证书ID --entitlements entitlements.plist  xxx.app
    
      1. 除了使用命令行重签名以外,我们还可以使用GUI图形化工具进行重签名,这里推荐两个比较好用的工具:
      • iOS App Signer,可以对.app重签名打包成.ipa,需要再.app包中提供对应的embedded.mobileprovision文件

      • iReSign,可以对ipa进行重签名,需要提供entitlements.plist、embedded.mobileprovision文件的路径

    九、对tweak项目进行重签名
    • 1. 准备好tweak项目的App包,还有通过tweak生成的dylib库
      • (1). 拿到脱壳后的ipa文件,具体脱壳方法可以看这里,一键脱壳,以便后续使用

      • 也通过MJAppTools工具MJAppTools -l命令,找到微信的Mach-O可执行文件路径 ,通过iFunBox将其拖出来,然后用class-dump进行脱壳,以便后续使用

      • (2). 通过iFunBox,在手机的Device/Library/MobileSubstrate/DynamicLibraries目录中,找到通过tweak生成的WeChatTest.dylib库,拖出来以便后续使用

      • (3). 将App包中的Info.plist文件里的设备列表UISupportedDevices删掉,并保存,主要为了防止安装时报不支持设备的错误

    • 2. 从苹果开发者网站准备一个embedded.mobileprovision文件,必须是付费证书产生的,appid、device一定要匹配,准备好后,放入App包中
    • 3. 使用insert_dylib库dylib动态库注入到Mach-O文件中
      • (1). 将下载好的insert_dylib库进行编译,拿到release版本的insert_dylib库,将其放入到mac的/usr/local/bin目录下,这样就可以在命令行里使用insert_dylib命令了

      • (2). 命令格式是:insert_dylib 动态库加载绝对路径 Mach-O文件,这个命令有两个常用的参数:--weak,及时动态库找不到也不会报错;--all-yes,后面的所有选项都是yes

    @executable_path代表可执行文件所在的目录
    @loader_path代表动态库所在的目录
    
    将tweak_xxx.dylib注入到MachO_XXX文件中,命令如下 :
    insert_dylib @executable_path/tweak_xxx.dylib MachO_XXX  --weak --all-yes
    
    将WeChatTest.dylib注入到WeChat可执行文件中,命令如下:
    insert_dylib @executable_path/WeChatTest.dylib WeChat --weak --all-yes
    
    • 4. 使用在mac命令行,输入otool -L Mach-O可执行文件命令,查看dylib库的依赖文件,我们发现tweak生成的dylib库依赖CydiaSubstrate库,所以想要在非越狱手机上安装,就必须把CydiaSubstrate库也注入到Mach-O文件中
    使用otool命令,找到WeChatTest.dylib的依赖库
    otool -L WeChatTest.dylib
    
    输出了下面这个,证明WeChatTest.dylib依赖CydiaSubstrate
    /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
    
    • 5. 在手机上的Device/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate,找到CydiaSubstrate库,拖出来,以便后续使用
    • 6. 由于非越狱设备中没有CydiaSubstrate库,所以要把CydiaSubstrateWeChatTest.dylib放在同一个目录下,并且更改WeChatTest.dylib中的CydiaSubstrate库的加载地址,命令是:install_name_tool -change 旧地址 新地址 Mach-O文件
    更改WeChatTest.dylib中的CydiaSubstrate库的加载地址
    install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/CydiaSubstrate  WeChatTest.dylib
    
    • 7. 对动态库进行重签名,命令是:codesign -fs 证书ID xxx.dylib
    查看所有可用证书,选择合适的证书,进行重签名
    security find-identity -v -p codesigning
    
    先对CydiaSubstrate进行重签名
    codesign -fs 2E377710143F8F007535CA3791B29FBDBF173BB9 CydiaSubstrate
    
    再对WeChatTest.dylib进行重签名
    codesign -fs 2E377710143F8F007535CA3791B29FBDBF173BB9 WeChatTest.dylib
    
    • 8. 用iOS App Signer对.app包进行重签名,需要将CydiaSubstrate、WeChatTest.dylib都放入.app包中,在进行重签名,iOS App Signer会自动给Framework、dylib、AppExtension、WatchApp、.app包重新签名
    image.png
    • 9. 使用iFunBox工具把签好名的ipa包,安装到非越狱手机上,如果安装失败,可以打开控制台,查看安装失败的日志找原因
    十、总结一下

    整个逆向、重签名过程的原理,其实非常简单,如下所示,假设我们要为微信开发插件

      1. 通过Theos生成一个dylib动态库: A.dylib(为了方便叙述,我们称它为A.dylib动态库)
      1. 通过insert_dylibA.dylib注入到脱壳后微信的可执行文件中,把A.dylib和它依赖的CydiaSubstrate库一起放到WeChat.app包中,也就是跟微信可执行文件同一个目录下 (一键脱壳的方法
    寻找A.dylib库
    在手机的Device/Library/MobileSubstrate/DynamicLibraries目录中,可以找到通过tweak生成的A.dylib库
    
    寻找CydiaSubstrate库
    在手机上的Device/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate,可以找到CydiaSubstrate库
    
    注入A.dylib到WeChat可执行文件
    insert_dylib @executable_path/A.dylib WeChat --weak --all-yes WeChat
    
      1. 修改A.dylibCydiaSubstrate库的加载路径,把绝对路径改成相对路径
    install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/CydiaSubstrate  WeChatTest.dylib
    
      1. WeChat.app包中的Info.plist文件里的设备列表UISupportedDevices删掉,并保存,主要为了防止安装时报不支持设备的错误
      1. WeChat.app包中的所有Info.plist文件里的com.tencent.xin都改成你想改的BundleID,例如我就改成:com.test888.888,包括插件、扩展里的。(大部分的com.tencent.xin都需要改,要是不知道作用的话,建议你全改)
      1. 从苹果开发者网站准备一个embedded.mobileprovision文件,必须是付费证书产生的,appid、device一定要匹配,准备好后,放入WeChat.app包中
      1. 使用codesign命令对A.dylibCydiaSubstrate库进行重签名
    查看所有可用证书,选择合适的证书,进行重签名
    security find-identity -v -p codesigning
    
    先对CydiaSubstrate进行重签名
    codesign -fs 2E377710143F8F007535CA3791B29FBDBF173BB9 CydiaSubstrate
    
    再对WeChatTest.dylib进行重签名
    codesign -fs 2E377710143F8F007535CA3791B29FBDBF173BB9 A.dylib
    
      1. 使用iOS App Signer对WeChat.app包进行重签名,证书一定要选择对,然后通过iFunBox安装到手机即可,遇到错误查看控制台日志 (由于上面已经改过了BundleID,这里就不需要再改了)
        iOS App Signer会给包里的所有动态库、插件、扩展进行签名.png
      1. 以上这么多步骤,就是为了模拟真机调试的过程,为啥描述文件要命名为embedded.mobileprovision呢,因为真机调试的时候,苹果就把描述文件命名为embedded.mobileprovision,你可以在真机调试的.app包中查看,通过这些步骤,让苹果设备误以为你是真机调试,就可以把逆向的App安装到非越狱的手机上啦。

    相关文章

      网友评论

          本文标题:iOS逆向工程(十一):iOS签名机制

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