问题描述
我的目标是执行类似于 How to get access to iOS Developer Certificate from code 的操作:验证我的库没有在重新打包的 IPA 中使用。那里的答案建议解析 embedded.mobileprovision
文件以查看有关证书和配置文件的信息。
在 embedded.mobileprovision
文件中,我可以找到一个很长的嵌入 plist,我看到的 XML 有两个相关字段:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AppIDName</key>
…
<key>application-identifier</key>
<string>ABCDEFGHIJ.com.example.ObjCExample</string>
…
<key>UUID</key>
<string>00000000-0000-0000-0000-000000000000</string>
…
<key>Version</key>
<integer>1</integer>
</dict>
</plist>
(出于显而易见的原因,我用 ABCDEFGHIJ
替换了真正的 DEVELOPMENT_TEAM ID,用零替换了 UUID)。
在键 <data>
下还有一个 list 长 DeveloperCertificates
条目数组,但我不知道如何使用这些数据。例如,我不知道我是否可以始终选择这些证书之一。但是我在这个文件中没有看到签名证书 ID,而且我也没有一个可靠的程序来解析 embedded.mobileprovision
文件。
不过,这对于我的目的来说可能已经足够了,但我还有另一种更强大的方法。我可以解析我的二进制文件的 mach_header
,按照 example 的 Dave DeLong 并基于 earlier answer 的 Cédric Luthi。 LC_CODE_SIGNATURE
的格式似乎比 embedded.mobileprovision
文件的格式更好。
具体来说,EMbedDED_ENTITLEMENTS
blob(魔术0xfade7171
)包含一个简短的纯文本 plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>ABCDEFGHIJ.com.example.ObjCExample</string>
<key>com.apple.developer.team-identifier</key>
<string>ABCDEFGHIJ</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>ABCDEFGHIJ.com.example.ObjCExample</string>
</array>
</dict>
</plist>
到目前为止一切顺利,但我不确定相同的 XML 将如何查找来自 AppStore 的应用程序。例如,有一个新的 EMbedDED_ENTITLEMENTS_DER
blob (0xfade7172
) 似乎包含相同的 plist,但采用二进制格式( 是否有一个示例说明如何解析它?).
此外,我在 Apple Development: alexcohn@mycompany.com (KLMnopQRST)
blob(魔术 REQUIREMENTS
)中看到签名证书 ID 0xfade0c01
,并且按照 go package 的流程,我可以找到此 ID以编程方式在我的可执行文件中。
哪个证书 ID 对我来说更可靠?
要求很简单:
- 当应用退出时,这个 ID 应该改变,即使它没有为 App Store 退出。
- 此 ID 应存在于调试版本和发布版本中(它们可能是不同的 ID)。
- 此 ID 应该稳定,即当开发者重新构建应用、切换构建机器或将新设备添加到 adHoc 配置文件时,它不应更改。
- 此 ID 应该很容易找到(就像签名证书在钥匙串应用中可见一样)。
解决方法
好的,所以我在 github 上找到了 this repo,现在我可以提取(并验证)签名证书的正确 SHA256 签名,该签名以标准 PKCS7 格式存储在 -
blob 中0xfade0b01
命令。
缺点是我只是为此导入了整个 openssl library。有没有办法在内置 SecCertificate 类的帮助下解析这个 blob?另一个悬而未决的问题,也许嵌入式 openssl lib 比系统框架更能抵御逆向工程和 Frida 式注入攻击?