js逆向实战之一品威客signature参数解密

url: https://www.epwk.com/login.html

分析过程

  1. 输入用户名和密码,看触发的流量包。
    image

  2. signature参数明显是被加密过的,接下来就是去寻找加密的过程。关键词搜索signature
    image
    有两处,第二处是个固定值不需要看,关注点在第一处。

  3. 点进去看对应的代码,并打断点,重新登录,触发该断点。
    image
    查看该行代码所有变量的值。
    image
    总共是4个关注点,Object(f.a)是个函数,UMl.j ? l.g : l.c是传给Object(f.a)函数的三个变量。

  4. 先看三个变量中的l.j ? l.g : l.cl.j为false,所以会取l.c
    image

  5. 再看U变量。
    image
    U的定义如下:
    image
    其中需要考虑的变量只有TimestempNonceStrApp-Id,其余值都是固定的。
    App-Id的值最容易得到,由于l.j为false,故App-Id的值为l.b的值。
    Timestemp的值就是个时间戳。
    NonceStr的变量稍微麻烦点,由TimestempObject(h.e)()拼接而成。看Object(h.e)()是什么。
    image
    该函数本质上就是生成一个随机字符串并截取字符串中的第3位到第8位,既然是个随机函数,所以该值取什么无所谓。

  6. 最后看M变量。
    image
    其中的username和password和code就是我们输入的账号密码和图片验证码。refer可以理解成一个固定值,不用变。

  7. 变量看完了,最后来看Object(f.a)函数。
    image
    看到函数中的变量都跟arguments有关,先看arguments是什么。
    image
    arguments是个字典,第一个键值对中的值就是U变量,第二个键值对中的值就是M变量,第三个键值对中的值是个定值。那么变量datae很容易就能得到。
    n = e + f(data) + f(t) + e中需要知道f函数的作用和变量t是什么。
    image
    变量t跟变量U是一致的。
    函数f的实现如下。
    image
    如果我们看不懂具体代码是什么意思,可以将结果输出看看。
    image
    大概就是一个字符串的拼接。
    最后看dv函数。
    image
    image
    d函数是一个md5算法,v算法是一个AES加密,只要知道了密钥、偏移量和加密模式即可。
    image
    上图中显示的key和iv都是字节,想要看到字符串类型的话可以采用toString函数。
    image

  8. 一切加密过程都知道了,把相关代码复制,完整代码如下。

var CryptoJS = require("crypto-js");

function test(t, arguments) {
    var data = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}
      , e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "a75846eb4ac490420ac63db46d2a03bf"
      , n = e + f(data) + f(t) + e;
    return n = d(n),
    n = v(n)
}

r = {};

r.a = function(e) {
    return typeof e
};

function f(t) {
	var e = "";
	return Object.keys(t).sort().forEach((function(n) {
	    e += n + ("object" === Object(r.a)(t[n]) ? JSON.stringify(t[n], (function(t, e) {
	        return "number" == typeof e && (e = String(e)),
	        e
	    }
	    )).replace(/\//g, "\\/") : t[n])
	}
	)),
	e
}


l = {
    "key": {
        "words": [
            1717059670,
            2034454870,
            1987077226,
            944915297
        ],
        "sigBytes": 16
    },
    "iv": {
        "words": [
            0,
            0,
            0,
            0
        ],
        "sigBytes": 16
    }
};

function d(data) {
    return CryptoJS.MD5(data).toString()
}

function v(data) {
    return function(data) {
        return CryptoJS.AES.encrypt(data, l.key, {
            iv: l.iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        }).toString()
    }(data)
}

测试一下。

t = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    "Imei": "",
    "Access-Token": "",
    "Timestemp": 1713833424,
    "NonceStr": "1713833424aoi0s",
    "App-Id": "4ac490420ac63db4",
    "Device-Os": "web"
};

arguments = {
    "0": {
        "App-Ver": "",
        "Os-Ver": "",
        "Device-Ver": "",
        "Imei": "",
        "Access-Token": "",
        "Timestemp": 1713833424,
        "NonceStr": "1713833424aoi0s",
        "App-Id": "4ac490420ac63db4",
        "Device-Os": "web"
    },
    "1": {
        "username": "111111",
        "password": "111111",
        "code": "qwrd",
        "hdn_refer": "https://www.epwk.com/"
    },
    "2": "a75846eb4ac490420ac63db46d2a03bf"
};

console.log(test(t, arguments));

结果如下:
image
可以得到正确的加密结果。

如果想要在python中运行,需要加入下述代码:

import time
import execjs

App_Ver = ""
Os_Ver = ""
Device_Ver = ""
Imei = ""
Access_Token = ""
App_Id = "4ac490420ac63db4"
Device_Os = "web"
timestamp = int(time.time())
NonceStr = "{}fj1e".format(timestamp)


t = {
    "App-Ver": App_Ver,
    "Os-Ver": Os_Ver,
    "Device-Ver": Device_Ver,
    "Imei": Imei,
    "Access-Token": Access_Token,
    "Timestemp": timestamp,
    "NonceStr": NonceStr,
    "App-Id": App_Id,
    "Device-Os": Device_Os
}

arguments = {
    "0": t,
    "1": {
        "username": "111111",
        "password": "123456",
        "code": "zyp6",
        "hdn_refer": "https://www.epwk.com/"
    },
    "2": "a75846eb4ac490420ac63db46d2a03bf"
}

f = open("解密.js", mode="r", encoding="utf-8")
exec_js = f.read()

exec_code = execjs.compile(exec_js)
print(exec_code.call("test", t, arguments))
posted @ 2024-04-23 12:09  死不悔改奇男子  阅读(82)  评论(0编辑  收藏  举报