某省资源交易中心 (js逆向)

news2024/9/8 23:40:55

该文章只是用于逆向学习,不得以商用或者是破坏他人利益的目的进行使用。如有侵权请联系作者。

网站链接:

bse64

aHR0cHM6Ly9nZ3p5ZncuZnVqaWFuLmdvdi5jbi9idXNpbmVzcy9saXN0Lw==

分析环节

进入网站 进行翻页请求时我们会发现改请求时ajax请求。

这里,我们可以直接看一下请求参数和返回结果,以及表头携带。

请求参数

请求参数中不存在加密

返回数据

data被加密了

 请求头

请求头中存在一个加密参数

此时我们换页,查看改参数是否改变

 

发生改变,所以我们现在需要做的就是先找到请求头中的 portal-sign的加密位置。

由于数据加密的这个过程中我们并不知道再那个文件中,应为返回数据的话是已经得到加密头了,所以这里我们采用搜索关键字的方法来进行快速定位。这也是为什么我不直接使用xhr断点找加密的原因。

搜索关键词portal-sign

找到关键字,点击进入该js文件

打个断点待会好调试

现在我们已经找到加密的位置了,根据名字可以直接确定,这就是加密的赋值操作,现在开始调试,找到加密函数。

执行一步的时候我们发现他出现到这里了,结合上面的f.getsign(e)可以确定,这个过程是正确的

那么,我们先不扣代码,先走一步看看,执行到这里的时候我们需要看一下这些参数是什么

控制台输出一下r["a"]

 

这个值先记录一下

输出l(t),我们可以确定的是,l(t)是一个加密的过程

并且我们看参数t是一个对象

 中间的ts是一个时间戳,带有请求的一些参数,这个先不管

现在继续进入,进入下图文件中。我们发现这个过程是创建了一个Md5对象并且调用了update方法,所以我们已经可以知道这个结果了,以防万一,我们直接跳过调试观察一下。可以验证个参数就是一个通过md5加密的一个过程,你现在可以采用md5加密验证也可以直接扣下来这段代码,我们使用平台是可以直接知道,这个加密就是MD5加密的一个过程,但是为了锻炼我的扣代码能力,我选择了硬扣。如果你不想查看这个过程的话,可以直接略过。

js扣代码环节 

根据我们上边的一些记录我们现在需要做的是,刷新网页,重新打开浏览器,执行一遍这个过程,看看有哪些是固定的。

可以确定r["a"]是没有改变,我们直接搜索这个值看一下有没有

存在,所以现在我们就知道这个过程了,他是将一个请求头t当作参数传递给d在d函数中,通过一个常量和一个加密后的数据进行拼接,然后使用MD5进行加密。

现在开始着手扣第一步代码,得到加密后的n

我喜欢使用html来验证js代码是否完整,所以这里我使用的html讲解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        
function s(t, e) {
    return t.toString().toUpperCase() > e.toString().toUpperCase() ? 1 : t.toString().toUpperCase() == e.toString().toUpperCase() ? 0 : -1
}
function l(t) {
    for (var e = Object.keys(t).sort(s), n = "", a = 0; a < e.length; a++)
        if (void 0 !== t[e[a]])
            if (t[e[a]] && t[e[a]]instanceof Object || t[e[a]]instanceof Array) {
                var i = JSON.stringify(t[e[a]]);
                n += e[a] + i
            } else
                n += e[a] + t[e[a]];
    return n
}
function d(t) {
    for (var e in t)
        "" !== t[e] && void 0 !== t[e] || delete t[e];
    var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);
    console.log(n)
    return u(n).toLocaleLowerCase()
}
t = {
    "ts": 1702288385369,
    "type": "12",
    "IS_IMPORT": 1,
    "pageSize": 3
}
d(t)
    </script>
</body>
</html>

出现的错误是因为没有找到u(n),我们可以发现已经出现拼接好的n了,那么我们可以确定的是,代码已经成功了一步。

现在开始着手MD5加密环节

进入之后,会返回一个new对象,所以直接将u(n)部分替换

替换的代码

function d(t) {
    for (var e in t)
        "" !== t[e] && void 0 !== t[e] || delete t[e];
    var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);
    console.log(n)
    return new Md5(!0).update(n)[t]()

 接下来就i是把整个md5扣下来了

联立前面的代码,我们可以直接放到html中,观察。

