python爬虫js逆向某准网-工资数据(b、kiv参数+返回值解密)

今天我们爬取某准网-’操作员‘的工资:
在这里插入图片描述


1. 抓包:

发现参数b、kiv以及返回值均为加密:
在这里插入图片描述
在这里插入图片描述


查看调用栈:

在这里插入图片描述
发现promise+其他的请求也是类似的加密格式
判断是:拦截器 ——>搜interceptors
在这里插入图片描述
网页源码:
在这里插入图片描述
找到请求与返回的拦截器(共四个),打断点:
在这里插入图片描述
切换城市:发现在请求拦截器,拦截下来了


注意:
数据在这里之前就已经被加密了,
所有请求时的参数加密,和拦截器是没有关系的!
在这里插入图片描述
所以应该继续往调用前找
由于该promise是给异步的框架,所以这些调用栈不一定是该固定的操作顺序:
我们可以重新在嫌疑函数处打断点!
当找到 a 调用栈时:发现有重大嫌疑的代码:
在这里插入图片描述
打断点,重新切换城市:
在这里插入图片描述
发现还是被加密的,继续溯源 r
发现r是上面定义的:
在这里插入图片描述
在i.request处的 r 是有params的,而r又是上面定义的
说明params的生成应该介于两者之间:
所以断点应该往前移:
在这里插入图片描述
这里是没有params的。
我们一直往下走一步,直到走到这里,发现params生成了:
在这里插入图片描述
即找到了入口函数。


2.分析:

在这里插入图片描述

逻辑:
a ? { b: t, kiv: a} : r.data : “post” == r.method.toLowerCase() && “json” == r.requestType.toLowerCase() ? (r.headers[“Content-Type”] = “application/json;charset=utf-8”,
a存在的话,{ b: t, kiv: a}

在这里插入图片描述
a是存在的!那么就溯源:a 和 t 哪来的:
先看到了t:

t = (0, M.mA)(n, { iv: a}
                         ).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "~")));
                         
逻辑:(函数)(实参)
而函数(0, M.mA)里面是逗号表达式:0不影响该函数
所以:
t = M.mA(n, { iv: a}    

n是:明文
经过 M.mA 的计算后,变成了 :t
此时,还差 a 的来源:

 "string" == typeof r.data && r.data.indexOf("kiv") > -1 ? (t = (n = "string" == typeof r.data ? JSON.parse(r.data) : r.data).b,
                a = n.kiv) : (a = (0,
                M._A)(),

分析代码,判断(a = (0,M._A)() ——>a = M._A()
进入 M._A():
在这里插入图片描述
进来发现:random
随机值,那么可以直接拿生成的数值即可
在这里插入图片描述


a = M._A()
等价于:a = '6ncum6fEaTfvL5HS'
那么t:
t = M.mA(n, { iv: '6ncum6fEaTfvL5HS'}   

就差M.mA函数,打断点进入:
在这里插入图片描述
分析应该是走:l(e, t.iv)) : “”
传入e(明文)和t.iv(“6ncum6fEaTfvL5HS”)
进入l:
在这里插入图片描述
发现了加密逻辑:

l = function(e, t) {
            void 0 === e && (e = ""),
            void 0 === t && (t = "");
            var n = u()
              , r = o.AES.encrypt(e.toString(), n.key, {    // key是?  
                iv: o.enc.Utf8.parse(t),
                mode: n.mode,
                padding: n.pad
            });
            return r = r.toString()
        },

key是什么?进入n = u()发现:拿到mode和pad以及key
在这里插入图片描述


3.代码:

AES解密:

这次我们通过js第三方库crypto-js来完成aes解密逻辑:

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

e = '{"query":"操作员","cityCode":34,"industryCodes":"","pageNum":1,"limit":15}';
t = 'i4PKiRyiKb65iVhe'
key = 'G$$QawckGfaLB97r'

r = CryptoJS.AES.encrypt(e.toString(), CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(t),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});
console.log(r.toString())

返回值解密代码整合:

分析网站逻辑:
请求逻辑:
1. 生成iv.(随机)
2. 加密
3. 把密文和iv传递给服务器

响应逻辑:
1. 拿到请求时发的iv
2. 进行解密(用的是请求时的iv)
3. 得到明文

综上, 加密和解密用的iv是同一个.

import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import requests

key = 'G$$QawckGfaLB97r'
iv = "3dgM3hFt2DG0Be2w"

ming = '{"query":"操作员","cityCode":1,"industryCodes":"","pageNum":1,"limit":15}'

#参数加密:
aes = AES.new(key=key.encode("utf-8"), mode=AES.MODE_CBC, iv=iv.encode("utf-8"))
mi = aes.encrypt(pad(ming.encode("utf-8"), 16))

mi = base64.b64encode(mi).decode().replace("/", "_").replace("+", "-").replace("=", "~")

params = {
    'b': mi,
    "kiv": iv
}

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 = requests.get(url="https://www.kanzhun.com/api_to/search/salary.json", params=params, headers=headers)

mi = resp.text

# 数据解密:
aes_dec = AES.new(key=key.encode("utf-8"), mode=AES.MODE_CBC, iv=iv.encode("utf-8"))
ming = aes_dec.decrypt(base64.b64decode(mi))

ming = unpad(ming, 16)
ming = ming.decode("utf-8")

print(json.loads(ming))
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

akkkk0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值