iOS逆向 - 应用签名原理及重签名 (重签微信应用实战)

  • 玩逆向的目的 ?

    • 为了应用安全 , 我们首先要知道 Hackers 都是怎么做的 , 他们如何做到可以调试我们的应用 . 在此基础上我们才能知道如何更有效的进行防护.
  • 在逆向的路上 , 很重要的一步就是应用重签名 , 以此达到调试别人应用的目的.

  • 想知道如何重签名 , 首先要知道 iOS 应用签名的原理 .

提示 :

本篇文章建立在对加密和签名有一定了解的基础上 . 如不太熟悉建议阅读前一篇博客 RSA加密原理&密码学&HASH 或者其他密码学以及签名文章.

废话不多说 , 开始.

iOS 应用签名原理

签名

为什么用签名这个词 . 因为老外喜欢用支票 , 支票上面的签名能够证明这玩意是你的 . 那么数字签名顾名思义 , 就是用于鉴别数字信息的方法

代码签名

代码签名是对可执行文件或脚本进行数字签名 . 用来确认软件是被认可的 , 且在签名后未被修改或损坏的措施。和数字签名原理一样 , 只不过签名的数据是代码而已.

其具体验证措施如下 :

发布者 将源代码散列后的 HASH 值使用私钥进行加密然后和源代码一起产生一个软件包 . 那么 验证端/使用端 收到后使用公钥解密拿到 HASH , 并使用 HASH 算法对源代码进行散列 , 将得到的结果进行比对 , 如果一致 , 则说明数据没有被篡改过 , 并且确实是由发布者发布的应用 .

苹果的应用安装需求

iOS 出来之前 , 以前的主流操作系统( Mac/Windows ) 软件随便从哪里下载都能运行 , 系统安全存在隐患 , 盗版软件 , 病毒入侵 , 静默安装等等 . 那么苹果希望解决这样的问题,要保证每一个安装到 iOS 上的 APP 都是经过苹果官方允许的,怎样保证呢 ? 就是通过代码签名。

那么首先怎么实现呢 ?

  • 苹果服务器有一个私钥 , 每台设备上有一个公钥 . 以此来保证每个安装的应用都是经过苹果服务器的允许的 .

这样确实可以保证 , 但是我们还有开发者 , 需要通过 Xcode 在开发阶段就能安装应用 , 另外还有企业证书 . 所以 实际上 , 苹果的签名机制是双层签名 .

iOS 应用签名流程

整个完整流程如上图 , 接下来我们结合实际操作来剖析一下其原理 .

1. 开发时期 , 申请证书

在我们希望安装开发好的程序到 iPhone 上时 , 我们都知道需要去开发者中心配置一下证书 .

  • MAC 通过钥匙串访问生成请求 CSR 文件. 这一步骤其实就是 MAC 生成了一对 公私钥M , 将 公钥M 放到请求文件 CSR 中上传给苹果服务器 .

  • 苹果服务器利用 私钥A公钥M 进行数字签名 ( 其实就是对 公钥M 值进行非对称加密 , 然后保存了 公钥MHASH ) , 生成的结果就是 证书 .

  • 然后用户继续添加设备 UDID , 选择证书 , 配置所需权限 . 生成描述文件 .

  • 当用户下载下来 / Xcode 自动管理把证书下载下来之后 , 钥匙串访问就会将证书和 MAC 中的 私钥M ( 就是我们所熟知的 p12 ) 进行关联 .

2. 编译安装

Xcode 在我们选择好了描述文件和开发者账户进行编译时 :

  • 首先 , Xcode 会利用证书锁所关联的 私钥M , 对 APP 进行代码签名 ( 将源文件的 HASH 值通过 私钥M 进行加密 ) . 然后会把描述文件和签名 以及可执行文件 MachO 一起打包 .

  • 当这个步骤完成 . iPhone 手机要对该软件包进行校验 .

    • 首先 , 苹果根据 iOS 系统中的 私钥A 对描述文件中的证书进行解密校验 . 通过则意味着这个证书是苹果颁发的 , 也就是说是被许可的 .
    • 当第一步完成解密 , 就拿到了 公钥M , 然后进行 HASH 校验是否被篡改过 .
    • 拿到 公钥M 之后 , 使用 公钥M 去验证 APP 的签名 , 以此来验证 这个证书是不是这个 APP 的. ( 这也就是为什么别的小伙伴生成的证书需要把 p12 发给其他人来真机调试的原因 . )
    • 然后校验 UDID 等等.