这边md5我就不单独放出来了,不然我写着是真的卡

出现错误:找不到这个blocks,那么开始在代码中找这个定义

 还顺带找到了buffers,直接拷贝到文件中。

出现错误

直接在浏览器中打印,是一个ture

直接填写,然后在代码中替换。

现在又出现缺少

我们发现是创建函数出了问题,里面少了一个参数t,直接根据提示,发现是一个字符串,在代码中补全。

现在缺少了一个EXTRA

 

开始找位置,然后补全,在这个位置,直接复制下来

继续找

找到,然后复制下来。

现在没有报错,我们试一下结果对不对。。

完美解决,所以此时我们已经得到了这个正确的js代码,只需要将参数中的ts更改成当前的请求时间戳就行,

这里贴上html代码,你只需要把js部分复制修改即可

1

我们来处理一下此时的python请求,先把第一步确定好。

第一步请求的python代码

import requests
import execjs
ts = int(execjs.compile(open('D:/桌面/pythoncode/new.js', 'r', encoding='utf-8').read()).call('gettime'))

json_data = {
        'pageNo': 1,
        'pageSize': 40,
        'total': 5770,
        'AREACODE': '',
        'M_PROJECT_TYPE': '',
        'KIND': 'GCJS',
        'GGTYPE': '1',
        'PROTYPE': '',
        'timeType': '6',
        'BeginTime': '2022-07-18 00:00:00',
        'EndTime': '2023-01-18 23:59:59',
        'createTime': [],
        'ts': ts,
}
sign  = str(execjs.compile(open('D:/桌面/pythoncode/new.js', 'r', encoding='utf-8').read()).call('main',json_data))
print(sign)
headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json;charset=UTF-8',
        'Origin': 'https://ggzyfw.fujian.gov.cn',
        'Referer': 'https://ggzyfw.fujian.gov.cn/business/list/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
        'portal-sign': sign,
        'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
    }

response = requests.post('https://ggzyfw.fujian.gov.cn/FwPortalApi/Trade/TradeInfo', headers=headers, json=json_data).json()
print(response)

得到请求头加密参数

