移动应用安全基础篇:APP抓包姿势总结 – 作者:tales

前文提要

移动应用安全基础篇:Android、iOS环境准备

移动应用安全基础篇:绕过iOS越狱检测

移动应用安全基础篇:解密iOS加密数据

介绍

目前对手机APP进行安全测试时,经常遇到无法抓取https的流量数据包,导致测试无法继续进行下去,这次给大家分享手机端抓包的一些方法。

今天主要是针对三款常规操作抓不到包的Android和iOS应用,方式为手动分析和工具使用。

使用Frida绕过SSl Pinning

绕过SSL Pinni

为了保证网络传输内容的安全性,在Android、iOS上开发的APP程序通常会开启SSL Pinning(称为“安全会话绑定”或“证书绑定”)。APP允许使用自签名的CA来构建HTTPS通信网络。在所有的通信过程中,对SSL通信证书合法性的验证由KeyStore提供的API来完成,在分析第三方APK的通信流量过程中,SSL Pinning是摆在分析员面前的第一座堡垒。Xposed、sslkillswitch插件的流行,使得绕过SSL Pinning不再是难事。

在对APP进行抓取流量时发现APP提示网络异常,猜测该APP使用了SSL Pinning。image.png使用Frida加载脚本进行Hook: image.png

/ 
   Android SSL Re-pinning frida script v0.2 030417-pier 
   $ adb push burpca-cert-der.crt /data/local/tmp/cert-der.crt
   $ frida -U -f it.app.mobile -l frida-android-repinning.js --no-pause
   https://techblog.mediaservice.net/2017/07/universal-android-ssl-pinning-bypass-with-frida/
/
setTimeout(function(){
    Java.perform(function (){
        console.log("");
        console.log("[.] Cert Pinning Bypass/Re-Pinning");
    var CertificateFactory = Java.use("java.security.cert.CertificateFactory");
    var FileInputStream = Java.use("java.io.FileInputStream");
    var BufferedInputStream = Java.use("java.io.BufferedInputStream");
    var X509Certificate = Java.use("java.security.cert.X509Certificate");
    var KeyStore = Java.use("java.security.KeyStore");
    var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");
    var SSLContext = Java.use("javax.net.ssl.SSLContext");
// Load CAs from an InputStream
console.log("[+] Loading our CA...")
cf = CertificateFactory.getInstance("X.509");
try {
    var fileInputStream = FileInputStream.$new("/data/local/tmp/cert-der.crt");
}
catch(err) {
    console.log("[o] " + err);
}
var bufferedInputStream = BufferedInputStream.$new(fileInputStream);
var ca = cf.generateCertificate(bufferedInputStream);
bufferedInputStream.close();
var certInfo = Java.cast(ca, X509Certificate);
console.log("[o] Our CA Info: " + certInfo.getSubjectDN());
// Create a KeyStore containing our trusted CAs
console.log("[+] Creating a KeyStore for our CA...");
var keyStoreType = KeyStore.getDefaultType();
var keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
console.log("[+] Creating a TrustManager that trusts the CA in our KeyStore...");
var tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
var tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
console.log("[+] Our TrustManager is ready...");
console.log("[+] Hijacking SSLContext methods now...")
console.log("[-] Waiting for the app to invoke SSLContext.init()...")
SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").implementation = function(a,b,c) {
    console.log("[o] App invoked javax.net.ssl.SSLContext.init...");
    SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").call(this, a, tmf.getTrustManagers(), c);
    console.log("[+] SSLContext initialized with our custom TrustManager!");
}
});
},0);

脚本的功能:

1、从文件系统下载一个流氓证书;

2、创建自己的KeyStore,其中包含信任CA;

3、最后一步它创建一个信任我们的KeyStore中CA的TrustManager。

当应用程序初始化其SSLContext时,Frida脚本将会拦截SSLContext.init(),并且在其被调用时会用我们自己的TrustManager取代它的第二个参数。在Android中,SSLContext函数是这么被调用的SSLContext.init(KeyManager, TrustManager, SecuRandom))。

然后重新尝试抓包:image.png发现burp可以成功抓取数据包。image.png

使用Objection绕过iOS SSL Pinning

1、首先在Cydia中添加frida的源;

2、pip3 install objection;

3、具体使用方法参考objection项目地址:https://github.com/sensepost/objection

首先,将手机通过USB连接到计算机,然后在终端窗口中,键入下列命令:

objection --gadget AppName explore

此时objection将附加到目标应用程序上。然后通过使用objection内置的ios sslpinning disable命令绕过证书绑定。