这就是 iOS 应用完整的双层签名流程了. 讲完签名原理 , 不急着研究重签名 , 先打下点基础知识 , 来看看描述文件 .

描述文件

那么我们来看一下描述文件到底是个啥东西.

打开目录

/Users/**你的名字**/Library/MobileDevice/Provisioning Profiles
复制代码

随便选择一个 , 使用终端查看

security cms -Di 0b7f1352-7a1e-4800-b52b-f2fc35e550dd.mobileprovision
复制代码

往下找到一个 entitlementskey 和其 value .

<key>Entitlements</key>
	<dict>
	<key>aps-environment</key>
		 <string>development</string>
	<key>application-identifier</key>
		 <string>4NJV3PZG3A.com.libin.WMXJ</string>
	<key>keychain-access-groups</key>
		 <array>
		    <string>4NJV3PZG3A.*</string>
		 </array>
	<key>get-task-allow</key>
		 <true/>
	<key>com.apple.developer.team-identifier</key>
		 <string>4NJV3PZG3A</string>
	</dict>
复制代码

这个 entitlements 就是权力配置 , 在重签名中会使用到. 描述文件中还包含了所有 APP 的配置内容 , 大家有兴趣可以一一查看.

那么 , 苹果是如何签名的我们知道了 . 那问题来了 , 如何去做重签名 ?

iOS 应用重签名

其实 iOS 应用签名部分都是利用了 CodeSign 来完成的 . 我们可以利用终端来自己进行签名 .

目前市面上也有许多应用可以可视化完成重签 或者一键重签 . 或者利用写好的 shell 脚本来玩 . 对于初学者 . 个人建议还是按照最基础的方式操作几遍 , 理解了其原理 , 在使用其他工具碰到为题也比较好处理 , 当然 , 本篇文章会介绍如何手写 shell 来完成重签名. .

准备工具 / 包

pp助手

pp助手 for Mac : 用来下载砸完壳的应用.

下载完成打开 , 被阻拦非 App Stroe 下载的应用打开的解决办法就不再介绍了. 设置 - 安全性与隐私 / 或者使用终端都可以 .

找到越狱应用下载微信

下载 ipa 完成 , 重命名为 zip , 解压缩 找到 Payload - WeChat .

查看文件

应用签名

弄了半天 , 我们先来看看这个东西 . Iterm2 / 终端命令:

codesign -vv -d WeChat.app
复制代码

其中有一项 : Authority , 就是应用签名 .

那么我们现在要用我们自己的证书 去重新签名 .

MachO 文件

WeChat 文件显示包内容 , 找到一个黑框框 WeChat 文件.

这个就是我们经常提到的 MachO 文件了 . 后续我会专门讲解它 以及如何仔细查看.

现在我们先来简单查看一下 , 利用 otool 工具.

命令 : otool -l WeChat .

内容比较多 , 我们重定向一下 , 写到一个文件里.

命令 : otool -l WeChat > /Users/libin/Desktop/iOS进阶逻辑课程/逆向/WeChatMaCho.txt ( 名称和路径随便 ).

写完后我们打开文件 , 搜索 cryptid ,

注意 : cryptid0 , 代表你下载的是砸过壳的 , 而一般应用是 1 , 也就是加密过的 , 其实就是 AppStore 使用的对称性加密 , iPhone 在运行的时后解密( 并非安装时就解密 ).

写了这么多 , 终于要开始重签名了 . GO -->

步骤1 : 查看自己电脑上证书

命令: security find-identity -v -p codesigning . 选择一个 , 复制下来 .

这里我就不列举笔者自己的了.

还完全没有证书的小伙伴

