本文尝试对安卓上见到的抓包方法及其检测做一个总结。大体上来看,抓包就是将手机app上的流量导向到代理程序,代理程序会使用MITM中间人攻击技术来充当一个假的服务器,以监听客户端与服务端的通信,当然此处需要强制客户端信任代理程序生成的假证书。而检测可以去检查是否存在非标准的信道,例如代理,VPN等;或者针对MITM的弱点,即限制证书,采用ssl pinning
;又可以采取双向验证,让服务器来验证客户端的证书,增加一个逆向证书的门槛。
当然,也有另外一套方法,即通过Hook TLS相关函数的方式来监听通信。提到Hook
自然能够想到Android Hook
的集大成者frida
;不过也出现了新的eBPF
技术,其uprobe
的模块可以跟踪用户态函数,相比于frida
下日渐激烈的对抗,还是一个比较新的领域。
Certificate
安卓对证书的配置相对iOS
比较麻烦,主要原因是高版本上用户添加的证书app
默认不会信任。
而系统证书本身的目录是只读的,只能通过一些hack(bind mount
)去将用户证书挂在到系统证书目录上。
目前高版本的可用方法:
其他方法(尚未尝试)
Proxy
在安卓的网络设置界面设置即可,或者也有更自动化的通过adb
设置的方法。
Adb Set Proxy
VPN Based
该方法会创建一个虚拟的tun网卡,和科学上网类似,可以将app的流量强制定向到代理工具。
VPN Detection
这部分是网络环境检测。例如,常见的银行和12306的app都会检测vpn和代理,检测到后可能会发出网络状况异常的通知。
Iptables
这种方法也可以实现按uid
来过滤。安卓会为每一个app
分配一个uid
。可以通过下面的命令查找:
pm list packages -U | grep package_name
clash based
算是比较新奇的思路。如果应用同时做了对VPN
,代理的检测,可以尝试,但缺点就是配置麻烦。
Proxyman
Charles
支持protobuf
Burp Suite
Hooking Based
Frida
思路比较简单,也就是利用frida
去hook
库里的SSL_read
以及SSL_write
函数,以及java
层的一些TLS
相关函数。
eBPF
可以很方便地跟踪libssl
层的函数,但对于java
还没有完备的支持。
目前这方面的对抗还比较少,但也有可行的方法:
Dection
Mutual Verification
简单讲就是不仅客户端验证服务器的证书,服务器也会去验证客户端的证书。
ssl_verify_client
和ssl_verify_client
是用来验证客户端的。
可以通过hook
一些常见的私钥相关方法来获取私钥和证书。例如,这里的java.security.KeyStore$PrivateKeyEntry.getPrivateKey
方法和java.security.KeyStore$PrivateKeyEntry.getCertificateChain
方法。
获取了私钥和证书后,可以指定对应参数来发包,例如这里的requests
库。
SSL Pinning
res/xml/network_security_config.xml
SSL
Library
对于用到了boringssl
库的应用,可以通过SSL_CTX_set_custom_verify
函数来实现ssl pining
。
OpenSSL
提供类似的函数:
代码示例可以在下面地址找到:
Java Level
App Specific
Tiktok
Reference