首页
社区
课程
招聘
[原创]一个app的登录字段分析
发表于: 2024-11-25 17:43 2230

[原创]一个app的登录字段分析

2024-11-25 17:43
2230

声明

本文仅限于技术讨论,不得用于非法途径,后果自负。

简介

这是一个公司出的一个面试题,他说他们的几个技术没有搞定,要求能够拉取详单,简单看了下,强度并不高,且要求提供测试账号也并没有满足,所以应该是骗方案的,不过虽然强度不高,但是很适合我这种萌新练习,定位代码的学习,所以自己给自己定了个任务,从登录协议中还原出输入的手机号。

抓包

下载Charles 根据网络上的抓包文档搭建了一个抓包环境。
https://blog.csdn.net/ZDK_001/article/details/142958082
在登录页面 输入8888888888 点击登录
图片描述
哦吼,没有抓到,apk有证书校验
这一步反而是耗时最久的 我用 objection 的hookssl,xposed 上的 just trust me,网络上的hook ssl的脚本都没有绕过去,最后是看了肉丝写的r0capture写的代码
图片描述
通过定位调堆栈用 找到了证书单向校验的代码nop掉才绕过去
图片描述

1
2
3
4
let a = Java.use("okhttp3.x$a");
       a["e"].implementation = function (certificatePinner:any) {
           return null;
       };

定位代码

抓包解决后
Charles 看登陆包
图片描述
可以看到 mobileNumber 就是我们需要找的东西
观察value特征 很明显可以看到base64的特征(=),干完才想到这里可以通过hookbase64的java库来快速定位代码。

字符串定位

直接使用jadx搜索"mobileNumber"这个uri字符串 查找他组包的过程
图片描述
这里就是无聊的重复过程 frida hook 看走没走 如果走打印堆栈
图片描述
之后定位到了这里invokeSuspend 函数
图片描述
注意这里 使用frida打印参数后发现 这两个字符串是
协议中的两个字段
图片描述
在观察这个类的名称 图片描述
应该是找到了
hook 这个init函数
图片描述
查看内容 发现encryptValue 是mobileNumber" 这个字段的值,查看这个类的的其他方法 发现tostrig 方法吧可以字段名称给还原了

1
2
3
public String toString() {
       return "EncryptionParamRes(key=" + this.strmobileNumber + ", value=" + this.mobileNumber + ", encryptValue=" + this.encryptValue + ", symmetricKey=" + this.AESKey + ", publicKeyEncrypted=" + this.AESkeyRSATwo + ", publicKey=" + this.str + ")";
   }

打印这个构造的堆栈
跟踪这个 encryptValue 是怎么来的定位到加密函数
图片描述
接着就是还原 对这个逻辑详细分析还原逻辑 ,不说 as强制生成的检查对还原轮廓及帮助很大
图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Encrypt {
    public static final String rastwo(String symmetricKey, String base64PublicKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
 
 
        byte[] bArr = Base64.decode(base64PublicKey, 2);
 
        PublicKey key = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(bArr));
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(1, key);
        byte[] bytes = symmetricKey.getBytes(UTF_8);
        byte[] bytes2 = ("FREECHARGE_V2|" + Base64.encodeToString(cipher.doFinal(bytes), 2)).getBytes(UTF_8);
        return Base64.encodeToString(bytes2, 2);
    }
 
    public static final String aesinput(String input, String symmetricKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] IV = new byte[12];
        SecretKeySpec secretKeySpec = SecretKey(symmetricKey);
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(1, secretKeySpec, new GCMParameterSpec(128, IV));
        byte[] bytes = input.getBytes(UTF_8);
        byte[] bytes2 = ("FREECHARGE_V2|" + Base64.encodeToString(cipher.doFinal(bytes),2)).getBytes(UTF_8);
 
        return Base64.encodeToString(bytes2, 2);
    }
 
    public static final SecretKeySpec SecretKey(String secretKey) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        byte[] bytes = secretKey.getBytes(UTF_8);
        byte[] digest = messageDigest.digest(bytes);
        byte[] copyOf = Arrays.copyOf(digest, 16);
        SecretKeySpec secretKeySpec = new SecretKeySpec(copyOf, "AES");
        return secretKeySpec;
    }
 
}

协议

1.随机生成aes密钥
2.使用固定rsa公钥对aes密钥 加密并base64 加盐("FREECHARGE_V2|")再次base64,放在cske字段
3.把rsa公钥放在pke 字段 ???(这里不是用私钥解密吗我去)
3.对密文使用aes加密 加密并base64 加盐("FREECHARGE_V2|")再次base64,放在mobileNumber字段

结语

这个字段搞了十几个小时,几乎有七八个小时都耗在抓包上了,只能够说自己的底蕴还是不够,花了很多时间找相关资料并试错,以此贴纪念自己第一次协议逆向吧,也帮助和我一样的萌新体验一次抓包逆向的全流程。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (3)
雪    币: 369
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
大佬厉害
2024-11-26 08:44
0
雪    币: 928
活跃值: (1878)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
牛牛牛
2024-11-26 09:19
0
雪    币: 1429
活跃值: (1560)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大佬厉害
2024-11-28 14:51
0
游客
登录 | 注册 方可回帖
返回
//