HEX_CHARS = "0123456789abcdef".split("")
EXTRA = [128, 32768, 8388608, -2147483648]
var buffer = new ArrayBuffer(68);
buffer8 = new Uint8Array(buffer),
blocks = new Uint32Array(buffer)
function Md5(t) {
    if (t)
        blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0,
            this.blocks = blocks,
            this.buffer8 = buffer8;
    else if (true) {
        var n = new ArrayBuffer(68);
        this.buffer8 = new Uint8Array(n),
            this.blocks = new Uint32Array(n)
    } else
        this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0,
        this.finalized = this.hashed = !1,
        this.first = !0
}
Md5.prototype.update = function (t) {
    if (!this.finalized) {
        var n, e = typeof t;
        if ("string" !== e) {
            if ("object" !== e)
                throw ERROR;
            if (null === t)
                throw ERROR;
            if (true && t.constructor === ArrayBuffer)
                t = new Uint8Array(t);
            else if (!Array.isArray(t) && (!true || !ArrayBuffer.isView(t)))
                throw ERROR;
            n = !0
        }
        var r, i, o = 0, c = t.length, A = this.blocks, a = this.buffer8;
        while (o < c) {
            if (this.hashed && (this.hashed = !1,
                A[0] = A[16],
                A[16] = A[1] = A[2] = A[3] = A[4] = A[5] = A[6] = A[7] = A[8] = A[9] = A[10] = A[11] = A[12] = A[13] = A[14] = A[15] = 0),
                n)
                if (true)
                    for (i = this.start; o < c && i < 64; ++o)
                        a[i++] = t[o];
                else
                    for (i = this.start; o < c && i < 64; ++o)
                        A[i >> 2] |= t[o] << SHIFT[3 & i++];
            else if (true)
                for (i = this.start; o < c && i < 64; ++o)
                    r = t.charCodeAt(o),
                        r < 128 ? a[i++] = r : r < 2048 ? (a[i++] = 192 | r >> 6,
                            a[i++] = 128 | 63 & r) : r < 55296 || r >= 57344 ? (a[i++] = 224 | r >> 12,
                                a[i++] = 128 | r >> 6 & 63,
                                a[i++] = 128 | 63 & r) : (r = 65536 + ((1023 & r) << 10 | 1023 & t.charCodeAt(++o)),
                                    a[i++] = 240 | r >> 18,
                                    a[i++] = 128 | r >> 12 & 63,
                                    a[i++] = 128 | r >> 6 & 63,
                                    a[i++] = 128 | 63 & r);
            else
                for (i = this.start; o < c && i < 64; ++o)
                    r = t.charCodeAt(o),
                        r < 128 ? A[i >> 2] |= r << SHIFT[3 & i++] : r < 2048 ? (A[i >> 2] |= (192 | r >> 6) << SHIFT[3 & i++],
                            A[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]) : r < 55296 || r >= 57344 ? (A[i >> 2] |= (224 | r >> 12) << SHIFT[3 & i++],
                                A[i >> 2] |= (128 | r >> 6 & 63) << SHIFT[3 & i++],
                                A[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]) : (r = 65536 + ((1023 & r) << 10 | 1023 & t.charCodeAt(++o)),
                                    A[i >> 2] |= (240 | r >> 18) << SHIFT[3 & i++],
                                    A[i >> 2] |= (128 | r >> 12 & 63) << SHIFT[3 & i++],
                                    A[i >> 2] |= (128 | r >> 6 & 63) << SHIFT[3 & i++],
                                    A[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]);
            this.lastByteIndex = i,
                this.bytes += i - this.start,
                i >= 64 ? (this.start = i - 64,
                    this.hash(),
                    this.hashed = !0) : this.start = i
        }
        return this.bytes > 4294967295 && (this.hBytes += this.bytes / 4294967296 << 0,
            this.bytes = this.bytes % 4294967296),
            this
    }
}
    ,
    Md5.prototype.finalize = function () {
        if (!this.finalized) {
            this.finalized = !0;
            var t = this.blocks
                , n = this.lastByteIndex;
            t[n >> 2] |= EXTRA[3 & n],
                n >= 56 && (this.hashed || this.hash(),
                    t[0] = t[16],
                    t[16] = t[1] = t[2] = t[3] = t[4] = t[5] = t[6] = t[7] = t[8] = t[9] = t[10] = t[11] = t[12] = t[13] = t[14] = t[15] = 0),
                t[14] = this.bytes << 3,
                t[15] = this.hBytes << 3 | this.bytes >>> 29,
                this.hash()
        }
    }
    ,
    Md5.prototype.hash = function () {
        var t, n, e, r, i, o, c = this.blocks;
        this.first ? (t = c[0] - 680876937,
            t = (t << 7 | t >>> 25) - 271733879 << 0,
            r = (-1732584194 ^ 2004318071 & t) + c[1] - 117830708,
            r = (r << 12 | r >>> 20) + t << 0,
            e = (-271733879 ^ r & (-271733879 ^ t)) + c[2] - 1126478375,
            e = (e << 17 | e >>> 15) + r << 0,
            n = (t ^ e & (r ^ t)) + c[3] - 1316259209,
            n = (n << 22 | n >>> 10) + e << 0) : (t = this.h0,
                n = this.h1,
                e = this.h2,
                r = this.h3,
                t += (r ^ n & (e ^ r)) + c[0] - 680876936,
                t = (t << 7 | t >>> 25) + n << 0,
                r += (e ^ t & (n ^ e)) + c[1] - 389564586,
                r = (r << 12 | r >>> 20) + t << 0,
                e += (n ^ r & (t ^ n)) + c[2] + 606105819,
                e = (e << 17 | e >>> 15) + r << 0,
                n += (t ^ e & (r ^ t)) + c[3] - 1044525330,
                n = (n << 22 | n >>> 10) + e << 0),
            t += (r ^ n & (e ^ r)) + c[4] - 176418897,
            t = (t << 7 | t >>> 25) + n << 0,
            r += (e ^ t & (n ^ e)) + c[5] + 1200080426,
            r = (r << 12 | r >>> 20) + t << 0,
            e += (n ^ r & (t ^ n)) + c[6] - 1473231341,
            e = (e << 17 | e >>> 15) + r << 0,
            n += (t ^ e & (r ^ t)) + c[7] - 45705983,
            n = (n << 22 | n >>> 10) + e << 0,
            t += (r ^ n & (e ^ r)) + c[8] + 1770035416,
            t = (t << 7 | t >>> 25) + n << 0,
            r += (e ^ t & (n ^ e)) + c[9] - 1958414417,
            r = (r << 12 | r >>> 20) + t << 0,
            e += (n ^ r & (t ^ n)) + c[10] - 42063,
            e = (e << 17 | e >>> 15) + r << 0,
            n += (t ^ e & (r ^ t)) + c[11] - 1990404162,
            n = (n << 22 | n >>> 10) + e << 0,
            t += (r ^ n & (e ^ r)) + c[12] + 1804603682,
            t = (t << 7 | t >>> 25) + n << 0,
            r += (e ^ t & (n ^ e)) + c[13] - 40341101,
            r = (r << 12 | r >>> 20) + t << 0,
            e += (n ^ r & (t ^ n)) + c[14] - 1502002290,
            e = (e << 17 | e >>> 15) + r << 0,
            n += (t ^ e & (r ^ t)) + c[15] + 1236535329,
            n = (n << 22 | n >>> 10) + e << 0,
            t += (e ^ r & (n ^ e)) + c[1] - 165796510,
            t = (t << 5 | t >>> 27) + n << 0,
            r += (n ^ e & (t ^ n)) + c[6] - 1069501632,
            r = (r << 9 | r >>> 23) + t << 0,
            e += (t ^ n & (r ^ t)) + c[11] + 643717713,
            e = (e << 14 | e >>> 18) + r << 0,
            n += (r ^ t & (e ^ r)) + c[0] - 373897302,
            n = (n << 20 | n >>> 12) + e << 0,
            t += (e ^ r & (n ^ e)) + c[5] - 701558691,
            t = (t << 5 | t >>> 27) + n << 0,
            r += (n ^ e & (t ^ n)) + c[10] + 38016083,
            r = (r << 9 | r >>> 23) + t << 0,
            e += (t ^ n & (r ^ t)) + c[15] - 660478335,
            e = (e << 14 | e >>> 18) + r << 0,
            n += (r ^ t & (e ^ r)) + c[4] - 405537848,
            n = (n << 20 | n >>> 12) + e << 0,
            t += (e ^ r & (n ^ e)) + c[9] + 568446438,
            t = (t << 5 | t >>> 27) + n << 0,
            r += (n ^ e & (t ^ n)) + c[14] - 1019803690,
            r = (r << 9 | r >>> 23) + t << 0,
            e += (t ^ n & (r ^ t)) + c[3] - 187363961,
            e = (e << 14 | e >>> 18) + r << 0,
            n += (r ^ t & (e ^ r)) + c[8] + 1163531501,
            n = (n << 20 | n >>> 12) + e << 0,
            t += (e ^ r & (n ^ e)) + c[13] - 1444681467,
            t = (t << 5 | t >>> 27) + n << 0,
            r += (n ^ e & (t ^ n)) + c[2] - 51403784,
            r = (r << 9 | r >>> 23) + t << 0,
            e += (t ^ n & (r ^ t)) + c[7] + 1735328473,
            e = (e << 14 | e >>> 18) + r << 0,
            n += (r ^ t & (e ^ r)) + c[12] - 1926607734,
            n = (n << 20 | n >>> 12) + e << 0,
            i = n ^ e,
            t += (i ^ r) + c[5] - 378558,
            t = (t << 4 | t >>> 28) + n << 0,
            r += (i ^ t) + c[8] - 2022574463,
            r = (r << 11 | r >>> 21) + t << 0,
            o = r ^ t,
            e += (o ^ n) + c[11] + 1839030562,
            e = (e << 16 | e >>> 16) + r << 0,
            n += (o ^ e) + c[14] - 35309556,
            n = (n << 23 | n >>> 9) + e << 0,
            i = n ^ e,
            t += (i ^ r) + c[1] - 1530992060,
            t = (t << 4 | t >>> 28) + n << 0,
            r += (i ^ t) + c[4] + 1272893353,
            r = (r << 11 | r >>> 21) + t << 0,
            o = r ^ t,
            e += (o ^ n) + c[7] - 155497632,
            e = (e << 16 | e >>> 16) + r << 0,
            n += (o ^ e) + c[10] - 1094730640,
            n = (n << 23 | n >>> 9) + e << 0,
            i = n ^ e,
            t += (i ^ r) + c[13] + 681279174,
            t = (t << 4 | t >>> 28) + n << 0,
            r += (i ^ t) + c[0] - 358537222,
            r = (r << 11 | r >>> 21) + t << 0,
            o = r ^ t,
            e += (o ^ n) + c[3] - 722521979,
            e = (e << 16 | e >>> 16) + r << 0,
            n += (o ^ e) + c[6] + 76029189,
            n = (n << 23 | n >>> 9) + e << 0,
            i = n ^ e,
            t += (i ^ r) + c[9] - 640364487,
            t = (t << 4 | t >>> 28) + n << 0,
            r += (i ^ t) + c[12] - 421815835,
            r = (r << 11 | r >>> 21) + t << 0,
            o = r ^ t,
            e += (o ^ n) + c[15] + 530742520,
            e = (e << 16 | e >>> 16) + r << 0,
            n += (o ^ e) + c[2] - 995338651,
            n = (n << 23 | n >>> 9) + e << 0,
            t += (e ^ (n | ~r)) + c[0] - 198630844,
            t = (t << 6 | t >>> 26) + n << 0,
            r += (n ^ (t | ~e)) + c[7] + 1126891415,
            r = (r << 10 | r >>> 22) + t << 0,
            e += (t ^ (r | ~n)) + c[14] - 1416354905,
            e = (e << 15 | e >>> 17) + r << 0,
            n += (r ^ (e | ~t)) + c[5] - 57434055,
            n = (n << 21 | n >>> 11) + e << 0,
            t += (e ^ (n | ~r)) + c[12] + 1700485571,
            t = (t << 6 | t >>> 26) + n << 0,
            r += (n ^ (t | ~e)) + c[3] - 1894986606,
            r = (r << 10 | r >>> 22) + t << 0,
            e += (t ^ (r | ~n)) + c[10] - 1051523,
            e = (e << 15 | e >>> 17) + r << 0,
            n += (r ^ (e | ~t)) + c[1] - 2054922799,
            n = (n << 21 | n >>> 11) + e << 0,
            t += (e ^ (n | ~r)) + c[8] + 1873313359,
            t = (t << 6 | t >>> 26) + n << 0,
            r += (n ^ (t | ~e)) + c[15] - 30611744,
            r = (r << 10 | r >>> 22) + t << 0,
            e += (t ^ (r | ~n)) + c[6] - 1560198380,
            e = (e << 15 | e >>> 17) + r << 0,
            n += (r ^ (e | ~t)) + c[13] + 1309151649,
            n = (n << 21 | n >>> 11) + e << 0,
            t += (e ^ (n | ~r)) + c[4] - 145523070,
            t = (t << 6 | t >>> 26) + n << 0,
            r += (n ^ (t | ~e)) + c[11] - 1120210379,
            r = (r << 10 | r >>> 22) + t << 0,
            e += (t ^ (r | ~n)) + c[2] + 718787259,
            e = (e << 15 | e >>> 17) + r << 0,
            n += (r ^ (e | ~t)) + c[9] - 343485551,
            n = (n << 21 | n >>> 11) + e << 0,
            this.first ? (this.h0 = t + 1732584193 << 0,
                this.h1 = n - 271733879 << 0,
                this.h2 = e - 1732584194 << 0,
                this.h3 = r + 271733878 << 0,
                this.first = !1) : (this.h0 = this.h0 + t << 0,
                    this.h1 = this.h1 + n << 0,
                    this.h2 = this.h2 + e << 0,
                    this.h3 = this.h3 + r << 0)
    }
    ,
    Md5.prototype.hex = function () {
        this.finalize();
        var t = this.h0
            , n = this.h1
            , e = this.h2
            , r = this.h3;
        return HEX_CHARS[t >> 4 & 15] + HEX_CHARS[15 & t] + HEX_CHARS[t >> 12 & 15] + HEX_CHARS[t >> 8 & 15] + HEX_CHARS[t >> 20 & 15] + HEX_CHARS[t >> 16 & 15] + HEX_CHARS[t >> 28 & 15] + HEX_CHARS[t >> 24 & 15] + HEX_CHARS[n >> 4 & 15] + HEX_CHARS[15 & n] + HEX_CHARS[n >> 12 & 15] + HEX_CHARS[n >> 8 & 15] + HEX_CHARS[n >> 20 & 15] + HEX_CHARS[n >> 16 & 15] + HEX_CHARS[n >> 28 & 15] + HEX_CHARS[n >> 24 & 15] + HEX_CHARS[e >> 4 & 15] + HEX_CHARS[15 & e] + HEX_CHARS[e >> 12 & 15] + HEX_CHARS[e >> 8 & 15] + HEX_CHARS[e >> 20 & 15] + HEX_CHARS[e >> 16 & 15] + HEX_CHARS[e >> 28 & 15] + HEX_CHARS[e >> 24 & 15] + HEX_CHARS[r >> 4 & 15] + HEX_CHARS[15 & r] + HEX_CHARS[r >> 12 & 15] + HEX_CHARS[r >> 8 & 15] + HEX_CHARS[r >> 20 & 15] + HEX_CHARS[r >> 16 & 15] + HEX_CHARS[r >> 28 & 15] + HEX_CHARS[r >> 24 & 15]
    }
    ,
    Md5.prototype.toString = Md5.prototype.hex,
    Md5.prototype.digest = function () {
        this.finalize();
        var t = this.h0
            , n = this.h1
            , e = this.h2
            , r = this.h3;
        return [255 & t, t >> 8 & 255, t >> 16 & 255, t >> 24 & 255, 255 & n, n >> 8 & 255, n >> 16 & 255, n >> 24 & 255, 255 & e, e >> 8 & 255, e >> 16 & 255, e >> 24 & 255, 255 & r, r >> 8 & 255, r >> 16 & 255, r >> 24 & 255]
    }
    ,
    Md5.prototype.array = Md5.prototype.digest,
    Md5.prototype.arrayBuffer = function () {
        this.finalize();
        var t = new ArrayBuffer(16)
            , n = new Uint32Array(t);
        return n[0] = this.h0,
            n[1] = this.h1,
            n[2] = this.h2,
            n[3] = this.h3,
            t
    }
    ,
    Md5.prototype.buffer = Md5.prototype.arrayBuffer,
    Md5.prototype.base64 = function () {
        for (var t, n, e, r = "", i = this.array(), o = 0; o < 15;)
            t = i[o++],
                n = i[o++],
                e = i[o++],
                r += BASE64_ENCODE_CHAR[t >>> 2] + BASE64_ENCODE_CHAR[63 & (t << 4 | n >>> 4)] + BASE64_ENCODE_CHAR[63 & (n << 2 | e >>> 6)] + BASE64_ENCODE_CHAR[63 & e];
        return t = i[o],
            r += BASE64_ENCODE_CHAR[t >>> 2] + BASE64_ENCODE_CHAR[t << 4 & 63] + "==",
            r
    }
