跳到主要内容

Android 代理及 VPN 检测初探

· 阅读需 4 分钟
声明

本文版权归原作者所有,转载请注明出处。

前言

大多数 APP 为了防止自身被抓包,通常会采用检测代理或者 VPN 的方式,检测 VPN 实际上也还是检测代理,VPN 最终实现的还是代理的一个效果。

在 APP 渗透中,往往需要绕过 APP 检测代理,知己知彼才能百战百胜,因此必须了解它的检测原理,才能更好地与之对抗。了解检测原理后,后续只需要使用一些 Android 的一些 Hook 框架(Xposed、Frida )或者使用成熟的模块来绕过它的检测,当然,部分 APP 也会加固从而防止反编译甚至是 Hook 检测,这里就不多说了。

由于我不是专业的 Android 开发工程师,因此只能参考网上资料以及询问 ChatGPT 来辅助学习,大部分代码都是由 ChatGPT 生成的,我只是修改了部分检测逻辑,以下代码仅支持 Android 8.0 及以上。

检测方式

检测系统属性

通过获取系统的属性来判断,由于 Android 系统是 Java 开发的,而 Java 提供了一系列的系统属性,在属性中就有针对代理的:

System.getProperty("http.proxyPort");  
System.getProperty("http.proxyHost");

在判断时只需检测这两个属性即可,如果需要绕过,Hook System.getProperty 这个方法就行。

检测 VPN 网络接口特征

在 Android 中如果开启了 VPN,则在网络接口中多出一个类似名为 tun0 的网卡,因此只需通过 Java 提供的 NetworkInterface 类来枚举网络接口的名称即可,如下:

// 检测VPN接口  
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
if (interfaces != null) {
for (NetworkInterface networkInterface : Collections.list(interfaces)) {
String interfaceName = networkInterface.getName().toLowerCase();
if (interfaceName.contains("tun") || interfaceName.contains("tap") || interfaceName.contains("vpn")) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}

如果需要绕过,则 Hook networkInterfacegetName 方法即可,经过测试,算法助手隐藏VPN 选项就只针对这种方式进行了 Hook,其余的方式都没触及。 `

通过 Android API 检测

Android 系统本身也提供了一些 API 来帮助开发者判断设备的网络情况,检测方式如下:

 // 通过系统API判断是否使用VPN  
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
Network activeNetwork = cm.getActiveNetwork();
NetworkCapabilities capabilities = cm.getNetworkCapabilities(activeNetwork);
if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
return true;
}
}

如果需要绕过,Hook capabilities.hasTransport 这个方法,将其值改为 False,当然这里要注意参数判断为 NetworkCapabilities.TRANSPORT_VPN

总结

以上的检测方式可能不全,但也差不多了应该。

代码已经做成了一个 APP Demo 并开源:https://github.com/yinsel/AndroidCheckProxy

可以尝试下载来绕过看看,当然不要直接绕过我的检测类,那就莫得意思了,也欢迎补充和 Start!