某8旗下安某某App登录参数分析

查看 9|回复 1
作者:cure888   
本文仅作为个人技术学习与研究的记录,旨在分享逆向分析的思路和方法,不涉及也不鼓励任何形式的商业破解、盗版传播或非法用途。文中所有示例与操作均出于技术探讨目的,且涉及的关键信息已进行脱敏处理,不会影响或泄露实际软件的商业利益。
如有内容存在侵权或不当之处,请联系我,我将第一时间删除或修正。环境及版本:
  • 手机: Pixel 4xl android12
  • frIDA-server 魔改16.6.6
  • App版本:17.24.1
    工具:jadx-gui 1.5.2 ida9.2 Pro Charles+Postern+JustTrustMe++抓包: 用的 Charles+Postern+JustTrustMe++ 抓


    image-20250912174533239.png (44.95 KB, 下载次数: 2)
    下载附件
    2025-9-14 16:59 上传

    通过观察,logininfo被加密了分析Java层:将apk放到桌面,打开jadk,把apk拖进去,搜索"logininfo"


    image-20250912192155751.png (64.07 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:02 上传

    只有这一个,点进去观察能看到doEncrypt传入了   jSONObject.toString() + com.wuba.loginsdk.network.l.a.a()是账号密码组成的json格式的数据转成字符串和另外一个字符串拼接而成.跟进a方法继续分析public static java.lang.String a() {
            java.lang.String r2;
            android.net.NetworkInfo r2;
            //省略不是那么重要的代码
            java.lang.String r3 = !android.text.TextUtils.isEmpty(com.wuba.loginsdk.internal.l.a.H().L()) ? com.wuba.loginsdk.internal.l.a.H().L() : "";
            if (!com.wuba.loginsdk.b.b.v(com.wuba.loginsdk.b.d.L)) {
                r3 = "";
            }
            java.lang.String r1 = com.wuba.loginsdk.network.l.a.c.replace("%nettype", r2).replace("%deviceid", com.wuba.loginsdk.data.b.K()).replace("%thirdinfo", com.wuba.loginsdk.thirdapi.ThirdUtils.generateInjectThirdInfo()).replace("%preMobileMaskMd5", android.text.TextUtils.isEmpty(r3) ? "" : com.wuba.loginsdk.utils.DeviceUtils.encryptionMD5(r3.getBytes())).replace("%preMobileMaskFormat", com.wuba.loginsdk.utils.o.e(r3)).replace("currentTimeMillis", java.lang.String.valueOf(java.lang.System.currentTimeMillis())).replace("randomUUID", com.wuba.loginsdk.utils.DeviceUtils.getRandomUUID());
            com.wuba.loginsdk.log.LOGGER.d("NetWorkFactory", r1);
            return r1;
        }
    ​这里能看到返回的r1是由com.wuba.loginsdk.network.l.a.c这个字符串通过replace方法处理过后得到,定位com.wuba.loginsdk.network.l.a.c的位置


    image.png (75.07 KB, 下载次数: 1)
    下载附件
    2025-9-14 17:13 上传

    继续跟进b方法public static String b(Context context) throws Throwable {
            String imei = DeviceUtils.getImei(context);
            String model = DeviceUtils.getModel();
            String osVersion = DeviceUtils.getOsVersion();
            String model2 = DeviceUtils.getModel();
            String deivceLanguage = DeviceUtils.getDeivceLanguage();
            String deviceCountry = DeviceUtils.getDeviceCountry();
            String brand = DeviceUtils.getBrand();
            String displayHxW = DeviceUtils.getDisplayHxW(context);
            String applicationName = DeviceUtils.getApplicationName(context);
            String versionName = DeviceUtils.getVersionName(context);
            String timeZone = DeviceUtils.getTimeZone();
            String simOperatorType = DeviceUtils.getSimOperatorType(context);
            String cPUSerial = DeviceUtils.getCPUSerial();
            String deviceMemory = DeviceUtils.getDeviceMemory(context);
            String androidID = DeviceUtils.getAndroidID(context);
            String applicationId = DeviceUtils.getApplicationId(context);
            String wifiSSID = DeviceUtils.getWifiSSID(context);
            String wifiIPAddress = DeviceUtils.getWifiIPAddress(context);
            String emulatorMsg = DeviceUtils.getEmulatorMsg(context);
            boolean zIsDeviceRoot = DeviceUtils.isDeviceRoot();
            int i = !TextUtils.isEmpty(emulatorMsg) ? 1 : 0;
            StringBuilder sb = new StringBuilder();
            sb.append("\u0001");
            sb.append(imei);
            sb.append(f34988b);
            sb.append("android");
            sb.append(f34988b);
            sb.append(model);
            sb.append(f34988b);
            sb.append(osVersion);
            sb.append(f34988b);
            sb.append("%nettype");
            sb.append(f34988b);
            sb.append(model2);
            sb.append(f34988b);
            sb.append(deivceLanguage);
            sb.append(f34988b);
            sb.append(deviceCountry);
            sb.append(f34988b);
            sb.append(brand);
            sb.append(f34988b);
            sb.append(displayHxW);
            sb.append(f34988b);
            sb.append(applicationName);
            sb.append(f34988b);
            sb.append(versionName);
            sb.append(f34988b);
            sb.append(timeZone);
            sb.append(f34988b);
            sb.append(simOperatorType);
            sb.append(f34988b);
            sb.append("");
            sb.append(f34988b);
            sb.append(cPUSerial);
            sb.append(f34988b);
            sb.append(deviceMemory);
            sb.append(f34988b);
            sb.append(f34988b);
            sb.append(f34988b);
            sb.append(wifiSSID);
            sb.append(f34988b);
            sb.append(wifiIPAddress);
            sb.append(f34988b);
            sb.append("");
            sb.append(f34988b);
            sb.append("");
            sb.append(f34988b);
            sb.append(zIsDeviceRoot ? 1 : 0);
            sb.append(f34988b);
            sb.append("%deviceid");
            sb.append(f34988b);
            sb.append(i);
            sb.append(f34988b);
            sb.append(emulatorMsg);
            sb.append(f34988b);
            sb.append("%thirdinfo");
            sb.append(f34988b);
            sb.append(androidID);
            sb.append(f34988b);
            sb.append(applicationId);
            sb.append(f34988b);
            sb.append("%preMobileMaskMd5");
            sb.append(f34988b);
            sb.append("%preMobileMaskFormat");
            sb.append(f34988b);
            sb.append("currentTimeMillis");
            sb.append(f34988b);
            sb.append("randomUUID");
            LOGGER.d("NetWorkFactory", sb.toString());
            return sb.toString();
        }这个方法就是把一系列系统参数拼接到一起,f34988b是#需要注意的一点是这个字符串最前面有一个控制字符\u0001(我最开始没看这个方法,直接hook的doEncrypt拿的明文,这个控制字符看不到,hook这hook那,搞了好久才发现),返回doEncrpt继续分析


    image-20250912192256258.png (68.32 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:00 上传

    很清楚地看到了doEncrypt方法内部逻辑,把明文转成byte数组传入native方法encrypt



    image.png (61.08 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:14 上传

    分析so层:解压apk,拿到lib\armeabi-v7a\下面的libcom_wuba_uc_rsa.so,打开ida分析是个动态注册的,直接进入Jni_Onload


    image.png (110.05 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:15 上传

    点击off_C004( JNINativeMethod 数组的地址)


    image-20250912193226748.png (75.49 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:05 上传

    一眼就看到了加密方法,继续跟进


    image.png (167.66 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:16 上传

    进入j_encrypt_defaultint __fastcall encrypt_default(int byte_len, int byte, int out)
    {
      int result; // r0
      int v6; // r0
      _BYTE *v7; // r4
      int v8; // r8
      int i; // r6
      int v10; // r0
      int v11; // [sp+Ch] [bp-434h]
      _DWORD v13[3]; // [sp+14h] [bp-42Ch] BYREF
      _BYTE v14[128]; // [sp+20h] [bp-420h] BYREF
      _BYTE v15[128]; // [sp+A0h] [bp-3A0h] BYREF
      _BYTE v16[768]; // [sp+120h] [bp-320h] BYREF
    ​
      result = -1;
      if ( byte_len  0 )
          ++v6;
        v16[128 * v6] = 1;
        v11 = v6 = byte_len )
          {
            j_base64_encode_uc(v16, v11 | 1, out);  //base64
            return 0;
          }
          v10 = i Vp$qT#T=phf MA
    image-20250914105830574.png (105.36 KB, 下载次数: 1)
    下载附件
    2025-9-14 17:06 上传

    填充


    image-20250914110416648.png (56.6 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:07 上传

    用时间戳当作随机数种子,生成随机数填充回到rc4,先看看rc4加密逻辑


    image-20250914162440083.png (16.96 KB, 下载次数: 1)
    下载附件
    2025-9-14 17:08 上传



    image-20250914162633164.png (42.92 KB, 下载次数: 1)
    下载附件
    2025-9-14 17:09 上传

    通过j_ch_init初始化,返回一个128长度的数组,再传入j_ch_crypt进行一些列运算,得到真正的S盒,然后进行运算拿到结果,再进行rc4加密(非标准rc4,标准的S盒长度是256)


    image-20250914164434306.png (107.26 KB, 下载次数: 2)
    下载附件
    2025-9-14 17:09 上传

    sq是hook j_ch_init的Onleave的第一个参数


    image-20250914164349136.png (147.57 KB, 下载次数: 1)
    下载附件
    2025-9-14 17:16 上传

    代码是ai写的,自己简单改改就好了,就不贴代码了新手小白第一次尝试,难免有疏漏或不足,欢迎各位批评指正。总结加密流程: 分块加密,每一块最长117,这一块先rsa再rc4,再把每一块加密结果拼接在一起,再在字节数组最后面拼接上0x01,再进行base64加密(+替换成-,/替换成_.=替换成B)

    下载次数, 下载附件

  • xixicoco   

    八旗?什么app啊,看了半天
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部