吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2609|回复: 6
收起左侧

[Android 原创] 某8旗下安某某App登录参数分析

[复制链接]
cure888 发表于 2025-9-14 17:18
本文仅作为个人技术学习与研究的记录,旨在分享逆向分析的思路和方法,不涉及也不鼓励任何形式的商业破解、盗版传播或非法用途。文中所有示例与操作均出于技术探讨目的,且涉及的关键信息已进行脱敏处理,不会影响或泄露实际软件的商业利益。
如有内容存在侵权或不当之处,请联系我,我将第一时间删除或修正。
环境及版本:
  • 手机: 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 通过观察,logininfo被加密了分析Java层:将apk放到桌面,打开jadk,把apk拖进去,搜索"logininfo" image-20250912192155751.png 只有这一个,点进去观察能看到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 继续跟进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 很清楚地看到了doEncrypt方法内部逻辑,把明文转成byte数组传入native方法encrypt
image.png 分析so层:解压apk,拿到lib\armeabi-v7a\下面的libcom_wuba_uc_rsa.so,打开ida分析是个动态注册的,直接进入Jni_Onload image.png 点击off_C004( JNINativeMethod 数组的地址) image-20250912193226748.png 一眼就看到了加密方法,继续跟进 image.png 进入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 <= 585 && byte )
  {
    v6 = sub_4C4C(byte_len, 117);
    v7 = v16;
    if ( byte_len - 117 * v6 > 0 )
      ++v6;
    v16[128 * v6] = 1;
    v11 = v6 << 7;
    j_apply(v13, 32, v15);
    j_hexsToBigInt(
      "bc587820f3ad01608b64af88af1ee883bed3e4954457da8f7b5af76403c40329bc4f5e66e46f83eacfba28b2a4d3a61553ee237db6c22f49f5"
      "377e4d6ac3b63b3cd36a9746f9dc6bdd7c2aae26020a6b6fc1ac6399b4da58f8ed3944686cfaca328d1dd581ef86d1dbe87c12af0130e8ce72"
      "8d00814e968bee602752d25ac691",
      v13);
    v8 = 0;
    for ( i = byte_len; ; i -= 117 )
    {
      if ( v8 >= byte_len )
      {
        j_base64_encode_uc(v16, v11 | 1, out);  //base64
        return 0;
      }
      v10 = i < 118 ? i : 117;
      if ( j_encrypt_one_group(v10, byte + v8, 65537, v13[0], v13[1], v13[2], v14) ) //加密
        break;
      qmemcpy(v7, v14, 0x80u);
      v7 += 128;
      v8 += 117;
    }
    return -1;
  }
  return result;
}大概看一下,像rsa加密,分析一下逻辑整个代码是一个 分块加密,每一块是117个字节,加密逻辑在j_encrypt_one_group这个函数里面,每次加密117个字节,再拼接在一起,最后在末尾拼接了一个字节0x01,在进行base64编码。分析j_encrypt_one_group:int __fastcall encrypt_one_group(char *byte_len, int byte, int a3, int a4, int a5, int a6, int out)
{
  _BYTE v8[132]; // [sp+10h] [bp-98h] BYREF
&#8203;
  if ( j_encrypt(byte_len, byte, a3, a4, a5, a6, out) )
    return -1;
  memset(v8, 0, 0x80u);
  j_ch_init(v8, "1V:8(Nqa,U&Ll.RW2 @slN>Vp$qT#T=phf MA<0GO/6V+rW-A!");
  j_ch_crypt(v8, out, 128);
  return 0;
}这里先进行了一个RSA加密,再把加密结果进行了RC4加密进入j_encrypt image-20250914105830574.png 填充 image-20250914110416648.png 用时间戳当作随机数种子,生成随机数填充回到rc4,先看看rc4加密逻辑 image-20250914162440083.png image-20250914162633164.png 通过j_ch_init初始化,返回一个128长度的数组,再传入j_ch_crypt进行一些列运算,得到真正的S盒,然后进行运算拿到结果,再进行rc4加密(非标准rc4,标准的S盒长度是256) image-20250914164434306.png sq是hook j_ch_init的Onleave的第一个参数 image-20250914164349136.png 代码是ai写的,自己简单改改就好了,就不贴代码了新手小白第一次尝试,难免有疏漏或不足,欢迎各位批评指正。总结加密流程: 分块加密,每一块最长117,这一块先rsa再rc4,再把每一块加密结果拼接在一起,再在字节数组最后面拼接上0x01,再进行base64加密(+替换成-,/替换成_.=替换成B)
image-20250912193010801.png
image-20250912192256258.png
image-20250912192431891.png
image-20250912193730436.png
image-20250914164349136.png

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
buluo533 + 1 + 1 用心讨论,共获提升!
helian147 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

xixicoco 发表于 2025-9-15 22:38
八旗?什么app啊,看了半天
hackest 发表于 2025-9-16 04:24
红动中国 发表于 2025-9-16 09:32
zx45283 发表于 2025-9-16 16:46
红动中国 发表于 2025-9-16 09:32
八旗是干什么的,学习资料的吗

某8 旗下 安xx,应该就是安居客了
fuyucc 发表于 2025-9-18 08:40
不错,学习了
kxkj 发表于 2025-10-14 11:33
学习了学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-2-9 07:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表