ios sslpinning disable

该命令可以用于禁用SSL pinning功能,当然是否奏效还要视应用程序的具体实现而定。image.png通过观察输出信息发现objection是通过hook AFNetworking等常用库和一些底层的methods实现绕过证书绑定。image.png发现可以成功获取数据包。

同样,也可以通过Frida hook AFSecurityPolicy evaluateServerTrust函数的返回值来实现绕过SSL Pinning。

function main() {
    var resolver = new ApiResolver('objc');//创建已加载Object-C类方法的API查找器
    var matches = resolver.enumerateMatchesSync("-[AFSecurityPolicy evaluateServerTrust:forDomain:]");//查找evaluateServerTrust:forDomain函数,返回数组类型
    if (matches.lenght == 0) {
        console.log("\n[E] -[AFSecurityPolicy evaluateServerTrust:forDomain:] is not found!\n");
        return;
    }
    Interceptor.attach(ptr(matches[0]["address"]),{
            onLeave: function(retval) {
                console.log("[I] -[AFSecurityPolicy evaluateServerTrust:forDomain:] hits!");
                retval.replace(1);//将返回值修改为1
            }
        }
    );
    console.log("[I] -[AFSecurityPolicy evaluateServerTrust:forDomain:] is hooked!\n")
}
main();

image.png成功抓取数据包: image.png

路由直连

某App用代理软件正常抓包发现无法抓到域名和数据包,开启或者关闭代理都不影响APP本身的刷新,抓包软件也没有任何的数据包。针对这种APP首先进行脱壳,然后我们导入jeb中查看具体的源码。image.png参考AsyncHttpClient为什么无法用Fiddler来抓包

String DEFAULT_PROXY = “http.route.default-proxy”表示定义可以被不使用JRE设置的默认路由规划者使用的代理主机。
这个参数期望得到一个HttpHost类型的值。如果这个参数没有被设置,那么就会尝试直接连接到目标。
ConnRoutePNames.DEFAULT_PROXY,默认情况下,他是不使用代理进行路由寻址的,当我们通过setProxy(“172.29.14.249”,8888) 即改变了路由寻址的策略,将wifi直连改为通过wifi代码去寻址;顾我们可以顺利的抓包了。
http.route.default-proxy
如果没有设置ip端口则默认路由直连,没有通过wifi走代理,所以我们使用代理工具抓不到包,但依然可以访问网络。

针对这种情况可以利用Proxifier配合Charles进行抓包,首先配置好Proxifier。image.png然后在模拟器中运行该APP,在搜索框内随便输入一些字符。 image.png回到抓包软件中发现,已经可以成功抓取到刚才输入的数据。image.png如上图所示,通过开启Proxifier配合抓包工具Charles可成功捕获到数据包。

工具

SSL Kill Switch 2

简介

iOS上用到的这款工具叫做SSL Kill Switch 2,该工具使用了Cydia Substrate的钩子技术,这个钩子Hook了IOS的验证证书函数,使得他们接受任何证书。https://github.com/nabla-c0d3/ssl-kill-switch2

实现原理

SSL Kill Switch 2 工作的原理是 Hook 安全传输相关的函数 SSLHandshake、SSLSetSessionOption、SSLCreateContext,核心代码如下:

// 安全传输相关的函数 hook, 支持 iOS 9
MSHookFunction((void ) SSLHandshake,(void )  replaced_SSLHandshake, (void ) &original_SSLHandshake);
MSHookFunction((void ) SSLSetSessionOption,(void )  replaced_SSLSetSessionOption, (void ) &original_SSLSetSessionOption);
MSHookFunction((void ) SSLCreateContext,(void )  replaced_SSLCreateContext, (void ) &original_SSLCreateContext);
// libsystem_coretls.dylib hook,只支持 iOS 10 及以上
NSProcessInfo processInfo = [NSProcessInfo processInfo];
if ([processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] && [processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){11, 0, 0}])
{
    // 支持 iOS 12
    void handle = dlopen("/usr/lib/libnetwork.dylib", RTLD_NOW);
    void tls_helper_create_peer_trust = dlsym(handle, "nw_tls_create_peer_trust");
    if (tls_helper_create_peer_trust)
    {
        MSHookFunction((void ) tls_helper_create_peer_trust, (void ) replaced_tls_helper_create_peer_trust,  (void ) &original_tls_helper_create_peer_trust);
    }
}
else if ([processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] && [processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 0, 0}])
{
    // 支持 iOS 10
    void tls_helper_create_peer_trust = dlsym(RTLD_DEFAULT, "tls_helper_create_peer_trust");
    MSHookFunction((void ) tls_helper_create_peer_trust, (void ) replaced_tls_helper_create_peer_trust,  (void **) &original_tls_helper_create_peer_trust);
}

