iOS应用中的凭证与密钥挖掘:低悬苹果的快速收获

本文详细介绍了如何在iOS应用中挖掘硬编码的凭证和API密钥,涵盖静态与动态分析技术,使用Frida和Objection工具快速提取敏感信息,适合安全研究人员和开发者参考。

iOS应用中的低悬苹果:凭证与密钥挖掘

动机

直接深入逆向工程iOS应用可能令人望而生畏且耗时。虽然长期来看深入二进制文件会有很大回报,但从简单的胜利开始也很有用,尤其是在时间和资源有限的情况下。其中一个简单的胜利就是在iOS应用中挖掘登录凭证和API密钥。

大多数iOS应用使用第三方API和SDK,如Twitter、Amazon Web Services等。与这些API交互需要API密钥,这些密钥在应用中使用(并因此存储)。粗心的开发者很容易泄露权限过多的密钥,或者本不应存储在客户端的密钥。

为什么找到这些密钥是简单的胜利?正如顶级iOS开发者Mattt Thompson所述:

无法保护存储在客户端的秘密。一旦有人能在自己的设备上运行你的软件,游戏就结束了。

他还告诉我们:

2018年发表的另一篇论文发现,在100个热门iOS应用样本中,有68个存在SDK凭证滥用问题。

直到API和开发者认识到客户端秘密在设计上就是不安全的,iOS应用中总会存在这些低悬的漏洞。

技术

Mattt Thompson分享了开发者(不安全地)在应用中存储客户端秘密的三种方式:

  1. 在源代码中硬编码秘密
  2. 在Info.plist中存储秘密
  3. 使用代码生成混淆秘密

对于前两种方法,我们可以使用静态分析并通过解密的应用文件进行grep来暴露这些秘密。对于混淆的秘密,我们可以通过Frida的动态分析魔法来短路混淆,节省数小时的反向工程时间。这就是我为漏洞赏金计划提取AWS客户端和秘密密钥的方式。

以下演练假设您已根据我的iOS应用渗透测试快速入门文章设置了iOS测试环境。

静态分析

静态分析从提取目标.ipa文件开始。确保已安装iproxy和frida-ios-dump。

  1. 在一个终端中,运行iproxy 2222 22
  2. 在iDevice上打开目标应用
  3. 在另一个终端中,运行./dump.py <应用显示名称或包标识符>
  4. 现在当前目录中应有一个<应用名称>.ipa文件
  5. mv <应用名称>.ipa <应用名称>.zip
  6. unzip <应用名称>.zip
  7. 文件现在解压到Payload文件夹;打开它并检查是否已创建<应用名称>.app文件(.ipa和.app文件之间的<应用名称>可能不同)
  8. mkdir AppFiles
  9. mv Payload/<应用名称>.app/* AppFiles/

此时,您应在AppFiles目录中看到一堆文件。虽然文件显然因应用而异,但以下是一些需要查看的关键文件。

Info.plist和其他.plist文件*:Info.plist的功能类似于Android应用的manifest.json。它包含应用元数据,并可以指出弱点或新的攻击面,如自定义方案URL。当然,它也可以包含存储的凭证。您可以使用macOS内置的plutil命令以JSON格式整齐地布局数据:plutil -p Info.plist

一些plist文件可以以二进制而非XML存储,这使得直接解析更加困难。运行plutil -convert xml1 Info.plist将它们转换回XML。

快速提示:虽然GoogleService-Info.plist存在于许多应用中,并包含一个极其诱人的API_KEY值,但这并不是敏感凭证。它需要与自定义令牌配对才能产生任何影响。并非所有API密钥都是平等的;一些具有适当的访问控制,可以无风险地暴露。查看keyhacks以快速识别和验证敏感API密钥。

您还希望开始grep和解析各种文件;grep "API_KEY" -r *或类似命令是一个快速而肮脏的解决方案。

此时,您还应探查提示有漏洞功能的有趣文件。检查html文件(可能有一个内部URL方案易受DOM XSS攻击?)、模板以及可能具有已知漏洞的第三方框架。

幸运的话,您可能会轻松获得直接的凭证暴露。

动态分析

大多数时候,事情不会那么直接。然而,有一些线索可能指向混淆的凭证。

在一个漏洞赏金计划中,我注意到我正在测试的应用将个人资料图片上传到S3存储桶,但请求被隐藏以拦截,并且凭证未以明文形式存储在应用文件中。然而,鉴于上传正在发生,可以安全地假设正在交换凭证。

此时,我可以使用Ghidra深入二进制文件,并尝试遍历混淆代码以解密凭证,但有一种方法可以短路整个过程。

这样想:最终,无论使用多少混淆,凭证都需要以明文形式(对于不安全的实现)发送到服务器。为此,需要在代码中的某个地方调用使用这些凭证的方法。

这就是Frida和Objection的用武之地。您希望挂钩到进行该调用的方法,并转储该方法的参数——这应该是您正在寻找的凭证。

首先,您需要识别方法。使用objection --gadget <应用名称> explore启动Objection。接下来,运行ios hooking list classes以转储应用中所有可用的类。这是一个巨大的列表。通过grep遍历列表并识别有趣的类。例如,我查找了名称中包含AWS或Amazon的类。幸运的是,有一个AWSCredentials类,以及其他有趣的类名。

接下来,您希望开始监视这些类。在Objection控制台中为每个类运行ios hooking watch class <类名>。现在,在应用中执行可能暴露潜在漏洞凭证的操作。在这种情况下,我执行了应用中的个人资料图片上传功能,这触发了以下响应:

1
2
3
4
(agent) Watching method: - initKey:
(agent) Watching method: - initSDK:
(agent) Registering job gk6i5disc88. Type: watch-class-methods for: AWSCredentials
myApp on (iPhone: 13.1.2) [usb] # (agent) [gk6i5disc88] Called: [AWSS3Client initKey:] (Kind: instance) (Super: AWSClient)

太棒了。看起来Frida成功挂钩到AWSCredentials类,其中包括initKey和initSDK方法。当我执行个人资料图片上传时,调用了initKey方法。

现在,我们希望转储传递给initKey类方法的参数。在objection中,运行ios hooking watch method "-[AWSCredentials initKey:]" --dump-args。请注意,这里类方法的格式是"-[<类名> <方法>:]"。我再次在应用中执行了个人资料图片上传。

1
2
(agent) [gk6i5disc88] Called: -[AWSCredentials initKey:] 1 argument(Kind: instance) (Super: NSObject)
(agent) [gk6i5disc88] Argument dump: [AWSCredentials initKey: <AWS客户端密钥>:<AWS秘密密钥>]

成功!使用动态分析,我暴露了应用使用的AWS密钥。当然,这意味着应用正在使用与S3的不安全通信协议,因为有无凭证的方式可以实现S3上传。

结论

在iOS应用中挖掘秘密是一项低努力、高回报的任务,可以帮助您轻松进入应用渗透测试。(不幸的是,秘密管理仍然是一个难题,尤其是对于经验不足的开发者,并且继续作为一个反复出现的漏洞出现。很容易忘记,即使编译到应用二进制文件中,凭证仍然暴露。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计