吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5320|回复: 30
收起左侧

[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] 纯文本查看 复制代码
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, 2024-11-22 11:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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