参考:https://www.jianshu.com/p/ada10d2976f2
Flutter是Google使用Dart语言开发的移动应用开发框架,使用一套Dart代码就能快速构建高性能、高保真的iOS和Android应用程序。
由于Dart使用Mozilla的NSS库生成并编译自己的Keystore,导致我们就不能通过将代理CA添加到系统CA存储来绕过SSL验证。为了解决这个问题,就必需要研究libflutter.so。
当向Burp发送HTTPS流量时,Flutter应用程序会抛出一个错误,可以将其作为起点进行溯源:
E/flutter (10371): [ERROR:flutter/runtime/dart_isolate.cc(805)] Unhandled exception:
E/flutter (10371): HandshakeException: Handshake error in client (OS Error:
E/flutter (10371): NO_START_LINE(pem_lib.c:631)
E/flutter (10371): PEM routines(by_file.c:146)
E/flutter (10371): NO_START_LINE(pem_lib.c:631)
E/flutter (10371): PEM routines(by_file.c:146)
E/flutter (10371): CERTIFICATE_VERIFY_FAILED: self signed certificate in certificate chain(handshake.cc:352))
E/flutter (10371): #0 _rootHandleUncaughtError. (dart:async/zone.dart:1112:29)
E/flutter (10371): #1 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (10371): #2 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/flutter (10371): #3 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:116:13)
E/flutter (10371): #4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:173:5)
该错误显示了触发错误的位置:handshake.cc:352,代码如下所示。
if (ret == ssl_verify_invalid) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
}
这是ssl_verify_peer_cert函数的一部分,该函数返回ssl_verify_result_t的枚举,枚举定义在ssl.h的第2290行:
enum ssl_verify_result_t BORINGSSL_ENUM_INT {
ssl_verify_ok,
ssl_verify_invalid,
ssl_verify_retry,
};
经过试验,将ssl_verify_peer_cert的返回值更改为ssl_verify_ok (=0)的话仍会因为上面的ssl_send_alert()函数调用而失败,因此需要找另一个hook点。handshake.cc的代码段上方有一段验证证书链的方法:
ret = ssl->ctx->x509_method->session_verify_cert_chain(
hs->new_session.get(), hs, &alert)
? ssl_verify_ok
: ssl_verify_invalid;
session_verify_cert_chain函数定义在ssl_x509.cc,此函数返回布尔值类型,并且没有像ssl_verify_peer_cert函数那样的问题,可以作为hook的目标。在该方法里可以看到有两个字符串可以辅助定位方法,如图1-1所示。
图1-1 所需hook函数中有辨识度较高字符串
之后在ida中的strings可以找到并定位函数为sub_3A5564,过程如图1-2到1-4所示。
图1-2 stirngs搜索到目标字符串
图1-3 查看调用函数
图1-4 确定本函数为目标函数
图1-5 利用前10字节定位函数
后面可以在frida中编写脚本,使用函数前10字节定位,在运行时将返回函数改为true即可绕过证书链检查实现抓包,示例如下。
function hook_ssl_verify_result(address)
{
Interceptor.attach(address, {
onEnter: function(args) {
send("Disabling SSL validation")
},
onLeave: function(retval)
{
send("Retval: " + retval)
retval.replace(0x1);
}
});
}
function disablePinning()
{
var m = Process.findModuleByName("libflutter.so");
var pattern = "2d e9 f0 4f a3 b0 81 46 50 20 10 70"
var res = Memory.scan(m.base, m.size, pattern, {
onMatch: function(address, size){
send('[+] ssl_verify_result found at: ' + address.toString());
// Add 0x01 because it's a THUMB function
hook_ssl_verify_result(address.add(0x01));
},
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-9-9 16:55
被beimingyouyu编辑
,原因: