首页
社区
课程
招聘
贝壳APP渗透测试WP
发表于: 2024-6-1 12:44 30644

贝壳APP渗透测试WP

2024-6-1 12:44
30644

在贝壳找房APP上发现JSBridge鉴权绕过,TOKEN写入sdcard目录日志文件,HTTP明文传输COOKIE等安全问题。这是我第一次系统性渗透测试APP,写篇WP记录下

使用PIXEL 4手机,为Android 12系统

APP名为贝壳找房,包名com.lianjia.beike,版本号3.01.10,截至2024/05/07为最新版,小米应用市场下载

可以参考往期推送,《绕过最新版bilibili APP反Frida机制》,见文章末尾。Bypass.js脚本可以通用,应该都是用的某个安卓安全产品

抓包有两个地方会踩坑:1)要把Burp的证书安装为系统证书,贝壳APP不信任用户证书;2)贝壳APP默认不走系统设置的代理,要使用Drony等软件

对于问题1,可以使用Magisk的MoveCertificate模块[1]。对于问题2,Drony可在Google搜索下载,使用教程网上很多,不赘述

在AndroidMainfest.xml中可以看到如下SCHEME,使用lianjiabeike://等作为特征字符串即可搜集到大部分DEEPLINK

重点关注一些能发起网络请求的DEEPLINK,如下所示,调用该DEEPLINK可以指定URL打开一个WEBVIEW

在shell中打开该DEEPLINK可以使用命令am start -a android.intent.action.VIEW -W -d "lianjiabeike://web/main?url=URL编码(网页URL)"

配置Burp抓包后多操作一些APP功能,有意识地搜集一些WEB接口即可

重点关注/sdcard/Android/data/com.lianjia.beike目录下的落地文件,重点关注后缀名为log, js的文件,前者可能有敏感信息泄露问题,后者可能会作为页面/代码加载执行

在/sdcard/Android/data/com.lianjia.beike/cache/lianjia/com.lianjia.beike/log/beike目录发现.xlog文件,通过搜索发现xlog是腾讯mars日志模块产生的日志文件[3],并且不是纯文本格式,需要解码

JSBridge鉴权绕过是经典问题了,论文[2]发表于2022年,讨论了47个顶流APP的JSBridge鉴权漏洞,发表后各厂商更进修复了一轮

贝壳的JSBridge实现方式有点不同,如下所示,只有当DOMAIN在白名单内时才会调用addJavascriptInterface注册接口。也就是先鉴权,再注册JSBridge,而其它实现方式基本上是先注册JSBridge,调用接口时再鉴权

白名单如下,对于.开头的域名,表示匹配该域名的所有子域名,对于非.开头的域名,表示只匹配该域名。

为了方便调试,首先要通过HOOK手段打开APP内WEBVIEW的调试功能,通过重写android.webkit.WebView的构造函数强制调用setWebContentsDebuggingEnabled方法打开调试功能,代码如下

然后在Chrome浏览器中点击inspect即可调试对应WEBVIEW

