【Android 抓包对抗】代理检查绕过
1. 安装apk,点进去发现一点就挂
2. apk 拖入到jadx中观察,发现多出检查,一旦满足条件就会退出
....
if (((ConnectivityManager) getSystemService("connectivity")).getNetworkInfo(17).isConnected()) {
stop();
}
....
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
String name = networkInterfaces.nextElement().getName();
if (name.equals("tun0") || name.equals("ppp0")) {
stop();
}
}
......
ConnectivityManager connectivityManager = (ConnectivityManager) OkHttpUtil.activityContext.getSystemService("connectivity");
if (Build.VERSION.SDK_INT >= 23 && connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork()).hasTransport(4)) {
System.exit(-1);
}
......
3. 编写frida绕过检查,防止app一进入就挂了
var can_hook = false
var ConnectivityManager = Java.use("android.net.ConnectivityManager");
ConnectivityManager.getNetworkInfo.overload('int').implementation = function(){
console.log("call getNetworkInfo function !!!")
if(arguments[0] == 17){
can_hook = true
}
var ret = this.getNetworkInfo(arguments[0])
return ret
}
var NetworkInfo = Java.use("android.net.NetworkInfo")
NetworkInfo.isConnected.implementation = function(){
var ret = this.isConnected()
if(can_hook){
ret = false
can_hook = false
console.log("call isConnected function !!!")
}
return ret
}
var NetworkCapabilities = Java.use("android.net.NetworkCapabilities")
NetworkCapabilities.hasTransport.implementation = function(){
var ret = this.hasTransport(arguments[0])
if(arguments[0] == 4){
console.log("call hasTransport function !!!")
ret = false
}
return ret
}
NetworkCapabilities.transportNameOf.overload('int').implementation = function(){
console.log("call transportNameOf function !!!")
var ret = this.transportNameOf(arguments[0])
if(ret.indexOf("VPN") >= 0){
ret = "WIFI"
}
return ret;
}
var NetworkInterface = Java.use("java.net.NetworkInterface")
NetworkInterface.getAll.implementation = function(){
var nis = this.getAll()
console.log("call getAll function !!!")
nis.forEach(function(ni){
if (ni.name.value.indexOf("tun0")>=0 || ni.name.value.indexOf("ppp0")>=0 ){
ni.name.value = "xxxx"
ni.displayName.value = "xxxx"
}
})
return nis
}
成功让app可以进入,但是还是抓不到包
观察到和上一篇有一点出入的地方,设置了不让代理
builder.proxy(Proxy.NO_PROXY);
这里有两种解法,
一是hook 这个proxy方法
参考: https://www.freebuf.com/articles/terminal/249920.html
二是手机开启VPN,转发流量到charls上,这个方法的好处是更底层的流量代理,socket也找处理不误
操作方法:
1. 手机下载一个VPN软件,比如Brook
2. 点进去,选择socks5 然后填入charls监听的IP 和监听socks 的端口比如默认的8889
3. PC上操作charles, proxy -> Proxy Settings 点击enbale SOCKS proxy
这样操作APP时,就可以在Charles上看到流量了
4. 但还是看不到流量数据,这是因为代码中有一些检查,通过观察堆栈日志,需要追加以下代码,绕过日志中的报错检查
var MainActivity = Java.use("com.dta.dtawallpaper.MainActivity$4");
MainActivity["onFailure"].implementation = function (call, iOException) {
console.log("***************************")
console.log(Java.use("android.util.Log").getStackTraceString(iOException));
this.onFailure(call, iOException);
};
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner["check$okhttp"].implementation = function (hostname, cleanedPeerCertificatesFn) {
};
var OkHttpUtil = Java.use("com.dta.dtawallpaper.util.OkHttpUtil$1");
OkHttpUtil["verify"].implementation = function (str, sSLSession) {
return true
};
5. 整体代码为
function main(){
Java.perform(function (){
//TrustAllManager
var TrustAllManagerClass = Java.registerClass({
name: "TrustAllManager",
implements:[Java.use("javax.net.ssl.X509TrustManager")],
methods: {
checkClientTrusted(chain, authType) {
console.log("checkClientTrusted Called!!")
},
checkServerTrusted(chain, authType) {
console.log("checkServerTrusted Called!!")
},
getAcceptedIssuers() {
return [];
},
}
})
var trustAllManagerHandle = TrustAllManagerClass.$new()
var sslContext = Java.use("javax.net.ssl.SSLContext").getInstance("TLS")
var trustManagers = Java.array("Ljavax.net.ssl.X509TrustManager;",[trustAllManagerHandle])
sslContext.init(null,trustManagers,null)
var sslSocketFactory = sslContext.getSocketFactory()
Java.use("okhttp3.OkHttpClient$Builder").sslSocketFactory.overload('javax.net.ssl.SSLSocketFactory', 'javax.net.ssl.X509TrustManager').implementation = function(arg0, arg1){
console.log("sslSocketFactory Called!!")
return this.sslSocketFactory(sslSocketFactory,trustAllManagerHandle)
}
//HostnameVerify
var MyHostnameVerify = Java.registerClass({
name: "MyHostnameVerify",
implements:[Java.use("javax.net.ssl.HostnameVerifier")],
methods: {
verify(hostname, session){
console.log(hostname)
return true
}
}
})
var myHostnameVerifyHandle = MyHostnameVerify.$new()
Java.use("okhttp3.OkHttpClient$Builder").build.implementation = function(){
this.hostnameVerifier(myHostnameVerifyHandle)
console.log(this.hostnameVerifier)
return this.build()
}
var can_hook = false
var ConnectivityManager = Java.use("android.net.ConnectivityManager");
ConnectivityManager.getNetworkInfo.overload('int').implementation = function(){
console.log("call getNetworkInfo function !!!")
if(arguments[0] == 17){
can_hook = true
}
var ret = this.getNetworkInfo(arguments[0])
return ret
}
var NetworkInfo = Java.use("android.net.NetworkInfo")
NetworkInfo.isConnected.implementation = function(){
var ret = this.isConnected()
if(can_hook){
ret = false
can_hook = false
console.log("call isConnected function !!!")
}
return ret
}
var NetworkCapabilities = Java.use("android.net.NetworkCapabilities")
NetworkCapabilities.hasTransport.implementation = function(){
var ret = this.hasTransport(arguments[0])
if(arguments[0] == 4){
console.log("call hasTransport function !!!")
ret = false
}
return ret
}
NetworkCapabilities.transportNameOf.overload('int').implementation = function(){
console.log("call transportNameOf function !!!")
var ret = this.transportNameOf(arguments[0])
if(ret.indexOf("VPN") >= 0){
ret = "WIFI"
}
return ret;
}
var NetworkInterface = Java.use("java.net.NetworkInterface")
NetworkInterface.getAll.implementation = function(){
var nis = this.getAll()
console.log("call getAll function !!!")
nis.forEach(function(ni){
if (ni.name.value.indexOf("tun0")>=0 || ni.name.value.indexOf("ppp0")>=0 ){
ni.name.value = "xxxx"
ni.displayName.value = "xxxx"
}
})
return nis
}
var MainActivity = Java.use("com.dta.dtawallpaper.MainActivity$4");
MainActivity["onFailure"].implementation = function (call, iOException) {
console.log("***************************")
console.log(Java.use("android.util.Log").getStackTraceString(iOException));
this.onFailure(call, iOException);
};
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner["check$okhttp"].implementation = function (hostname, cleanedPeerCertificatesFn) {
};
var OkHttpUtil = Java.use("com.dta.dtawallpaper.util.OkHttpUtil$1");
OkHttpUtil["verify"].implementation = function (str, sSLSession) {
return true
};
});
}
setImmediate(main)
成功看到流量日志

PS: 如果遇到一些问题 可以看一下是不是 SSL Proxying Settings中目的端口是不是没有配置导致的,在这里我踩了一点坑
【Android 抓包对抗】代理检查绕过的更多相关文章
- Android抓包方法(一)之Fiddler代理
Android抓包方法(一) 之Fiddler代理 前言: 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等. 不管是之前做HTML5手机 ...
- Android抓包方法(二)之Tcpdump命令+Wireshark
Android抓包方法(二) 之Tcpdump命令+Wireshark 前言 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等.学会抓包分 ...
- Android抓包方法(转)
Android抓包方法(转) 作者:Findyou 地址:http://www.cnblogs.com/findyou/p/3491014.html 前言: 做前端测试,基本要求会抓包,会分析请求数据 ...
- Android抓包方法(三)之Win7笔记本Wifi热点+WireShark工具
Android抓包方法(三) 之Win7笔记本Wifi热点+WireShark工具 前言 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等 ...
- HttpCanary——最强Android抓包工具!
迎使用HttpCanary——最强Android抓包工具! HttpCanary是一款功能强大的HTTP/HTTPS/HTTP2网络包抓取和分析工具,你可以把他看成是移动端的Fiddler或者Char ...
- Android抓包方法 之Fiddler代理
1.抓包原理 Fiddler是类似代理服务器的形式工作,它能够记录所有你的电脑和互联网之间的http(S)通讯,可以查看.修改所有的“进出”的数据.使用代理地址:127.0.0.1, 默认端口:888 ...
- *android抓包工具——fiddler抓包分析api接口
本文地址:http://blog.csdn.net/u011733020 首先,写这个仅仅是为了学习.不是要做什么违法的事情,假设有问题,有关部门 请联系我,立刻删除. 不要查我水表. 正题:这里介绍 ...
- Android 抓包,监控流量工具之 mitmproxy
转:http://greenrobot.me/devpost/how-to-debug-android-http-get-started/ mitmproxy实践教程之调试 Android 上 HTT ...
- android抓包工具——使用fiddler4在安卓手机抓包
Fiddler是一款非常流行并且实用的http抓包工具,它的原理是在本机开启了一个http的代理服务器,然后它会转发所有的http请求和响应,因此,它比一般的firebug或者是chrome自带的抓包 ...
- Android抓包方法
0. Fiddler代理 1.tcpdump命令+wireshark工具 adb shell #登入手机 su #切换Root用户 /data/local/tcpdump -p ...
随机推荐
- [转帖]linux 内核协议栈 TCP time_wait 原理、配置、副作用
https://my.oschina.net/u/4087916/blog/3051356 0. 手把手教你做中间件.高性能服务器.分布式存储技术交流群 手把手教你做中间件.高性能服务器.分布式存 ...
- [转帖]360孵化奇安信科创板上市,IPO前清空股权赚37亿元分手费
https://baijiahao.baidu.com/s?id=1666485645739027654&wfr=spider&for=pc 来源:IPO头条 来源:IPO头条原创 ...
- 【转帖】一文解析ethtool 命令的使用
命令简介 ethtool命令用于查询和控制网络设备驱动程序和硬件设置,尤其是有线以太网设备,devname网卡的名称.网卡就像是交换机的一个端口,正常使用我们只是配置网卡IP地址等信息,网卡的速率.双 ...
- Core 文件的简单学习
背景 最近公司内经常出现jvm进程宕机的情况. 宕机之后没有产生jvm的dump文件.比如xxx.hprof 但是产生了 core.$pid的文件. 曾经在aarch64架构上宕机时曾经想学习一下co ...
- OpenEuler2203使用rpm方式安装Oracle19c的过程
OpenEuler2203使用rpm方式安装Oracle19c的过程 安装介质 oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm oracle-d ...
- Spring Boot日志框架Slf4j+logback
一.简介 Slf4j Java的简单日志记录外观(Simple Logging Facade for Java )可作为各种日志记录框架(例如java.util.logging,logback,log ...
- 你不知道的Linux shell操作
Linux Shell 脚本入门教程 Linux Shell 脚本是一种强大的工具,它允许您自动化日常任务和复杂操作.在本教程中,我们将逐步介绍几个实用的 Shell 脚本示例.每个示例都将详细说明, ...
- diff算法是如何比较的,保证让你看的明明白白的!
更新dom节点,最小力度去跟新 index.html <body> <h1>你好啊!</h1> <button id="btn">该 ...
- Walrus 0.5发布:重构交互流程,打造开箱即用的部署体验
开源应用管理平台 Walrus 0.5 已于近日正式发布! Walrus 0.4 引入了全新应用模型,极大程度减少了重复的配置工作,并为研发团队屏蔽了云原生及基础设施的复杂度.Walrus 0.5 在 ...
- PaddleHub--{超参优化AutoDL Finetuner}【二】
相关文章: 基础知识介绍: [一]ERNIE:飞桨开源开发套件,入门学习,看看行业顶尖持续学习语义理解框架,如何取得世界多个实战的SOTA效果?_汀.的博客-CSDN博客_ernie模型 百度飞桨: ...