function s(t, e) {
    return t.toString().toUpperCase() > e.toString().toUpperCase() ? 1 : t.toString().toUpperCase() == e.toString().toUpperCase() ? 0 : -1
}
function l(t) {
    for (var e = Object.keys(t).sort(s), n = "", a = 0; a < e.length; a++)
        if (void 0 !== t[e[a]])
            if (t[e[a]] && t[e[a]] instanceof Object || t[e[a]] instanceof Array) {
                var i = JSON.stringify(t[e[a]]);
                n += e[a] + i
            } else
                n += e[a] + t[e[a]];
    return n
}
function d(t) {
    for (var e in t)
        "" !== t[e] && void 0 !== t[e] || delete t[e];
    var n = "B3978D054A72A7002063637CCDF6B2E5" + l(t);
    return new Md5(!0).update(n)['hex']()
}
function gettime(){
    d1 = ((new Date).getTime())
    return d1
}

function main(dictData) {
    return d(dictData)
}

准备解决得到的加密数据。

这个纯靠经验,直接搜索,decrypt(),这个东西是js的一种解密的密钥

出现两个,我们现在先看第一个。

打断点调试

执行到这个位置的时候,我们输出一下a.tostring(),主要还是t的数据格式格式跟返回的data太像了

发现,这个结果是我们需要的数据