先通过window.location="173K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6r3c8Q4x3X3g2W2K9r3!0E0k6i4m8S2P5g2)9J5k6h3y4G2L8g2)9J5x3W2!0q4y4g2)9^5z5q4)9^5y4#2!0q4y4W2)9^5c8q4!0m8x3W2!0q4y4g2)9^5z5q4!0n7x3q4!0q4y4q4!0n7z5q4)9^5x3q4!0q4y4q4!0n7z5q4!0m8b7g2!0q4y4g2)9&6b7#2!0m8z5q4!0q4y4#2)9&6z5g2!0n7c8q4!0q4y4g2)9&6x3q4)9^5c8q4!0q4y4g2)9^5c8q4)9&6y4g2!0q4z5g2)9^5y4#2)9^5b7#2!0q4z5g2)9&6c8q4!0m8x3W2!0q4y4#2)9&6b7g2)9^5y4q4!0q4y4g2)9&6c8W2)9&6c8W2!0q4y4g2)9&6x3q4)9^5c8q4!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4#2)9^5y4q4!0n7y4W2!0q4y4g2)9&6x3q4)9^5c8g2!0q4y4g2!0n7x3q4!0n7x3g2!0q4y4g2)9^5c8W2!0m8c8W2!0q4y4q4!0n7b7W2!0m8y4g2!0q4z5q4!0n7x3q4)9^5x3#2!0q4z5q4!0m8c8W2)9&6y4f1A6e0b7Y4u0A6k6r3N6W2i4@1f1^5i4@1t1H3i4K6R3K6i4@1f1%4i4K6V1@1i4@1p5^5i4@1f1$3i4K6V1$3i4@1t1&6i4@1f1$3i4@1t1K6i4K6V1#2i4@1f1K6i4K6R3H3i4K6R3J5i4@1f1#2i4@1p5$3i4K6R3J5i4@1f1@1i4@1t1^5i4K6S2n7i4@1f1$3i4K6R3&6i4K6R3H3i4@1f1%4i4@1p5@1i4@1u0m8i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1#2i4K6S2r3i4K6V1I4i4@1f1%4i4K6S2q4i4@1t1H3N6$3W2F1k6r3!0%4i4K6u0W2d9s2W2T1M7X3W2V1b7Y4u0A6k6r3N6W2e0p5A6Q4x3X3g2Q4y4h3k6Y4k6i4c8e0N6r3q4@1K9h3y4p5j5i4c8S2i4K6t1^5i4K6t1&6i4@1f1#2i4K6S2r3i4@1q4r3i4@1f1@1i4@1u0n7i4@1p5#2i4@1f1^5i4K6S2q4i4@1t1%4i4@1f1#2i4K6S2r3i4K6V1$3g2p5!0w2c8f1&6Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0g2Q4z5f1y4Q4b7e0S2Q4c8e0g2Q4b7f1g2Q4z5f1g2Q4c8e0W2Q4b7f1q4Q4z5p5y4Q4c8e0c8Q4b7U0S2Q4b7f1c8Q4c8e0g2Q4z5p5k6Q4z5e0q4Q4c8e0N6Q4z5p5g2Q4b7U0m8Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0g2Q4z5p5k6Q4b7f1q4Q4c8e0W2Q4z5f1y4Q4z5o6m8Q4c8e0S2Q4b7e0k6Q4z5o6q4Q4c8e0S2Q4b7f1k6Q4b7e0g2f1e0@1E0q4e0W2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4g2!0n7x3q4!0n7x3g2!0q4y4g2)9^5c8W2!0m8c8W2!0q4y4q4!0n7b7W2!0m8y4g2!0q4z5q4!0m8c8W2!0n7y4#2!0q4y4W2!0n7x3g2)9^5x3W2!0q4y4g2!0m8y4q4!0m8y4#2!0q4y4g2!0m8y4q4)9&6b7g2!0q4y4W2)9&6y4g2!0n7x3q4!0q4y4W2)9^5c8g2!0m8y4g2!0q4y4g2)9^5c8W2!0m8x3H3`.`.

我HOOK了checkDomainEffective方法,在观察日志时发现在WEBVIEW中返回上一个页面时不会调用该方法,于是想到一种可能的路径:进入PAYLOAD网页 -> 跳转至白名单URL注册JSBridge -> 返回上一个页面且保留了JSBridge。POC HTML代码及演示视频如下

白名单中的域名ehomepay.com正在出售,可以直接买了接管。bkjk.cn域名似乎已经废弃不用,查询whois信息发现今年9月份过期

将/sdcard/Android/data/com.lianjia.beike/cache/lianjia/com.lianjia.beike/log/beike目录下的xlog拉取到本地,使用mars库提供的日志解码脚本(decode_mars_nocrypt_log_file.py)成功解码日志。注意这个脚本需要python2环境运行

解码后发现TOKEN,如下所示

只要有该TOKEN就能请求绝大多数接口了,如下图所示。部分接口还需要Authorization HEADER字段,该字段的生成算法可以在APK中找到。

