首页
社区
课程
招聘
[原创]某行移动端抓包解密
发表于: 2023-3-18 19:52 7690

[原创]某行移动端抓包解密

2023-3-18 19:52
7690

环境

app

加解密

抓到的包如下

可以看到request包中的parameter和response包中的info被加密
分别通过hook可得到未加密之前的数据,即com.xxx.baselibs.http.InvokeRequest和com.xxx.baselibs.http.CommonInvokeListener下

流程分析

根据抓到的特征进行搜索
在com.xxx.baselibs.http.InvokeRequest得到request中被加密parameter的代码
图片描述
函数build中的invokeRequestParameter参数为加密前的数据。

 

而response在com.xxx.baselibs.http.CommonInvokeListener的
图片描述

 

的infostr为加密前的数据。

加密过程分析

request

跟踪函数build中的invokeRequestParameter参数,可以在同页面下得到该class
图片描述

 

在该class下获取各加密前数值(ps:代码长没有全部截图)

 

图片描述

 

之后再利用getRequestMap进行加密

 

图片描述

 

通过对代码的分析,得到其不同的版本加密方式不同,即request包中的ver来判断加密方式
即加密函数RequestConfuse.V3.encodeParameter、RequestConfuse.V2.encodeParameter

当ver=2时

跟踪RequestConfuse.V2.encodeParameter函数,到com.xxx.baselibs.util.RequestConfuse下

 

图片描述

 

parameter到class V2之后第一步到

 

图片描述

 

跟踪该函数到java.net.URLEncoder

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public static String encode(String s, String enc) throws UnsupportedEncodingException {
    BitSet bitSet;
    int charAt;
    int d;
    boolean needToChange = false;
    StringBuffer out = new StringBuffer(s.length());
    CharArrayWriter charArrayWriter = new CharArrayWriter();
    if (enc == null) {
        throw new NullPointerException("charsetName");
    }
    try {
        Charset charset = Charset.forName(enc);
        int i = 0;
        while (i < s.length()) {
            int c = s.charAt(i);
            if (dontNeedEncoding.get(c)) {
                if (c == 32) {
                    c = 43;
                    needToChange = true;
                }
                out.append((char) c);
                i++;
            } else {
                do {
                    charArrayWriter.write(c);
                    if (c >= 55296 && c <= 56319 && i + 1 < s.length() && (d = s.charAt(i + 1)) >= 56320 && d <= 57343) {
                        charArrayWriter.write(d);
                        i++;
                    }
                    i++;
                    if (i >= s.length()) {
                        break;
                    }
                    bitSet = dontNeedEncoding;
                    charAt = s.charAt(i);
                    c = charAt;
                } while (!bitSet.get(charAt));
                charArrayWriter.flush();
                String str = new String(charArrayWriter.toCharArray());
                byte[] ba = str.getBytes(charset);
                for (int j = 0; j < ba.length; j++) {
                    out.append('%');
                    char ch = Character.forDigit((ba[j] >> 4) & 15, 16);
                    if (Character.isLetter(ch)) {
                        ch = (char) (ch - ' ');
                    }
                    out.append(ch);
                    char ch2 = Character.forDigit(ba[j] & 15, 16);
                    if (Character.isLetter(ch2)) {
                        ch2 = (char) (ch2 - ' ');
                    }
                    out.append(ch2);
                }
                charArrayWriter.reset();
                needToChange = true;
            }
        }
        return needToChange ? out.toString() : s;
    } catch (IllegalCharsetNameException e) {
        throw new UnsupportedEncodingException(enc);
    } catch (UnsupportedCharsetException e2) {
        throw new UnsupportedEncodingException(enc);
    }
}

之后进行base64
图片描述

 

最后一步就是进行加密,即(这加密应该是自己写的)

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
36
37
private static String encode(String s) {
            char x;
            int size = s.length();
            StringBuilder sb = new StringBuilder(size);
            double sz = size / 2;
            int i = 0;
            while (true) {
                x = '=';
                if (i >= sz) {
                    break;
                }
                char x2 = s.charAt(i * 2);
                char y = s.charAt((i * 2) + 1);
                sb.append(y == '+' ? '-' : y == '-' ? '+' : y == '*' ? '=' : y == '=' ? '*' : y);
                if (x2 == '+') {
                    x = '-';
                } else if (x2 == '-') {
                    x = '+';
                } else if (x2 != '*') {
                    x = x2 == '=' ? '*' : x2;
                }
                sb.append(x);
                i++;
            }
            if (2.0d * sz < size) {
                char x3 = s.charAt(size - 1);
                if (x3 == '+') {
                    x = '-';
                } else if (x3 == '-') {
                    x = '+';
                } else if (x3 != '*') {
                    x = x3 == '=' ? '*' : x3;
                }
                sb.append(x);
            }
            return sb.toString();
        }

最后返回

当ver=3或者是其他时

跟踪到

 

图片描述

 

在跟踪SmSoftEncrypt.instance().encodeWithSvrSm4Key
到com.xxx.baselibs.util.sm.SmSoftEncrypt

 

图片描述

 

当中svrSm4PKey

 

图片描述

 

可在com.xxx.baselibs.http.InvokeRequest下hook到

 

图片描述

 

随后进行sm4的加密

response

在com.xxx.baselibs.http.CommonInvokeListener中

 

图片描述

 

分析其加密方式跟request是一致的,不同点在 RequestConfuse.V3.decodeNoHex函数上
跟踪来到com.xxx.baselibs.util.RequestConfuse

 

图片描述

 

跟踪来到com.xxx.baselibs.util.sm.SmSoftEncrypt
图片描述
也是sm4的加密


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 221
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
大佬,我也碰到这个APP,能带带我怎么脱壳和绕frida嘛
2023-3-20 16:48
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
wx_偏执。 大佬,我也碰到这个APP,能带带我怎么脱壳和绕frida嘛

这APP是啥APP,只知道是某行 

最后于 2023-3-21 11:22 被思睿编辑 ,原因:
2023-3-21 10:30
0
雪    币: 123
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
666星辰天合
2023-3-21 18:45
0
游客
登录 | 注册 方可回帖
返回
//