直接复制这段函数,使用crypto-js,来模拟一下检查是不是aes的(名字中存在)

将缺少的参数补上,这里还是控制台输出r["e"] r["j"]

返回参数解密

const Crypto = require('crypto-js')

var c = 'EB444973714E4A40876CE66BE45D5930'
var b = 'B5A8904209931867'
function decrypt(t) {
    var e = Crypto.enc.Utf8.parse(c)
      , n = Crypto.enc.Utf8.parse(b)
      , a = Crypto.AES.decrypt(t, e, {
        iv: n,
        mode: Crypto.mode.CBC,
        padding: Crypto.pad.Pkcs7
    });
    return a.toString(Crypto.enc.Utf8)
}

我们可以发现返回值符合预期结果,所以这个js文件处理加密的数据是正确的

最终的py代码

import requests
import execjs
ts = int(execjs.compile(open('D:\桌面\pythoncode\得到加密参数.js', 'r', encoding='utf-8').read()).call('gettime'))

json_data = {
        'pageNo': 1,
        'pageSize': 40,
        'total': 5770,
        'AREACODE': '',
        'M_PROJECT_TYPE': '',
        'KIND': 'GCJS',
        'GGTYPE': '1',
        'PROTYPE': '',
        'timeType': '6',
        'BeginTime': '2022-07-18 00:00:00',
        'EndTime': '2023-01-18 23:59:59',
        'createTime': [],
        'ts': ts,
}
sign  = str(execjs.compile(open('D:\桌面\pythoncode\得到加密参数.js', 'r', encoding='utf-8').read()).call('main',json_data))
print(sign)
headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json;charset=UTF-8',
        'Origin': 'https://ggzyfw.fujian.gov.cn',
        'Referer': 'https://ggzyfw.fujian.gov.cn/business/list/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
        'portal-sign': sign,
        'sec-ch-ua': '"Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
    }

