案例-一品威客

网址:  https://www.epwk.com/

 

输入错误的账号密码,点击发送,可以得到请求:

下面的NonceStr需要关注一下,大概率是需要逆向的

还有下面这两个:大概率也是需要逆向

选取一个关键字全局搜索:发现有两个JS文件都有

在第一个JS文件打上断点:

第二个JS文件中:看到是一个小写的,大概率不太像。

回到我们断点的地方:刷新运行,然后观察输出结果:

对比参数的值,发现是一致的。

 

这里iv是一个大坑:'0000000000000000'  是一个字符串

正确的iv是: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

而 x00 是空字符:

 

Python代码:

import subprocess
from functools import partial

subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")

import execjs
import requests
import json

f = open("一品威客.js", mode='r', encoding="utf-8")
js_code = f.read()
f.close()

js = execjs.compile(js_code)

data = {
    "code": "",
    "hdn_refer": "",
    "password": "123456",
    "username": "13211134154",
}

url = "https://www.epwk.com/api/epwk/v1/user/login"

session = requests.session()
session.headers = js.call("fn", data)  # js代码调整成了. 最方便调用的样子.
session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"

resp = session.post(url, data=data)
print(resp.text)
一品威客.js
 var crypto = require("crypto");
var CryptoJS = require("crypto-js");

h = function(t) {
    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;
    n = d(n);
    n = v(n);
    return n;
}

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

d = function(e){
    return crypto.createHash("md5").update(e).digest('hex');
}

l = {
    key: CryptoJS.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),
    iv: CryptoJS.enc.Utf8.parse(function(t) {
        for (var e = "", i = 0; i < t.length - 1; i += 2) {
            var n = parseInt(t[i] + "" + t[i + 1], 16);
            e += String.fromCharCode(n)
        }
        return e
    }("00000000000000000000000000000000"))
    // 这里iv是一个大坑....
    // 这个iv可不是'0000000000000000'
    // 正确的iv是: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
}

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

function fn(P){
    let D = parseInt((new Date).getTime() / 1e3)
    var U = {
        "App-Ver": "",
        "Os-Ver": "",
        "Device-Ver": "",
        "Imei": "",
        "Access-Token": "",
        "Timestemp": D+"",
        "NonceStr": "".concat(D).concat('u1gq2'),
        "App-Id": "4ac490420ac63db4",
        "Device-Os": "web",
    };
    U['Signature'] = h(U,P, "a75846eb4ac490420ac63db46d2a03bf")
    return U;
}
posted @ 2023-08-22 12:44  屠魔的少年  阅读(9)  评论(0)    收藏  举报