13 KiB
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一家网络安全公司工作吗?你想在HackTricks中看到你的公司广告吗?或者你想获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
-
发现我们的独家NFTs收藏品The PEASS Family
-
加入 💬 Discord群组 或 Telegram群组 或 关注我在Twitter上的🐦@carlospolopm。
-
通过向hacktricks仓库和hacktricks-cloud仓库提交PR来分享你的黑客技巧。
自定义URL scheme允许应用程序通过自定义协议进行通信。应用程序必须声明对这些scheme的支持,并处理使用这些scheme的传入URL。
URL scheme提供了一种潜在的攻击向量,因此请确保验证所有URL参数并丢弃任何格式错误的URL。此外,将可用的操作限制为不会危及用户数据的操作。
例如,URI:myapp://hostname?data=123876123
将调用已注册了scheme mydata
的应用程序(即与hostname hostname
相关的操作),并发送带有值123876123
的参数data
。
一个脆弱的例子是2010年发现的Skype Mobile应用程序中的以下漏洞:Skype应用程序注册了skype://
协议处理程序,这允许其他应用程序触发对其他Skype用户和电话号码的呼叫。不幸的是,Skype在拨打电话之前没有向用户请求权限,因此任何应用程序都可以在用户不知情的情况下拨打任意号码。攻击者通过放置一个不可见的<iframe src="skype://xxx?call"></iframe>
(其中xxx
被一个高级号码替换)来利用此漏洞,因此任何不经意访问恶意网站的Skype用户都会拨打高级号码。
你可以在应用程序的Info.plist
文件中找到应用程序注册的scheme,搜索**CFBundleURLTypes
**(例如来自iGoat-Swift的示例):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.iGoat.myCompany</string>
<key>CFBundleURLSchemes</key>
<array>
<string>iGoat</string>
</array>
</dict>
</array>
然而,请注意恶意应用程序可以重新注册已被应用程序注册的URI。因此,如果您通过URI发送敏感信息(myapp://hostname?password=123456),恶意应用程序可以拦截带有敏感信息的URI。
此外,这些URI的输入应该经过检查和清理,因为它可能来自试图利用SQL注入、XSS、CSRF、路径遍历或其他可能的漏洞的恶意来源。
应用程序查询方案注册
应用程序可以调用canOpenURL:
来验证目标应用程序是否可用。然而,由于这种方法被恶意应用程序用作枚举已安装应用程序的方式,从iOS 9.0开始,传递给它的URL方案也必须在应用程序的Info.plist
文件中添加LSApplicationQueriesSchemes
键,并包含最多50个URL方案的数组。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>url_scheme1</string>
<string>url_scheme2</string>
</array>
canOpenURL
将始终对未声明的scheme返回NO
,无论是否安装了适当的应用程序。然而,这个限制只适用于canOpenURL
。
测试URL处理和验证
为了确定URL路径是如何构建和验证的,如果你有原始的源代码,你可以搜索以下方法:
application:didFinishLaunchingWithOptions:
方法或application:will-FinishLaunchingWithOptions:
:验证决策是如何做出的以及如何检索URL的信息。application:openURL:options:
:验证资源是如何被打开的,即数据是如何被解析的,验证options,特别是是否允许或拒绝调用应用程序(sourceApplication
)访问。当使用自定义URL scheme时,应用程序可能还需要用户权限。
在Telegram中,你将找到四种不同的方法被使用:
func application(_ application: UIApplication, open url: URL, sourceApplication: String?) -> Bool {
self.openUrl(url: url)
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?,
annotation: Any) -> Bool {
self.openUrl(url: url)
return true
}
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
self.openUrl(url: url)
return true
}
func application(_ application: UIApplication, handleOpen url: URL) -> Bool {
self.openUrl(url: url)
return true
}
测试向其他应用程序发送URL请求
方法openURL:options:completionHandler:
和已弃用的UIApplication
的openURL:
方法负责打开URL(即向其他应用程序发送请求/进行查询),该URL可能是当前应用程序的本地URL,也可能是由其他应用程序提供的URL。如果您有原始源代码,可以直接搜索这些方法的用法。
此外,如果您想知道应用程序是否正在查询特定的服务或应用程序,并且该应用程序是众所周知的,您还可以在线搜索常见的URL schemes,并将它们包含在您的greps(liOS应用程序scheme列表**)**中。
egrep -nr "open.*options.*completionHandler" ./Telegram-iOS/
egrep -nr "openURL\(" ./Telegram-iOS/
egrep -nr "mt-encrypted-file://" ./Telegram-iOS/
egrep -nr "://" ./Telegram-iOS/
测试废弃的方法
搜索废弃的方法,例如:
例如,在这里我们找到了这三个方法:
$ rabin2 -zzq Telegram\ X.app/Telegram\ X | grep -i "openurl"
0x1000d9e90 31 30 UIApplicationOpenURLOptionsKey
0x1000dee3f 50 49 application:openURL:sourceApplication:annotation:
0x1000dee71 29 28 application:openURL:options:
0x1000dee8e 27 26 application:handleOpenURL:
0x1000df2c9 9 8 openURL:
0x1000df766 12 11 canOpenURL:
0x1000df772 35 34 openURL:options:completionHandler:
...
调用任意URL
- Safari: 要快速测试一个URL scheme,你可以在Safari中打开URL并观察应用程序的行为。例如,如果你写入
tel://123456789
,Safari将尝试拨打该号码。 - Notes App: 长按你写的链接以测试自定义URL scheme。记得退出编辑模式以便能够打开它们。请注意,只有在安装了应用程序时,你才能点击或长按包含自定义URL scheme的链接,否则它们不会被标记为“可点击的链接”。
- IDB:
- 启动IDB,连接到你的设备并选择目标应用程序。你可以在IDB文档中找到详细信息。
- 转到URL Handlers部分。在URL schemes中,点击Refresh,在左侧你将找到正在测试的应用程序中定义的所有自定义scheme的列表。你可以通过点击右侧的Open来加载这些scheme。通过简单地打开一个空的URI scheme(例如,打开
myURLscheme://
),你可以发现隐藏的功能(例如,调试窗口)并绕过本地身份验证。 - Frida:
如果你只想打开URL scheme,你可以使用Frida来实现:
$ frida -U iGoat-Swift
[iPhone::iGoat-Swift]-> function openURL(url) {
var UIApplication = ObjC.classes.UIApplication.sharedApplication();
var toOpen = ObjC.classes.NSURL.URLWithString_(url);
return UIApplication.openURL_(toOpen);
}
[iPhone::iGoat-Swift]-> openURL("tel://234234234")
true
在这个来自Frida CodeShare的示例中,作者使用非公开的API LSApplicationWorkspace.openSensitiveURL:withOptions:
来打开URL(来自SpringBoard应用程序):
function openURL(url) {
var w = ObjC.classes.LSApplicationWorkspace.defaultWorkspace();
var toOpen = ObjC.classes.NSURL.URLWithString_(url);
return w.openSensitiveURL_withOptions_(toOpen, null);
}
请注意,非公开API的使用在App Store上是不允许的,这就是为什么我们甚至不测试这些API,但我们可以在动态分析中使用它们的原因。
Fuzzing URL Schemes
如果应用程序解析URL的某些部分,你还可以执行输入模糊测试以检测内存损坏漏洞。
我们上面学到的知识现在可以用来构建你自己选择的语言(例如Python)的模糊测试器,并使用Frida的RPC调用openURL
。该模糊测试器应该执行以下操作:
- 生成有效载荷。
- 对于每个有效载荷,调用
openURL
。 - 检查应用程序是否在
/private/var/mobile/Library/Logs/CrashReporter
中生成崩溃报告(.ips
)。
FuzzDB项目提供了可以用作有效载荷的模糊测试字典。
使用Frida进行模糊测试
使用Frida进行这个操作非常简单,你可以参考这篇博文来查看一个在iGoat-Swift应用程序上进行模糊测试的示例(适用于iOS 11.1.2)。
在运行模糊测试器之前,我们需要将URL schemes作为输入。从静态分析中,我们知道iGoat-Swift应用程序支持以下URL scheme和参数:iGoat://?contactNumber={0}&message={0}
。
$ frida -U SpringBoard -l ios-url-scheme-fuzzing.js
[iPhone::SpringBoard]-> fuzz("iGoat", "iGoat://?contactNumber={0}&message={0}")
Watching for crashes from iGoat...
No logs were moved.
Opened URL: iGoat://?contactNumber=0&message=0
参考资料
{% embed url="https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-object-persistence-mstg-platform-8" %}
☁️ HackTricks 云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
你在一家 网络安全公司 工作吗?想要在 HackTricks 中 宣传你的公司 吗?或者你想要获得 PEASS 的最新版本或下载 HackTricks 的 PDF 版本 吗?请查看 订阅计划!
-
发现我们的独家 NFTs 集合 The PEASS Family
-
加入 💬 Discord 群组 或 Telegram 群组,或者在 Twitter 上 关注 我 🐦@carlospolopm。
-
通过向 hacktricks 仓库 和 hacktricks-cloud 仓库 提交 PR 来分享你的黑客技巧。