response = requests.post('https://ggzyfw.fujian.gov.cn/FwPortalApi/Trade/TradeInfo', headers=headers, json=json_data).json()
data = response["Data"]
ctx = execjs.compile(open('D:\桌面\pythoncode\解密得到的数据.js', 'r', encoding='utf-8').read()).call('decrypt', data)
print(ctx)

效果展示

批量下载只需要修改参数即可,留个赞!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305102.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue 只渲染一次 v-once

v-once 指令&#xff1a;用于只渲染一次&#xff0c;首次渲染后&#xff0c;就不会再重新渲染了。 v-once 指令&#xff1a;也可以用在组件上&#xff0c;使组件只加载一次。 语法格式&#xff1a; // 在标签中使用 <div v-once> {{ 数据 }} </div>// 在组件中使…

【算法】递归、搜索与回溯算法

文章目录 一. 名词解释1. 递归1.1 什么是递归&#xff1f;1.2 为什么会用到递归&#xff1f;1.3 如何理解递归&#xff1f;1.4 如何写好一个递归&#xff1f; 2. 遍历和搜索3. 回溯和剪枝 二. 递归系列专题1. 汉诺塔问题2. 合并两个有序链表3. 反转链表4. 两两交换链表中的节点…

进程(IPC)_D3(2023-12-12)

