某appvpn代理检测绕过算法定位


安卓获取VPN代码

    安卓vpn检测代码:
    try {
    Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
    int count = 0;
    while (networkInterfaces.hasMoreElements()) {
    NetworkInterface next = networkInterfaces.nextElement();
    logOutPut("getName获得网络设备名称=" + next.getName());
    logOutPut("getDisplayName获得网络设备显示名称=" + next.getDisplayName());
    logOutPut("getIndex获得网络接口的索引=" + next.getIndex());
    logOutPut("isUp是否已经开启并运行=" + next.isUp());
    logOutPut("isBoopback是否为回调接口=" + next.isLoopback());
    logOutPut("**********************" + count++);
    }
    } catch (SocketException e) {
    e.printStackTrace();
    }
  • 上面代码就是获取vpn 名称什么各种信息的代码.有了上诉代码我就来编写frida hook vpn检测的hook脚本

测试案例

  • 我们打开小黄鸟抓包工具。然后打开软件。可以看到检测vpn。因为小黄鸟这个就是基于 vpn的抓包工具。那么如果绕过呢。 (1)我们就需要定位这个检测是在哪个函数。然后hook检测函数绕过。 (2)另外我们也说了我们知道安卓如何获取vpn名称的代码我们可以hook检测到的名称修改成其他名字这不就绕过了.两步都能绕过。
  • 检测vpn

定位思路

  • hook这个温馨提示 这个弹出的框定位检测函数
  • hook vpn检测函数 修改获取到的vpn名称
  • hook vpn检测函数 修改调用检测vpn函数的返回值
  • 第一个我们不知道如何进行hook。我们只知道安卓是如何获取vpn的那么我们编写hook脚本进行定位。直接定位到。hook脚本发布到频道。请到频道下载。
  • 我们可以看到直接hook成功能

  • 我们进一步分析下这个检测函数。用jadx打开app。静态分析一下。一看app被加固了。这个360加固我们常规用frida-dexdump blackdex 进行脱壳。但是经过我测试。这两个都没有脱掉壳。这个壳子升级了。那我们只好祭出。我们修改过的脱壳系统。成功脱掉
  • 360加固

分析app

  • 把脱壳后的zip文件放到jadx里面。由于jadx 反编译不出vpn检测代码我们用jeb进行反编译。我把完整检测代码放出来为了进一步了解是如何检测的。为了保护程序。部分关键代码替换。
  • 检测函数

    vpn检测

    package com.zzzzz.lib_common.utils;
    
    import android.content.Context;
    import android.net.ConnectivityManager;
    import android.text.TextUtils;
    import com.zzzzz.lib_common.constant.CommonConstant;
    import java.net.NetworkInterface;
    import java.net.SocketException;
    import java.util.Collections;
    import java.util.Iterator;
    import timber.log.Timber;
    
    public class CheckDevice {
        public static boolean isVpnUsed() {
            Iterator v0_1;
            if("com.zzzzz.shenji".equals(CommonConstant.PACKAGE_NAME)) {
                return 0;
            }
    
            try {
                v0_1 = Collections.list(NetworkInterface.getNetworkInterfaces()).iterator();
            }
            catch(SocketException v0) {
                v0.printStackTrace();
                return 0;
            }
    
            String v2 = "";
            try {
                while(true) {
                label_10:
                    if(!v0_1.hasNext()) {
                        return 0;
                    }
    
                    Object v3 = v0_1.next();
                    NetworkInterface v3_1 = (NetworkInterface)v3;
                    if(v3_1.isUp()) {
                        v2 = v3_1.getName();  //hook点
                    }
    
                    if(!v2.contains("tun") && !v2.contains("ppp") && !v2.contains("pptp")) {
                        goto label_10;
                    }
    
                    Timber.d("VPNname %s", new Object[]{v2});
                    return 1;
                }
            }
            catch(SocketException v0) {
            }
    
            v0.printStackTrace();
            return 0;
        }
    
        public static boolean isWifiProxy() {
            if("com.zzzzz.shenji".equals(CommonConstant.PACKAGE_NAME)) {
                return 0;
            }
    
            String v0 = System.getProperty("http.proxyHost");
            String v2 = System.getProperty("http.proxyPort");
            if(v2 == null) {
                v2 = "-1";
            }
    
            Timber.d("代理proxyAddress %s", new Object[]{v0});
            Timber.d("代理proxyPort %s", new Object[]{((int)Integer.parseInt(v2))});
            return !TextUtils.isEmpty(v0) && Integer.parseInt(v2) != -1;
        }
    
        public static boolean vpnnetworkCheck(Context arg2) {
            if("com.zzzzz.shenji".equals(CommonConstant.PACKAGE_NAME)) {
                return 0;
            }
    
            try {
                ConnectivityManager v2_1 = (ConnectivityManager)arg2.getSystemService("connectivity");
                return v2_1.getNetworkCapabilities(v2_1.getActiveNetwork()).hasTransport(4);
            }
            catch(Exception v2) {
                v2.printStackTrace();
                return 0;
            }
        }
    }
    
    

定位弹窗

  • 上一步我们分析了检测代码我们这来分析这个弹窗如何hook分析一下代码。查找。
  • 看到了检测点。由于这是表面所以我们要深入进行分析分析调用逻辑。
  • 下图调用这个setMessage 返回是他自己定义类那我们只有。从函数参数入手来定位了。发现是这个 this.binding.textContent.setText(charSequence); 。我们看 追踪到 public final TextView textContent; 可以看到import android.widget.TextView;这个属于安卓的那我们就hook这个看看
  • hook关键函数。我们hook到了。这个代码你们自己写就行了。我就不放了。到这里我们已经搞定抓包了。

算法定位

  • 来到登陆界面点击登陆抓包。咋眼一看。这和md5类似。掏出我们的算法通杀脚本进行。hook发现hook不到
  • 放大招了我们祭出我自己总结的hook脚本来hook一下。hook到了。自己写的果然是比较不错哈哈哈。
  • 看了一下在标准md5得到结果以后对结果进行加工了一下。难怪hook不到。。。。
  • 截图

hookvpn脚本下载

  • 分析到这里就分析完了。下载地址:https://t.me/SoftwareUpdateChannel/196

文章作者: peiqiF4ck
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 peiqiF4ck !
  目录