一品威客登陆接口逆向

本文详细解析了如何通过抓包分析,找出目标网站登录请求中的Signature字段,重点剖析了参数U和P,以及涉及的加密函数f.a。作者揭示了参数生成方法,包括时间戳、随机数和特定编码,最后提供了完整的JavaScript代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目标网站

aHR0cHM6Ly93d3cuZXB3ay5jb20vbG9naW4uaHRtbA==

抓包分析

在这里插入图片描述

先抓一个登陆的包,payload里面没有需要分析的数据

在这里插入图片描述

需要分析的数据在请求头里面,我们的目标是分析这个Signature

Signature 分析

在这里插入图片描述

直接搜索这个关键字,可以找到两个位置,第二个是小写的,跟我们要分析的字段没什么关系
在这里插入图片描述

断下以后,这个函数就是我们需要的signature字段,那么就需要分析这个函数

Object(f.a)(U, M, l.j ? l.g : l.c)
分析参数U

函数里面传入了U作为第一个参数

在这里插入图片描述

这里我们需要先搞定参数U的这些字段是怎么来的
在这里插入图片描述

向上找U的来源

var U = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    Imei: "",
    "Access-Token": "",
    Timestemp: D,
    NonceStr: "".concat(D).concat(Object(h.e)()),
    "App-Id": l.j ? l.f : l.b,
    "Device-Os": "web"
};

U的字段如上,这里面App-IdNonceStr都是需要分析的,其他都是固定的

NonceStr: "".concat(D).concat(Object(h.e)())

这个NonceStr字段就是Timestemph.e()函数结果的拼接

在这里插入图片描述

 d = function() {
     var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 5;
     return Math.random().toString(36).substring(3, 3 + e)

通过执行结果和函数原型,就可以知道NonceStr字段其实就是时间戳加上五个随机字符的拼接,既然是随机的我们就可以直接写死。

接着再来看App-Id

"App-Id": l.j ? l.f : l.b

对于App-Id这个字段,我们需要分析l的来源

在这里插入图片描述

这里l.j的值是false,所以App-Id的值是l.b

在这里插入图片描述

找到l.b的来源,这里返回了一个f
在这里插入图片描述

f来源于这个位置

f = (e.env.NUXR_XWZN_DOMAIN,"4ac490420ac63db4")

这里是一个逗号表达式,所以App-Id的值实际上就是固定的。

var U = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    Imei: "",
    "Access-Token": "",
    Timestemp: D,
    NonceStr: "".concat(D).concat(Object(h.e)()),
    "App-Id": "4ac490420ac63db4",
    "Device-Os": "web"
};

到这里参数U我们就分析完了,整理成JS代码如下:

D = parseInt((new Date).getTime() / 1e3);

var U = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    "Imei": "",
    "Access-Token": "",
    "Timestemp": D,
    "NonceStr": "".concat(D).concat("v6j3u"),
    "App-Id": "4ac490420ac63db4",
    "Device-Os": "web"
};
分析参数P
U.Signature = Object(f.a)(U, M, l.j ? l.g : l.c);

这里的第一个参数U我们已经分析完了,接下来分析参数M 。
在这里插入图片描述

参数M就是我们填写的登陆信息,账号密码加上图形验证码。

分析参数l.j

接下来分析参数l.j
在这里插入图片描述

l.j的值是false,所以我们要看l.c的值
在这里插入图片描述

l.c来源于m
在这里插入图片描述

而m也是一个固定值,所以第三个参数我们也分析完了

分析函数f.a
U.Signature = Object(f.a)(U, M, l.j ? l.g : l.c);

接着再来分析调用的函数f.a
在这里插入图片描述

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;
    return n = d(n),
        n = v(n)
}

这里直接把函数拿下来,补齐缺失的代码,放到JS代码里调用就可以了

signature代码实现

const Crypto=require("crypto-js")

D = parseInt((new Date).getTime() / 1e3);

var U = {
    "App-Ver": "",
    "Os-Ver": "",
    "Device-Ver": "",
    "Imei": "",
    "Access-Token": "",
    "Timestemp": D,
    "NonceStr": "".concat(D).concat("v6j3u"),
    "App-Id": "4ac490420ac63db4",
    "Device-Os": "web"
};

var M={'username': '17688888888', 'password': '123456', 'code': 'rtck', 'hdn_refer': ''};


third="a75846eb4ac490420ac63db46d2a03bf";

 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(data) {
    return Crypto.MD5(data).toString();
}

l = {
    key: Crypto.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),
    iv: Crypto.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"))
}
v = function(data) {
    return function(data) {
        return Crypto.AES.encrypt(data, l.key, {
            iv: l.iv,
            mode: Crypto.mode.CBC,
            padding: Crypto.pad.Pkcs7
        }).toString()
    }(data)
    }

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;
    return n = d(n),
        n = v(n)
}

console.log(h(U, M, third));

把所需要的所有的代码全部抠下来,然后尝试运行
在这里插入图片描述

此时,我们已经拿到了signature字段的值了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鬼手56

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值