快速掌握任意 Android 应用的抓包

抓包是流量分析的基础,也是安全研究重要的一环。抓包软件有很多种,如 Burpsuite、mitmproxy 以及 Fiddle,抓包方式常见的有设置系统代理、AP 热点抓包、透明代理等。不同方式有不同优缺点,也有不同的应用场景。相信很多安全研究者一定会遇到各种无法抓取流量的问题,本次就来简单总结一下 Android 环境中常用的抓包技术,包括一些应用常用的 SSLpinning、不走系统代理等对抗逆向技术。

这里不会重复搬运大部分博客已经总结过的抓包原理和经验,主要是想总结一下如何抓取任意应用的流量包,按照常规思路,假设现在我们想抓取某个应用的流量。

本文总结了如下 4 种抓包方案:

  1. 设置系统代理,即传统中间人代理方法
  2. 利用 iptables 三层网络流量路由
  3. r0capture HOOK 抓包
  4. eCapture ,基于 eBPF 技术实现的抓包软件

1 设置系统代理

设置系统代理是最为常见的一种方法,Android 提供了相应的设置功能,将系统代理指向 Burpsuite 所在的 IP 地址,即可使用 Burpsuite 抓取流量。抓包步骤如下:

这种方式可以解决部分应用的抓包问题,但是如今很多应用使用了 SSL Pinning,即证书绑定,应用只会信任自己本地绑定的证书,并不会信任系统根证书,也就是即使导入了 CA,仍然可能无法抓包。

OWASP 安全验证标准中,将对抗逆向称之为韧性要求,属于额外的管控方法,根据应用敏感性,开发者选择需不需要添加。而 SSL Pinning 就属于对抗逆向的一种手段。

2 利用 iptables 设置透明代理

尽管绕过了 SSL pinning,仍然有可能无法抓到 App 的流量,这是因为应用开发者完全可以不使用系统或其他的 HTTP 库,不理睬系统变量如 HTTP_PROXY,也就是应用不会理会我们设置的系统代理。这个时候就可以使用终极方法了,iptables + Burpsuite 透明代理,步骤如下:

iptables 是一个在应用层实现内核框架 Netfilter 的工具,常见于防火墙配置,而 Netfilter 是内核处理网络数据包的模块。

通过如下命令,即可将内核 OUTPUT 数据转发到我们的目标设备上。

D:\> adb shell iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination 127.0.0.1:8080

此时再利用 adb 反向代理功能,将 Android 手机某个网卡流量通过 adb 的方式转发到我们使用的 PC 上。

D:\> adb reverse tcp:8080 tcp:8080

设置 Burpsuite 透明代理即可抓包。

Burpsuite设置透明代理

当然,也可以指定抓包特定应用,加入如下 iptables 参数即可

-m owner --uid-owner 4000

参数简介

iptables [-t table] {-A|-C|-D} chain rule-specification
-t nat,设置iptables表为网络地址地址转发
-A Append,附加后续规则到相应的表上
chain, PREROUTING/INPUT/OUTPUT/POSTROUTING,来源于内核中的Netfilter模块,OUTPUT表示所有从本地发往远端的数据包
rule-specification, -j DNAT, 修改数据包的目标地址

adb reverseadb forward 的区别就是,前者是反向代理,后者是正向代理,前者是将所有手机流量导入到 PC,后者是将所有 PC 流量导入到手机。

关于 iptables 的原理以及更多配置,透明代理入门iptables在Android抓包中的妙用 等文章已经给了很好的解释,不再赘述。frida-skeleton 就是一个典型的使用 iptables 抓包的工具,但是如果只是抓包,可能用不到 skeleton,且此工具在不同环境下兼容性一般,可能会出现一些奇怪的问题。

3 r0capture hook 抓包

r0capture 是一个典型的通过 hook SSL 类库实现抓包的工具。既然是 hook,离不开 Frida。

下载脚本

git clone https://github.com/r0ysue/r0capture.git

Attach 模式

python3 r0capture.py -U com.qiyi.video -v -p iqiyi.pcap

Spawn 模式

python3 r0capture.py -U -f com.qiyi.video -v

经过实际测试,虽然工具声称是安卓应用层抓包通杀脚本,无需考虑证书,但是还是有很多厂商的应用数据包无法解密。

在这里插入图片描述

4 基于 eBPF 技术实现的 eCapture

同样,eCapture 也是一个无需 CA 证书抓 https网络明文通讯的工具。直接下载编译好的二进制,放到 Android 设备上,即可使用。

./ecapture tls -i eth0 -w pcapng -p 443

由于 eCapture 基于 eBPF,需要内核支持该特性,依赖系统内核是否支持 eBPF。目前支持在操作系统上,支持了 X86_64\ARM64 的 Linux kernel 4.18以 上内核,支持了 ARM64 Android(Linux) kernel 5.4 以上版本。

绕过 SSL Pinning

在设置系统代理抓包无果后,需要继续尝试 SSL Pinning 绕过。绕过证书绑定并不难,但是需要有系统 root 权限,使用 Frida 对相应校验证书的函数进行 Hook。已有多个现成的 Frida 脚本 可以解决此问题,以下是一个简单示例。

// $ frida --codeshare pcipolloni/universal-android-ssl-pinning-bypass-with-frida -f YOUR_BINARY
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...")
	    var 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);

当然,笔者正常使用的方法是在 Linux 环境中,直接使用 objection,已经集成了绕过 SSL pinning 等多个有用的 Frida 脚本,两行脚本搞定 SSL Pinning。

objection -g com.android.phone explore
Using USB device `Android Emulator 5554`
Agent injected and responds ok!

     _   _         _   _
 ___| |_|_|___ ___| |_|_|___ ___
| . | . | | -_|  _|  _| | . |   |
|___|___| |___|___|_| |_|___|_|_|
      |___|(object)inject(ion) v1.11.0

     Runtime Mobile Exploration
        by: @leonjza from @sensepost

[tab] for command suggestions
com.android.phone on (Android: 11) [usb] # android sslpinning disable

总结

不同抓包方案各有利弊,如果你只是想抓所有应用的 HTTPS 报文,使用 iptables 路由转发可以解决绝大多数 HTTPS 抓包问题,且没有环境依赖;如果你拥有最新版本 Android,内核大于 5.4,那么可以直接使用 eCapture;如果你还想抓其他应用层协议报文,例如 Smtp,那么可以使用 r0capture。方案对比如下

抓包方案HTTPS其他应用层协议上手难度依赖工具缺点
设置系统代理部分不支持容易Burpsuite某些应用不使用系统代理,无法抓包
iptables 路由转发全部不支持容易Burpsuite
r0capture hook 抓包部分支持容易Wireshark数据包部分混乱,缺失
基于 eBPF 技术实现的 eCapture全部不支持容易Wireshark需要高版本内核支持

撰写本文最大目的在于,让我们快速掌握任意 Android 应用的抓包,因为现实场景中,往往会遇到常规方法无法抓包的问题。而只需要通过 iptables 即可解决绝大多数问题。除了设置系统代理、iptables路由转发,还可以通过 tcpdump + keylog 以及 SSL read/write 的方式,但是这两种都需要 Hook,因此,对于大多数安全研究者来说,掌握 iptables 设置透明代理的方式就足够了。

参考文献

  1. 终端应用安全之网络流量分析
  2. 快应用调试器研究1:前置知识
  3. 透明代理入门
  4. iptables在Android抓包中的妙用
  5. android手机安装burp证书
  6. 从原理到实战,全面总结 Android HTTPS 抓包
  7. Frida CodeShare
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江下枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值