XMind&#xff08;分图版&#xff09;

通过例子了解Go测试---来自Russ Cox的演讲

大家好. 几周前,我在澳大利亚 GopherCon 上发表了这个演讲[1], 但一些音/视频问题影响了效果,所以我在家重新录制了这个版本,enjoy&#xff01; 这次演讲的主题是编写好的测试&#xff0c;但首先让我们思考一下为什么需要编写测试。为什么程序员要编写测试呢&#xff1f;编程相…

java实现局域网内视频投屏播放(三)投屏原理

常见投屏方案 常见的投屏方案主要有以下几种&#xff1a; DLNA DLNA的全称是DIGITAL LIVING NETWORK ALLIANCE(数字生活网络联盟)。DLNA委员会已经于2017年1月5日正式解散&#xff0c;原因是旧的标准已经无法满足新设备的发展趋势&#xff0c;DLNA标准将来也不会再更新。但是…

主机访问Android模拟器网络服务方法

0x00 背景 因为公司的一个手机app的开发需求&#xff0c;要尝试链接手机开启的web服务。于是在Android Studio的Android模拟器上尝试连接&#xff0c;发现谷歌给模拟器做了网络限制&#xff0c;不能直接连接。当然这个限制似乎从很久以前就存在了。一直没有注意到。 0x01 And…

鸿蒙系统最近删除文件夹的路径

鸿蒙手机上删除文件&#xff0c;会将文件移动到类似回收站的路径下&#xff0c;如何找到这个路径&#xff1f; 先找用文件管理器找到一个文件 比如aaa.jpg &#xff0c;这时在调试的shell下面运行 find . -name aaaa.jpg 得到如下 这时再删除该文件 再次运行 find . -name a…

