吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6463|回复: 31
收起左侧

[Web逆向] mtgsig1.2简单分析[狗头]

[复制链接]
ZydmxhZ 发表于 2023-10-18 10:43
[JavaScript] 纯文本查看 复制代码
{
 "a1": "1.2",        # 加密版本
 "a2": new Date().valueOf() - serverTimeDiff,       # 加密过程中用到的时间戳. 这次服主变坏了, 时间戳需要减去一个 serverTimeDiff(见a3) ! 
 "a3": "这是把xxx信息加密后提交给服务器, 服主校验成功后返回的一个dfpId",      # dfpId. 服务器返回的dfpId数据包里, 有一个serverTimestamp字段. serverTimeDiff = serverTimestamp - Date.now()
 "a4": "一个长48位的加密结果",                      #  a5, a2以及一小段jsvmp运行后, 输出a4
 "a5": "一个长320位的加密结果",                       # a2, a6, 以及下面的Ln, 计算后输出a5
 "a6": "w1.2xxxxx这一段长512xxxxxxx",        # w1.2 + 客户端环境的加密结果
 "a7": wx["getAccountInfoSync"]().miniProgram.appId,     # 小程序id
 "x0": 3,   # 源代码写死
 "d1": md5ToHex(j)      #  a1, a2, a3, a4, a7以及上面加密过程中出现的一些数组, 经过运算后, 输出d1
}
 
Ln = {
"b1": {appId: "小程序id",  envVersion: "release", version: "微信版本号"},
"b2": "一个url",
"b6": "微信的openId",    # 这个玩意儿可以考虑置空
"b7": Math.floor(Date.now() / 1e3),
"b8": "17"    # 不重要, 1-20给个随机值就行
}


PS:  基于某评微信小程序的guard.js文件, 且文件经过简单的ast脱混淆.
1. 收集的环境
[JavaScript] 纯文本查看 复制代码
Ne = {
                DFP: ["app", "dfpid", "filetime", "fpv", "localid", "system", "timestamp", "ext", "sessionId"],
                system: ["accelerometer", "albumAuthorized", "BatteryInfo", "batteryLevel", "Beacons", "benchmarkLevel", "bluetoothEnabled", "brand", "brightness", "cameraAuthorized", "compass", "deviceOrientation", "devicePixelRatio", "enableDebug", "errMsg", "fontSizeSetting", "language", "LaunchOptionsSync", "locationAuthorized", "locationEnabled", "locationReducedAccuracy", "microphoneAuthorized", "model", "networkType", "notificationAlertAuthorized", "notificationAuthorized", "notificationBadgeAuthorized", "notificationSoundAuthorized", "pixelRatio", "platform", "safeArea", "screenHeight", "screenTop", "screenWidth", "SDKVersion", "statusBarHeight", "system", "version", "wifiEnabled", "WifiInfo", "windowHeight", "windowWidth"],
                BatteryInfo: ["errMsg", "isCharging", "level"],
                safeArea: ["left", "right", "top", "bottom", "width", "height"],
                WifiInfo: ["SSID", "BSSID", "autoJoined", "signalStrength", "justJoined", "secure", "frequency"]
            }


1.1 环境加密逻辑(a6). 主要是找到收集了哪些环境, 以及环境对应的值.

a6

a6


加密函数中只有常见的加密运算符, 没有检测环境的异常分支或其他坑. 所以逆向中遇到的加密函数直接 复制粘贴到自己的代码里就好. 譬如:
[JavaScript] 纯文本查看 复制代码
vn = {
        gzipSync: R,
        compressSync: R,
        strToU8: function (e, n) {
                var a = e.length;
                if (!n && "undefined" != typeof TextEncoder) return new TextEncoder().encode(e);
 
                for (var t = new Je(e.length + (e.length >>> 1)), c = 0, r = function (e) {
                        t[c++] = e;
                }, f = 0; f < a; ++f) {
                        if (c + 5 > t.length) {
                                var o = new Je(c + 8 + (a - f << 1));
                                o.set(t), t = o;
                        }
 
                        128 > (o = e.charCodeAt(f)) || n ? r(o) : 2048 > o ? (r(192 | o >>> 6), r(128 | 63 & o)) : 55295 < o && 57344 > o ? (r(240 | (o = 65536 + (1047552 & o) | 1023 & e.charCodeAt(++f)) >>> 18), r(128 | o >>> 12 & 63), r(128 | o >>> 6 & 63), r(128 | 63 & o)) : (r(224 | o >>> 12), r(128 | o >>> 6 & 63), r(128 | 63 & o));
                }
 
                return nn(t, 0, c);
        }
};
function R(e, n) {
        void 0 === n && (n = {});
        var a = pn(),
                t = e.length;
        a.p(e);
        var c = (e = ln(e, n, 10 + (n.filename && n.filename.length + 1 || 0), 8)).length,
                r = n;
        if (n = r.filename, e[0] = 31, e[1] = 139, e[2] = 8, e[8] = 2 > r.level ? 4 : 9 == r.level ? 2 : 0, e[9] = 3, 0 != r.mtime && gn(e, 4, Math.floor(new Date(r.mtime || Date.now()) / 1e3)), n) for (e[3] = 8, r = 0; r <= n.length; ++r) e[r + 10] = n.charCodeAt(r);
        return gn(e, c - 8, a.d()), gn(e, c - 4, t), e;
}
gn = function (e, n, a) {
                for (; a; ++n) e[n] = a, a >>>= 8;
        },
function J(e) {
        function n() {
                for (var e, n = ["xxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxx"], a = [], c = 0; c < n["length"]; c++) {
                        e = "";
 
                        for (var r = n[c], f = r["length"], o = parseInt("0x" + r["substr"](0, 2)), d = 2; d < f; d += 2) {
                                var i = parseInt("0x" + r["charAt"](d) + r["charAt"](d + 1));
                                e += String["fromCharCode"](i ^ o);
                        }
 
                        a["push"](e);
                }
 
                return a;
        }
 
        var a = ke["codec"]["utf8String"]["toBits"](n()[0]),
                c = ke["codec"]["utf8String"]["toBits"](n()[1]);
        return a = new ke["cipher"]["aes"](a), e = ke["mode"]["cbc"]["encrypt"](a, e, c), ke["codec"]["base64"]["fromBits"](e);
}


2. a2-a8加密前的准备工作.

ready

ready


2.1 a5, a4的加密逻辑(包含两段简单的jsvmp代码, 相对于mtgsig1.1的jsvmp代码, 服主很可能还在练手).

a5, a4

a5, a4


代码中调用的函数也都是简单的运算操作. 例:
[JavaScript] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
Qn = function () {
        for (var n, a, c = 256, r = []; c--; r[c] = n >>> 0) for (a = 8, n = c; a--;) n = 1 & n ? n >>> 1 ^ 3988292384 : n >>> 1;
 
        return function (n) {
                if ("string" == e(n)) {
                        for (var a = 0, c = -1; a < n["length"]; ++a) c = r[255 & c ^ n["charCodeAt"](a)] ^ c >>> 8;
 
                        return 306674911 ^ c;
                }
 
                for (a = 0, c = -1; a < n["length"]; ++a) c = r[255 & c ^ n[a]] ^ c >>> 8;
 
                return 306674911 ^ c;
        };
}();
function Z(e) {
        var n = [];
        return n[0] = e >>> 24 & 255, n[1] = e >>> 16 & 255, n[2] = e >>> 8 & 255, n[3] = 255 & e, n;
}
function X(e) {
        for (var n = [], a = 0; a < e["length"]; a += 2) {
                var c = e["charAt"](a) + e["charAt"](a + 1);
                c = parseInt(c, 16), n["push"](c);
        }
 
        return n;
}
function W(e) {
        e = encodeURIComponent(e);
 
        for (var n = [], a = 0; a < e["length"]; a++) {
                var c = e["charAt"](a);
                "%" === c ? (c = e["charAt"](a + 1) + e["charAt"](a + 2), c = parseInt(c, 16), n["push"](c), a += 2) : n["push"](c["charCodeAt"](0));
        }
 
        return n;
}
function ae(e, n) {
        var a = e["length"];
        n ^= a;
 
        for (var c = 0; 4 <= a;) {
                var r = 1540483477 * (65535 & (r = 255 & e[c] | (255 & e[++c]) << 8 | (255 & e[++c]) << 16 | (255 & e[++c]) << 24)) + ((1540483477 * (r >>> 16) & 65535) << 16);
                n = 1540483477 * (65535 & n) + ((1540483477 * (n >>> 16) & 65535) << 16) ^ (r = 1540483477 * (65535 & (r ^= r >>> 24)) + ((1540483477 * (r >>> 16) & 65535) << 16)), a -= 4, ++c;
        }
 
        switch (a) {
                case 3:
                        n ^= (255 & e[c + 2]) << 16;
 
                case 2:
                        n ^= (255 & e[c + 1]) << 8;
 
                case 1:
                        n = 1540483477 * (65535 & (n ^= 255 & e[c])) + ((1540483477 * (n >>> 16) & 65535) << 16);
        }
 
        return ((n = 1540483477 * (65535 & (n ^= n >>> 13)) + ((1540483477 * (n >>> 16) & 65535) << 16)) ^ n >>> 15) >>> 0 ^ 1540483477;
}


2.2 d1, 以及最终mtgsig赋值

d1, mtgsig

d1, mtgsig

免费评分

参与人数 8吾爱币 +13 热心值 +8 收起 理由
coderxu + 1 用心讨论,共获提升!
笙若 + 1 + 1 谢谢@Thanks!
877758442 + 1 + 1 我很赞同!
mingyuetianya + 1 + 1 我很赞同!
涛之雨 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
GGbond + 1 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 谢谢@Thanks!
TY2325912259 + 1 + 1 感谢您的宝贵建议,我们会努力争取做得更好!

查看全部评分

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

pancake3699 发表于 2024-1-27 00:07
                            var p = K((r = 4294967295 & i)),
                              l = new Uint8Array(W(v)["concat"](p)),
                              g = se["md5"](l),
                              y = Y(g["substring"](0, 15));
                            (y[7] = 255 & (n ^ Qa(p)))
请问下计算a5 的时候 这里 n 的值有影响吗?
福仔 发表于 2024-10-21 10:24
遇到个问题, 怎么传递url计算呢?
我弄的也是1.2的版本, 但是a6那是w1.3

我用小程序打开F12控制台的话小程序就返回403, 我计算的a4代码和小程序打开F12时的是一样的
我看了小程序里计算a4时传的参数, 我跟着小程序那样传递计算出来的结果是和小程序一样
但是用不了, 怀疑小程序打开F12控制台返回403就是检测到了调试环境然后计算a4这里出了什么问题

a4是通过传递的url计算出来一个w值, 还有a5, 然后用这个w值和a5取哈希值进行异或运算, 然后md5ToHex, 最后得到计算a4的3个参数
通过这3个参数计算出a4
所以a4需要 url, 需要a5, 还有a2

d = 4294967295 & a2
S = 取哈希(url计算的w值, a2)
A = 取哈希(a5, a2)
_ = md5ToHex( [S, A, S^d,  S^A^d] )
a4 = 计算a4(S, A, _)
以上就是a4计算的步骤
现在怎么计算w值呢, 弄了好久都没弄好, 有交流的吗
我现在就差怎么传递url计算a4的值了
老M 发表于 2023-10-18 14:42
福仔 发表于 2024-10-21 11:03
福仔 发表于 2024-10-21 10:24
遇到个问题, 怎么传递url计算呢?
我弄的也是1.2的版本, 但是a6那是w1.3

不知道改动了什么, 或者我没注意到, 直接把url传递进去就可以计算出w值
抓包来的mtgsig解密后重新加密都能完全还原了, 但是还是403
估计还是有什么参数影响了
慕星月 发表于 2023-10-18 14:05
很不错哦
老M 发表于 2023-10-18 14:41
有点东西
zhugyun08 发表于 2023-10-19 09:25
感谢大佬的分享!
linguo2625469 发表于 2023-10-19 11:12
看到了 a1就是
一米七五 发表于 2023-10-27 15:07

1.1不是随便撸么
老M 发表于 2023-10-27 17:46

补下环境,改几个方法..
老M 发表于 2023-10-27 17:47

H5端现在都还是1.1吧
一米七五 发表于 2023-10-28 10:47
老M 发表于 2023-10-27 17:47
H5端现在都还是1.1吧

shide     
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-9 22:06

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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