先去申请一个吧 , 另外记得要选择 iPhone , 不要选成了 Mac

.

步骤2 : 删插件

  • 打开 WeChat , 显示包内容 . 找到 PlugIns 文件夹, 直接删除插件普通账号是签不了的.

  • 找到 Watch 文件夹 , 因为这里也有插件 , 我们暂时不需要 Watch , 直接删掉.

步骤3 : 重签 FrameWork

  • 进入 FrameWork 文件夹

  • 利用 CodeSign , 使用我们的证书进行重签名.

    codesign -fs "刚刚复制的你自己的证书名字" 要重签的FrameWork名称
    codesign -fs "iPhone Developer: ha ha (123456)" andromeda.framework
    FrameWork
    

步骤4 : 确保 MachO 执行权限

最简单的方式就是预览框中 , 黑色就代表可执行 , 灰色就代表不可执行 .

或者 命令 : ls -l WeChat , 结果是 -rwxr-xr-x 或者其他权限.

如果没有可执行权限 , 也就是 x 权限 , 可以通过 chmod +x WeChat 添加权限.

( 关于 Linux 权限和命令这块儿如果大家不是很清楚 , 留言一下 , 我后面补一篇文章详细讲讲 , 毕竟有些面试还是会问 , 不能只知道一个 777 , 因为很多是已经知道了 , 本文就暂不赘述了 )

步骤5 : 给包添加描述文件

因为我们下载的是上线包 , 肯定是没有描述文件这种东西在包里的 . 因此我们需要自己生成一个 .

    1. 打开 Xcode , 新建工程 我这里取名 WeChatDemo . 然后选择真机 , 选择开发者 , 自动 / 手动管理都可以 , 我这里勾选自动 , 然后运行 , 把这个空工程安装到手机上.
    1. 安装成功之后 , 把这个描述文件放到微信的包中.

步骤6 : 更改 Bundle ID

  • 微信包中找到 Info.plist
  • 修改 Bundle identifier
    • com.tencent.xin 改为你自己刚刚新建工程的 Bundle identifier 我这里为 com.libin.WeChatDemo

步骤7 : 通过授权文件(Entilements)重签.app包

  • 利用上文中我们说的查看描述文件方法 , 查看我们刚刚拷贝到微信包里的描述文件 . 也就是我们自己空工程生成的描述文件. 找到权力文件部分

  • 打开我们刚刚新建的 Xcode 工程 , 新建一个 Plist 文件 , Open As Source Code

  • 把上上图中描述文件的权利文件部分复制 , 粘贴到新建的 Plist 中 ,

    为了确保无误 可再次 Open As Property List 查看下. 其实就是为了得到一个 plist 文件备用. 也可以用其它方式.
  • 新建的 Plist 写好后 , Show In Finder . 将其放到微信包同路径中 , 方便操作.

  • 重点: 重签命令 --

codesign -fs "iPhone Developer: haha (123456)" --no-strict --entitlements=ent.plist WeChat.app

(注意替换自己的证书 , 文件)

见证奇迹的时刻

  • cmd + shift + 2
  • 点击加号 , 选择我们的微信包. (注意这一步之前最好检查下 微信包中 Bundle ID 有没有换成自己工程的 , 防止原版微信被替换了 )

注意看 , 手机上之前那个空工程变成了微信了 . ( 注意如果有安装失败的同学 , 先检查自己步骤有无错误 , 如没有 可尝试不使用 Xcode 自动生成证书以及描述文件 , 自己去开发者中心配置 , 选择.)

点击冒牌微信打开 , 微信项目启动了.

简单调试

打开附加 , 注意 , 如果你跟我一样有两个微信 , 那么哪个后开 , 哪个进程数字较大 . 因此自己判定哪个是冒牌的就好.

选择之后 注意看上方状态栏 , 变成 running 就好

然后就可以使用 view debug / LLDB , 添加符号断点等等调试方法了 .

由于篇幅问题 , 本文不多赘述了 , 后面会补充 shell 脚本自动重签实现 , 直接更换包实现 , 后续会继续就代码注入 等方面展开 .

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章