首先从apk文件看到明显的fluter开发的特征
这一类app有一个特点就是流量默认不走代理这是这个fluter框架层就决定的原因,对应的方法就是利用vpn代出流量,这里我们用的是Reqable与桌面端联动的形式,同时不信任系统证书,我们传统的在系统证书中加入的ca证书就无效了,因此我们需要对这个fluter框架进行一定的hook让他验证证书的关机函数全部返回为真
参考该项目:https://github.com/NVISOsecurity/disable-flutter-tls-verification
function hook_ssl_verify_result(address) {
Interceptor.attach(address, {
onEnter: function(args) {
console.log("Disabling SSL validation");
},
onLeave: function(retval) {
console.log("Retval: " + retval);
retval.replace(0x1);
}
});
}
function hookFlutter() {
var m = Process.findModuleByName("libflutter.so");
if (m) {
console.log("libflutter.so module found at base address: " + m.base);
var pattern = "FF C3 01 D1 FD 7B 01 A9 FC 6F 02 A9 FA 67 03 A9 F8 5F 04 A9 F6 57 05 A9 F4 4F 06 A9 08 0A 80 52 48 00 00 39 1A 54 40 F9 DA 02 00 B4 48 03 40 F9 88 02 00 B4 39 20 40 A9 F3 03 02 AA EE 01 0B 94 F7 03 1F AA 49 07 40 F9 2B 1B 40 F9 2D 37 40 F9 08 11 40 F9 6A 8D 40 F9 8A 01 00 B4 2C 93 42 39 F8 03 17 AA 8C 01 00 37 6B D9 40 B9 7F 09 00 71 01 01 00 54 4A 05 43 F9 57 61 42 A9 06 00 00 14";
Memory.scanSync(m.base, m.size, pattern, {
onMatch: function(address, size){
console.log('[+] ssl_verify_result found at: ' + address.toString());
hook_ssl_verify_result(address);
},
onError: function(reason){
console.log('[!] There was an error scanning memory: ' + reason);
},
onComplete: function() {
console.log("All done");
}
});
} else {
console.log("libflutter.so module not found");
}
}
setTimeout(hookFlutter, 5000); // 设置延时找对hook时机(太快函数还没加载出来,太慢app已经发起请求了)
这样不出意外我们将获取到app发出的请求,可惜的是发出的请求内容全部是加密的,并且包非常的奇怪,根据之前遇到的情况,有理由怀疑它将内部的流量进行了隧道化,真实的请求在内部流转,抓到的是已经封装好的隧道的流量
通过对java层apk进行分析,很明显flutter开发的程序业务都编译成了so文件找不到特别有用的东西,但我们找到了一个包名kiwi.sdk,验证了流量走的是本地隧道,端到端加密
根据包名找到一个基础提供商
到这里我们有两个思路可以继续,第一个是在走隧道前进行hook,很明显要找到flutter libapp.so,但要在这个so里面找到没有符号的具体某个发包的请求函数地址,对于我这个半吊子逆向人员是比较困难的
我们先验证我们的想法,找个安卓版的tcpdump 抓取本地网卡包看看
下载:https://github.com/extremecoders-re/tcpdump-android-builds
tcpdump -i lo -w data.pacp
本地的接口可以看到相关的流量
因此我们直接用adb shell将该包的监听打出来
netstat -anp | grep 'com.xxx.fxxx'
在将该端口映射出来
adb forward tcp:45599 tcp:45599
这样我们就能转换成传统的形式进行分析,该app还有一个需求需要处理,就是包全部带签名,因此我们需要找到其jwt的签名key才能够对包进行修改