通过ADB打开61eK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3E0W2i4K6u0W2j5$3!0E0i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1#2i4K6S2r3i4K6V1I4i4@1f1%4i4K6S2q4i4@1t1H3b7@1!0a6d9@1W2q4i4@1f1#2i4K6S2r3i4@1q4r3i4@1f1@1i4@1u0n7i4@1p5#2i4@1f1%4i4@1u0n7i4K6S2r3i4@1f1^5i4@1u0r3i4K6R3%4d9q4c8f1f1q4!0q4y4q4!0n7b7#2!0m8x3q4!0q4z5q4!0n7c8g2)9&6x3#2!0q4c8W2!0n7b7#2)9^5b7#2!0q4y4q4!0n7b7#2)9&6b7g2!0q4y4g2!0m8c8W2!0n7b7#2!0q4z5q4)9^5y4#2!0n7y4q4!0q4y4q4!0n7z5q4!0m8c8q4!0q4z5g2)9&6y4#2!0n7y4q4!0q4y4q4!0n7b7g2!0n7b7g2!0q4y4W2)9&6y4q4!0n7b7W2!0q4y4g2)9^5y4#2!0n7b7W2!0q4x3#2)9^5x3q4)9^5x3X3q4V1j5R3`.`. shell am start -a android.intent.action.VIEW -W -d "lianjiabeike://web/main?url=580K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3E0W2i4K6u0W2j5$3!0E0"

还有很多攻击面没有探索,比如DEEPLINK打开WEBVIEW时由于携带COOKIE可能会有CSRF问题,以及绑定第三方账号的接口。

[1] f1eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6&6M7K6p5J5x3K6q4Q4x3V1k6y4L8%4k6W2b7$3g2J5N6r3W2X3K9h3y4S2N6r3f1`.

[2] 0f3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2#2M7$3g2F1K9i4S2Q4x3X3g2G2M7X3N6Q4x3V1k6K6P5i4y4@1k6h3#2Q4x3V1k6X3K9h3I4W2M7#2)9J5c8Y4y4W2j5K6t1J5i4K6u0V1P5X3S2S2L8X3N6Q4x3X3c8D9k6h3W2Q4x3X3g2H3k6r3j5`.

[3] f05K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6B7N6h3g2B7K9h3&6Q4x3X3g2U0L8W2)9J5c8Y4m8G2M7%4c8Q4x3V1j5$3z5o6f1H3y4o6p5^5x3e0t1I4x3U0M7&6y4o6x3^5z5o6f1#2

[4] 59bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6f1k6h3&6U0k6h3&6@1i4K6u0r3L8h3q4J5M7#2)9J5c8X3u0D9L8$3u0Q4x3V1k6E0j5i4y4@1k6i4u0Q4x3V1k6E0j5i4u0K6i4K6u0r3P5r3I4G2k6#2)9J5c8X3y4J5P5i4m8@1i4K6u0r3k6r3g2U0L8$3c8W2i4K6g2X3L8h3q4J5M7#2)9#2k6X3&6G2j5%4u0&6M7s2c8Q4y4h3k6D9L8$3N6Q4y4h3k6X3K9h3I4W2i4K6u0W2M7s2V1`.

function open_webview_debug() {
    Java.perform(function () {
        var WebView = Java.use('android.webkit.WebView');
         
        WebView.$init.overloads.forEach(function(init) {
            init.implementation = function() {
                // 调用原始构造方法
                var instance = init.apply(this, arguments);
                 
                // 打开WebView的调试功能
                WebView.setWebContentsDebuggingEnabled(true);
                 
                console.log('[*] WebView调试已开启');
                 
                // 返回实例
                return instance;
            };
        });
    });
}
function open_webview_debug() {
    Java.perform(function () {
        var WebView = Java.use('android.webkit.WebView');
         
        WebView.$init.overloads.forEach(function(init) {
            init.implementation = function() {

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 9
支持
分享
最新回复 (2)
雪    币: 4162
活跃值: (6033)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
博阅怎么不继续研究混淆和反混淆那些了,整点脱壳也好呀
2024-6-2 05:01
1
雪    币: 1226
活跃值: (1675)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tmi
3
2024-6-3 10:53
0
游客
登录 | 注册 方可回帖
返回