Web逆向-mtgsig1.2简单分析
{ "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. 收集的环境
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). 主要是找到收集了哪些环境, 以及环境对应的值.
加密函数中只有常见的加密运算符, 没有检测环境的异常分支或其他坑. 所以逆向中遇到的加密函数直接 复制粘贴到自己的代码里就好. 譬如:
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 t.length) { var o = new Je(c + 8 + (a - f (o = e.charCodeAt(f)) || n ? r(o) : 2048 > o ? (r(192 | o >>> 6), r(128 | 63 & o)) : 55295 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 >>= 8; }, function J(e) { function n() { for (var e, n = ["xxxxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxxxxxxxxxxxxxxxxxxxxxx"], a = [], c = 0; c2. a2-a8加密前的准备工作.
2.1 a5, a4的加密逻辑(包含两段简单的jsvmp代码, 相对于mtgsig1.1的jsvmp代码, 服主很可能还在练手).
(图片来源网络,侵删)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 >> 8; return 306674911 ^ c; } for (a = 0, c = -1; a >> 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 16) & 65535) >> 24)) + ((1540483477 * (r >>> 16) & 65535) 16) & 65535) >> 13)) + ((1540483477 * (n >>> 16) & 65535) >> 15) >>> 0 ^ 1540483477; }2.2 d1, 以及最终mtgsig赋值
(图片来源网络,侵删)
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...