Flutter简介
Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。Flutter 开源、免费,拥有宽松的开源协议,适合商业项目,Flutter已推出稳定的2.0版本。
Flutter 特性
- 采用Dart语言
- 忽略系统代理设置、用户证书和网络安全设置
测试需求
- burp抓包
- bypass root检测
通过设置代理抓取Flutter流量
1、设置代理网关
本机开启流量转发
sudo sysctl -w net.inet.ip.forwarding=1
手机上设置网关后,通过wireshark、tcpdump可以抓到所有的数据流量
2、Burp抓取
本机设置
$ cat pfctl.txt
rdr pass inet proto tcp from 192.168.1.8 to runic.pl port 443 -> 127.0.0.1 port 8443
$ sudo pfctl -f pfctl.txt
$ sudo pfctl -s nat
rdr pass inet proto tcp from 192.168.1.8 to 37.187.60.243 port = 443 -> 127.0.0.1 port 8443
这个是将https流量通过本机的8443转发到runic.pl中,此时可以抓取到http流量,但是https还不行
3、root绕过
反编译app代码,查找isrooted函数,通过frida对该函数的返回值进行hook
console.log("Loading flutter_jailbreak_detection bypass...");
setImmediate(function() {
Java.perform(function () {
var root = Java.use("com.scottyab.rootbeer.RootBeer");
root.isRooted.overload().implementation = function() {
console.log("isRooted() called, returning false");
return false;
}
});
});
frida启动
frida -U -f pl.runic.ip -l frida-flutter-jailbreak-detection-bypass.js
绕过了root的检测,Frida脚本如下:
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 disablePinning()
{
var m = Process.findModuleByName("libflutter.so");
var pattern = "2d e9 f0 4f a3 b0 82 46 50 20 10 70"
var res = Memory.scan(m.base, m.size, pattern, {
onMatch: function(address, size){
console.log('[+] ssl_verify_result found at: ' + address.toString());
// Add 0x01 because it's a THUMB function
// Otherwise, we would get 'Error: unable to intercept function at 0x9906f8ac; please file a bug'
hook_ssl_verify_result(address.add(0x01));
},
onError: function(reason){
console.log('[!] There was an error scanning memory');
},
onComplete: function()
{
console.log("All done")
}
});
}
setTimeout(disablePinning, 1000)
4、禁用ssl证书锁定
function disablePinning()
{
var SslPinningPlugin = Java.use("com.macif.plugin.sslpinningplugin.SslPinningPlugin");
SslPinningPlugin.checkConnexion.implementation = function()
{
console.log("Disabled SslPinningPlugin");
return true;
}
}
Java.perform(disablePinning)
5、https流量的抓取
首先按照Burp抓取配置,然后设置burp的代理如下:
增加需要跳转到的地址和端口,增加Force use of TLS。这样即可抓取到https流量
通过reFlutter抓取Flutter流量
reFlutter是一个框架,帮助我们逆向Flutter app,主要是通过对Flutter 库的patch来实现上面我们手工做的内容
安装方式
# Linux, Windows, MacOS
pip3 install reflutter
或者通过docker方式来使用
sudo docker pull ptswarm/reflutter
使用
impact@f:~$ reflutter main.apk
Please enter your Burp Suite IP: <input_ip>
SnapshotHash: 8ee4ef7a67df9845fba331734198a953
The resulting apk file: ./release.RE.apk
Please sign the apk file
Configure Burp Suite proxy server to listen on *:8083
Proxy Tab -> Options -> Proxy Listeners -> Edit -> Binding Tab
Then enable invisible proxying in Request Handling Tab
Support Invisible Proxying -> true
impact@f:~$ reflutter main.ipa
上面是github上文档上的说明,可以看到工具通过侵入到apk中进行了代码补丁,并且形成了一个新的apk,这个apk需要进行重新签名,可以使用 uber-apk-signer:
java -jar uber-apk-signer.jar --allowResign -a release.RE.apk
为了能更好的查看,reFlutter可以通过logcat进行查看
impact@f:~$ adb logcat -e reflutter | sed 's/.*DartVM//' >> reflutter.txt
Burp抓取
上面也说了burp的配置方法,利用这种方法不需要引入burp的证书
- 配置端口:8083
- 绑定地址:All interfaces
- Request handling:打开Support invisible proxying
