前文提要
介绍
目前对手机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。使用Frida加载脚本进行Hook:
/
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))。
然后重新尝试抓包:发现burp可以成功抓取数据包。
使用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功能,当然是否奏效还要视应用程序的具体实现而定。通过观察输出信息发现objection是通过hook AFNetworking等常用库和一些底层的methods实现绕过证书绑定。发现可以成功获取数据包。
同样,也可以通过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();
成功抓取数据包:
路由直连
某App用代理软件正常抓包发现无法抓到域名和数据包,开启或者关闭代理都不影响APP本身的刷新,抓包软件也没有任何的数据包。针对这种APP首先进行脱壳,然后我们导入jeb中查看具体的源码。参考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。然后在模拟器中运行该APP,在搜索框内随便输入一些字符。 回到抓包软件中发现,已经可以成功抓取到刚才输入的数据。如上图所示,通过开启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
然后从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
回到Cydia中,查看安装的软件,已经在列表中。如果不需要使用插件,卸载命令如下:
dpkg -r com.nablac0d3.sslkillswitch2_0.13.deb
使用方法
进入手机设置,开启 Disable Certificate Validation,就可以抓取https的流量了,如图所示:
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中激活并重启手机,这时就可以抓取手机中的流量了。
Thor(锤子)、HTTP Catcher
简介
Thor(锤子)除了可以抓取ipa安装包,还能抓音乐、视频、图片和文本等,这个app强大之处并不只是抓取数据包,而是它强大的过滤器。过滤器可以自己开发,用作破解app或者解除付费app。
HTTP Catcher 是一个web调试工具,用来抓取并查看iOS系统上的应用发出去的http请求。实时记录HTTP/1,HTTP/2和WebSocket请求,支持解密HTTPS、请求过滤。可以添加规则进行重写,也可用作破解app或者解除付费app。
使用方法
建议读者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://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 或关注公众号: