【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 ...
随机推荐
- Systemd设置ulimit的方式与方法
Systemd设置ulimit的方式与方法 摘要 Linux安装完成之后前面几件事情一般是处理selinux 以及处理ulimit 其实处理文件打开数有多种方法,之前也总结过, 但是最近因为syste ...
- 某环境私有云 rpm 包安装失败总结
1. 最近公司同事说一个项目搭建环境时 rpm 安装mysql数据库会报错 错误图片主要如下: 第一个错误提示是 提示 /etc/host.conf line 2: bad command `nosp ...
- Centos7把home目录下多余的空间转移到/根目录下
通过df-h发现,根目录只有32G,而home目录可用的,居然有142G.我现在想分出70G给根目录 把你需要挂载的机器的逻辑卷记住(上面的图,左边是逻辑卷,右边是虚拟磁盘) /dev/mapper/ ...
- 手撕Vue-实现将数据代理到Vue实例
前言 经过上一篇文章的学习,完成了 v-on 指令的实现,接下来我们来实现将数据代理到 Vue 实例上. 为什么要完成这个功能呢?因为我们在使用 Vue 的时候,可以直接通过 this.xxx 的方式 ...
- 华为云虚拟IP申请
在上一篇文章当中我们搭建好了我们的 Nginx,这节呢,我们主要就是搭建我们的 Keepalive 与 Haproxy,搭建之前我们首先不要将我们华为云上面的弹性公网IP给取消了后续在取消,这次我介绍 ...
- mac中virtualBox添加主机网络报错VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
mac中virtualBox添加主机网络报错 现场复原 解决方法 参考 mac中virtualBox添加主机网络报错 现场复原 virtual box添加主机网络报错 VBoxNetAdpCtl: E ...
- 【Mysql】复合主键的索引
复合主键在where中使用查询的时候到底走不走索引呢?例如下表: create table index_test ( a int not null, b int not null, c int not ...
- BAT大厂面试的100道考题【算法、源码、架构、中间件、设计模式、网络、项目】,过60分的不到10%
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 独生子女生娃,没救了! 考题:https://docs.qq.com/form/page/DT ...
- 遥感图像处理笔记之【Deep learning for Geospatial data applications — Multi-label Classification】
遥感图像处理学习(2) 前言 遥感图像处理方向的学习者可以参考或者复刻 本文初编辑于2023年12月14日 2024年1月24日搬运至本人博客园平台 文章标题:Deep learning for Ge ...
- 6、后端学习规划:Java学习 - 学习规划系列文章
Java语言在现在的编程语言排行榜上也是前5的存在.经过这么些年的发展,Java的发展没有C#这么大,但是在编程领域,因为有MVC架构,以及Spring框架的支持,以及微服务架构等等,Java这些年也 ...