clash 节点切换
很多 Android 组件都有响应外部链接的能力,如果攻击者能随意的指定这些组件所响应的 url,轻则可以引导被攻击的 APP 弹出钓鱼页面,重则可能远程执行恶意 js 代码。因此 APP 开发者必然要对传入的 url 进行校验,而设置域名白名单就是一种简单常见且具有较高安全性的防御方法。
然而由于一些开发者并不完全通晓调用方法的底层特性clash 节点切换,使得看起来万无一失的白名单校验形同虚设。本文列举几种常见的 Android 域名白名单校验写法,并深入源码指出其中存在的风险和绕过方法。
可以看到 getHost和 loadUrl 的表现不一致,if检验跳转目标是legitimate.com,但执行时浏览器会把反斜线纠正为正斜线去访问attacker.com。那么如果是用 equals 来做完整的 host 检验该怎么办呢?只需加一个‘@’就能隔断非法前缀。
就在这里把@符号之前内容的作为 UserInfo 给切断了,host 内容从@符号之后算起。(这里其实存在另一个 bug,没有考虑多个@的情况)
所以安全补丁日期早于2018-04-01的系统都受影响,而 Google 一般通过协议要求 OEM 厂商保证产品上市之后两年内按期打安全补丁。那么经过推算得出 Android 6及以下的系统都受影响。
上一节提到了@的截取的特性,会把恶意地址前缀attacker.com存入 UserInfo,那么现在改进校验方法,加上UserInfo 的检查是不是就万无一失了呢?
从输出日志可以看到,通过此反射方法构造的 Uri 对象,可以通过check_v2方法对Scheme、UserInfo和Host的三项检验,但 toString 方法的值,才是被攻击的 Activity 拉起的实际地址。如前所述,@符号之后的attacker.com便成为了最终访问的 host。
截止到目前——Android Q Beta 4,还是有绕过的方法[6], 关于绕过原理的梳理不在本文议题范围。
抵御这种攻击的方法也非常简单,对传入的 Uri 对象加一次 parse 再做check_v2即可
事实上,有大量的开发者因为不了解这个性质,认为传入的 url 已经是“正常“通过Uri.parse构造的,直接信任放行。
我们知道,通过在组件中注册intent-filter,App 可以响应浏览器应用或短信应用访问的外链。
典型的一个配置写法如下,只有data标签中指定的内容和 Intent 中携带的 Data 完全一致时,当前活动才能响应该 Intent。
然而,对于第一个链接,浏览器会自动把反斜杠 纠正为正斜杠 /。对于第二个链接,反斜杠 会以 URL 编码形式保留而无法触发方法1。
通过仔细研究intent://scheme的工作机制[7],发现可以通过如下方式保留反斜杠 的方法:
小米安全中心致力于保障小米旗下所有产品及广大用户的信息安全,希望通过白帽子提交漏洞的方式加强自身业务安全及业界合作。我们承诺:每一份报告我们都会有专人进行评估和跟进,会给予白帽子与之匹配的利益。返回搜狐,查看更多