安装

首先在越狱后的Cydia工具中查看以下几项软件是否都安装完成:

Debian Packager
Cydia Substrate
PreferenceLoader

image.png然后从Github上下载最新的release包com.nablac0d3.sslkillswitch2_0.13.deb,将该文件拷贝到iOS设备中。用ssh链接iOS设备,找到deb文件传输目录(/User/Media)执行如下命令进行安装:

dpkg -i com.nablac0d3.sslkillswitch2_0.13.deb
killall -HUP SpringBoard

image.png回到Cydia中,查看安装的软件,已经在列表中。image.png如果不需要使用插件,卸载命令如下:

dpkg -r com.nablac0d3.sslkillswitch2_0.13.deb

使用方法

进入手机设置,开启 Disable Certificate Validation,就可以抓取https的流量了,如图所示:image.pngimage.png

JustTrustMe

简介

JustTrustMe 一个用来禁用、绕过 SSL 证书检查的基于 Xposed 模块。项目地址:https://github.com/Fuzion24/JustTrustMe配合hook框架Xposed,官方下载地址:http://repo.xposed.info/module/de.robv.android.xposed.installer

实现原理

JustTrustMe 是将 APK 中所有用于校验 SSL 证书的API都进行了 Hook,从而绕过证书检查Android 上实现 Https 的几种方式:

1、通过 OkHttp 来实现;

CertificatePinner(证书锁定):

自定义证书和 HostnameVerify 来实现 Https 校验:

2、通过 Apache 的 HttpClient 来实现; 

通过在 APK 中内置的证书初始化一个 KeyStore,然后用这个KeyStore 去引导生成的 TrustManager 来提供验证。

自定义 SSLSocketFactory 实现其中的 TrustManager 校验策略。

3、通过 HttpsURLConnection 来实现;

自定义的 HostnameVerifier 和 X509TrustManager 实现

使用内置的证书初始化一个 KeyStore,实现 TrustManager

4、WebView 加载 Https 页面时的证书校验;

5、JustTrustMe中其他 Hook 函数。

使用方法

下载JustTrustMe安装包安装进手机,在Xposted中激活并重启手机,这时就可以抓取手机中的流量了。

image.png

Thor(锤子)、HTTP Catcher

简介

Thor(锤子)除了可以抓取ipa安装包,还能抓音乐、视频、图片和文本等,这个app强大之处并不只是抓取数据包,而是它强大的过滤器。过滤器可以自己开发,用作破解app或者解除付费app。image.png

image.pngHTTP Catcher 是一个web调试工具,用来抓取并查看iOS系统上的应用发出去的http请求。实时记录HTTP/1,HTTP/2和WebSocket请求,支持解密HTTPS、请求过滤。可以添加规则进行重写,也可用作破解app或者解除付费app。 image.png image.png

使用方法

建议读者iOS商店下载APP后,自行百度搜索图文并茂的操作方法,在此不再敖述。

总结

关于Android、iOS中的防止抓包现在很多应用都开始做了对应的策略,最常见的是采用https协议,然后Fiddler、burp之类的证书是不被系统根证书认可,所以导致抓包失败的,但是可以Hook系统的证书认证功能即可解决这个问题。

参考文章

感谢各位大佬的倾情奉献!

https://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.htmlhttp://blog.sina.com.cn/s/blog_616e189f01018rpk.html  

https://github.com/square/okhttp/wiki/HTTPS  

https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/CertificatePinner.html

https://www.cnblogs.com/JDragons/p/7332324.html

http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ssl/SSLSocketFactory.html  

http://pingguohe.net/2016/02/26/Android-App-secure-ssl.html  

https://la0s.github.io/2018/10/14/Capture/

http://frodoking.github.io/2015/03/12/android-okhttp/

关注我们

Tide安全团队正式成立于2019年1月,是以互联网攻防技术研究为目标的安全团队,目前聚集了十多位专业的安全攻防技术研究人员,专注于网络攻防,网络安全,移动终端,安全开发,的IoT /物联网/工控安全等方向。想了解更多Tide安全团队,请关注团队官网 http://www.TideSec.net 或关注公众号:ewm.png

来源:freebuf.com 2019-07-01 09:00:51 by: tales

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论