一.检测代理
1. 原理
APP在发起网络请求前会检测系统是否设置了代理,如果发现有代理,就不发起请求。以下是一段APP检测系统是否有代理的实例代码:
public static boolean isWifiProxy(Context context) {
final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
String proxyAddress;
int proxyPort;
if (IS_ICS_OR_LATER) {
proxyAddress = System.getProperty("http.proxyHost"); //获取代理主机
String portStr = System.getProperty("http.proxyPort"); //获取代理端口
proxyPort = Integer.parseInt((portStr != null ? portStr : "-1"));
} else {
proxyAddress = android.net.Proxy.getHost(context);
proxyPort = android.net.Proxy.getPort(context);
}
Log.i("代理信息","proxyAddress :"+proxyAddress + "prot : " proxyPort")
return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
}
2.特征
设置手机代理后,APP无法获取网络数据。
3.绕过方法
-
直接在系统底层使用
iptables
强制转发流量(ProxyDroid:全局模式) -
反编译APP,在
smali
代码中修改检测代理的代码逻辑
4.参考文章
- ProxyDroid绕过APP代理检测:https://www.yuque.com/m1tang/itccm5/byyyox
- App防止被抓包:https://blog.csdn.net/feng___chen/article/details/100855576
二、No Proxy
1.原理
APP 用了No Proxy
参数发起网络请求,即使系统设置了代理,也会被直接绕过。
以下是一段使用No Proxy
参数发起网络请求的代码:
public void run() {
Looper.prepare();
OkHttpClient okHttpClient = new OkHttpClient.Builder().
proxy(Proxy.NO_PROXY). //使用此参数,可绕过系统代理直接发包
build();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
Toast.makeText(this, Objects.requireNonNull(response.body()).string(), Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
Looper.loop();
}
2.特征
设置代理后,APP依然能正常获取网络数据,但抓包工具无法抓到该APP的数据包。
3.绕过方法
-
直接在系统底层使用
iptables
强制转发流量(ProxyDroid:全局模式) -
以VPN形式设置代理(Drony,启动后手机状态栏上会显示VPN图标)
4.参考文章
- ProxyDroid绕过APP代理检测:https://www.yuque.com/m1tang/itccm5/byyyox
- 使用Drony突破APP不走代理:https://www.cnblogs.com/lulianqi/p/11380794.html#%E9%83%A8%E5%88%86%E5%BA%94%E7%94%A8%E4%B8%8D%E8%83%BD%E6%8A%93%E5%8C%85%E7%9A%84%E5%8E%9F%E5%9B%A0
- 如何让app不走系统代理:https://blog.csdn.net/u013356254/article/details/104725952
- Android 跳过系统代理防止被抓包采集:https://blog.csdn.net/seoyundu/article/details/88112684
三、SSL Pinning证书锁定
1.原理(多种实现方式,以下为 “证书特征码比对方式”)
开发者将SSL证书的某些字节码硬编码在APP中。当应用程序与服务器通信时,它将检查证书中是否存在相同的字节码。如果存在,则应用程序将请求发送到服务器。如果字节码不匹配,它将抛出SSL证书错误。此技术可防止攻击者使用自己的自签名证书。
实现方法当然不止这一种,例如以下是一段通过预埋证书来进行 SSL Pinning 的代码:
2.特征
挂代理后无法抓包,且APP无法获取网络数据。
3.绕过方法
-
逆向 APP 取出证书,导入到抓包程序中:证书通常在 /assets 里,jadx 反编译后搜索 .p12 .pem .cer ssl 等关键词
-
JustTruetMe:手机上部署xposed框架,然后安装此模块,对目标APP生效即可
-
Frida:自己对APP逆向分析后,手动使用 Frida 去 hook 证书校验的代码
-
局限性
虽然说我们可以使用通用的 HOOK 方式去修改证书校验的结果,但是开发人员也可以使用代码混淆的办法来对抗hook。开发人员只需要将证书校验的那部分代码混淆,就能够防止通用的SSL unpinning方法。这时候我们就只能反编译代码,自己去寻找代码中进行证书校验的位置,然后自己编写hook代码去进行SSL pinning的绕过。
4.参考文章
- Android 7.0 Https抓包单双向验证解决方案汇总:https://www.yuanrenxue.com/app-crawl/android-7-capture-data.html
- APP 绕过 SSL Pinning 机制抓取Https请求:https://www.cnblogs.com/yyoba/p/12370510.html
- Android应用中https SSL pinning以及绕过的方法介绍:https://zhuanlan.zhihu.com/p/127847550
四、双向认证
1.原理
相比 SSL Pinning,双向认证是服务器也对客户端一个提取预埋的证书进行了SSL Pinning。
2.特征
绕过 SSL Pinning 后仍然无法抓包,且 APP 无法获取网络数据。
3.绕过方法
-
逆向 APP 提取出客户端证书,并将证书挂载到抓包代理软件上
4.参考文章
- Android 7.0 Https抓包单双向验证解决方案汇总:https://www.yuanrenxue.com/app-crawl/android-7-capture-data.html
- APP双向认证绕过:https://blog.csdn.net/weixin_39907157/article/details/111112881
- 绕过SSL双向校验抓取Soul App的数据包:https://blog.csdn.net/qq_38316655/article/details/104176882
- 安卓APP抓包之双向认证突破:https://bbs.pediy.com/thread-265404.htm