小白如何启用和使用ChatGPT4插件的详细步骤演示

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

野牛物联网-OneNET配置教程

1、 本文愿景 OneNET物联网开放平台是中国移动打造的面向产业互联和智慧生活应用的物联网PaaS平台&#xff0c;也是市面上主流物联网云平台之一&#xff0c;野牛物联网为了便利大家&#xff0c;在此编写了配置接入该平台完整的一个流程。 2、 OneNET平台注册和配置 2.1、 注…

STL 源码剖析

临时对象的产生与运用 #include <stdio.h> #include<stdlib.h> #include<iostream> #include<vector> #include<algorithm> using namespace std;template <typename T> class print { public:void operator()(const T& elem){cout &…

ubuntu 20.04.6 server 服务器 下载与安装(配置静态IP)

下载地址&#xff1a;https://releases.ubuntu.com/20.04.6/ubuntu-20.04.6-live-server-amd64.iso 第一步&#xff1a; 准备U盘&#xff0c;使用软碟通将下载好的镜像写入到U盘中 软碟通网址&#xff1a;https://www.cn.ultraiso.net/xiazai.html 点击&#xff1a;文件 ->…

交换机配置本地端口镜像示例(1:1)

镜像概念 定义 镜像是指将指定源的报文复制一份到目的端口。指定源被称为镜像源&#xff0c;目的端口被称为观察端口&#xff0c;复制的报文被称为镜像报文。 镜像可以在不影响设备对原始报文正常处理的情况下&#xff0c;将其复制一份&#xff0c;并通过观察端口发送给监控…

【LeetCode-树】-- 109.有序链表转换二叉搜索树

109.有序链表转换二叉搜索树 方法&#xff1a;找到链表的中点&#xff0c;将其作为根节点 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNo…

SpringBoot集成系列--Kakfa

文章目录 一、代码1、添加依赖2、配置kafka3、创建生产者4、创建消费者5、测试 二、遇到问题1、could not be established. Broker may not be available2、Error while fetching metadata with correlation id xxx 一、代码 1、添加依赖 在pom.xml文件中添加Kafka的依赖 &l…

NFC物联网解决方案应用实例:基于NFC的通用物流链防伪溯源

NFC物联网系统解决方案已在某局进行推广应用&#xff0c;给出了某省内出口蔬菜水果检验检疫监管的物联网解决方案。 依据相关法规&#xff0c;出口蔬菜必须在质检总局注册种植基地进行种植&#xff0c;出口前按批次向产地检验检疫部门进行申报&#xff0c;按时在集中监管区统一…

Leetcode—2961.双模幂运算【中等】

2023每日刷题&#xff08;五十六&#xff09; Leetcode—2961.双模幂运算 实现代码 class Solution { public:int func(int a, int b) {int ans 1;for(int i 0; i < b; i) {ans * a;ans % 10;}return ans;}int func2(int a, int b, int m) {int ans 1;for(int i 0; i …

通过pull request执行结果运行自动化测试脚本

前提条件 已安装 Jenkins&#xff0c;并且安装插件Generic Webhook Trigger Plugin 配置 Jenkins创建一个 pipeline项目如图所示在Jenkins任务的build triggers中勾选Generic Webhook Trigger, 并且填写token在代码仓库管理平台&#xff08;截图的是bitbucket)&#xff0c;配…

Python之Requests库使用总结

概述 Requests是python中一个很Pythonic的HTTP库&#xff0c;用于构建HTTP请求与解析响应 Requests开发哲学 Beautiful is better than ugly.(美丽优于丑陋) Explicit is better than implicit.(直白优于含蓄) Simple is better than complex.(简单优于复杂) Complex is bett…

充电宝详解及推荐

一、充电宝选购攻略 二、充电宝的分类 &#xff08;1&#xff09;常规充电宝&#xff08;慢充&#xff09; 就是输出电压5V &#xff0c;输出电流1A或者2A的这种。 按照功率计算公示&#xff1a;PU*I&#xff0c; 这种充电宝给手机充电最快也就是&#xff1a;5.1V2.1A10.71W…

SpringBoot+Netty+Websocket实现消息推送

这样一个需求&#xff1a;把设备异常的状态每10秒推送到页面并且以弹窗弹出来&#xff0c;这个时候用Websocket最为合适&#xff0c;今天主要是后端代码展示。 添加依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifact…