声明:
该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关
一、找出需要加密的参数
- js运行 atob(‘aHR0cHM6Ly93d3cua2Fuemh1bi5jb20vc2VhcmNoLz9xdWVyeT1weXRob24mdHlwZT0w’) 拿到网址,F12打开调试工具,点击搜索,找到 api_to/search/comprehensive.json 请求
- 分析请求头、参数、响应结果会发现只有参数中的 b、kiv加密,还有响应结果加密,请求头中 cookie 也有一些看起来也像加密,暂时不管cookie中的,先去扣响应结果的加密,再通过代码注释 cookie 参数判断是否cookie需要加密
- 鼠标右击请求找到Copy>Copy as cUrl(cmd),打开网站:https://spidertools.cn/#/curl2Request,把拷贝好的curl转成python代码,新建 kanzhun.py 文件,把代码拷贝进去
- 新建 kanzhun.js 文件,用于放扣下的代码
二、定位响应结果解密位置
- 因为响应结果完全是加密的,这里采用XHR拦截请求的方法定位解密位置,想尝试关键字的可以采用:JSON.parse、decrypt符合AES加密的关键字进行搜索
- 切换到sources,添加XHR拦截api_to/search/comprehensive.json
- 点击搜索发送请求,一直点击跳过下一个函数,看到响应拦截器,分析代码会发现 t = (0,M.gy)(e.data, {iv: “string” == typeof n ? JSON.parse(n).kiv : n.kiv} 响应结果经过了这行代码的转换,又经过 JSON.parse 的转换,在 JSON.parse 打上断点,并把代码复制到 kanzhun.js 文件
- 结束本次调试,点击搜索发送请求,点击跳过断点调试,会定位到 JSON.parse 上的断点,分析 t = (0, )(e.data, {iv: “string” == typeof n ? JSON.parse(n).kiv : n.kiv} 会发现 M.gy、e.data、iv是需要注意的,鼠标分别悬浮上去会发现,M.gy 方法、e.data是加密参数、iv 是请求参数的kiv,分别把e.data、iv在控制台输出,把 e.data、iv 输出的值分别复制到 kanzhun.js 文件
- 鼠标悬浮到 M.gy 点击蓝色位置,找到该方法,会看到 m 方法,分析 m 方法会发现 c 方法,而e、t.iv参数是 M.gy 方法传过来的 ,在 m 方法内部打断点
- 结束本次调试,点击搜索发送请求,点击跳过断点调试,直到看到 m 方法,鼠标悬浮到 c 方法,点击蓝色部分找到该方法的位置,会发现 c 方法,分析内部代码得知是 AES 解密。而 iv 、e是经过 M.gy 传过来的,key、mode、padding 取得是 变量 n 中的,变量 n 是由 u() 方法实现,把代码复制到 kanzhun.js 文件,把方法名改为 decrypt,并导入 crypto-js 库,把代码中的 AES 相关的替换成库里面的,把 M.gy 替换成 ddecrypt
- 鼠标悬浮到 u 方法,点击蓝色部分找到该方法的位置,不想分析里面的代码可以完全复制到 kanzhun.js 文件,并把里面的 o.enc、o.mode、o.pad 替换成crypto-js 库的,有代码洁癖的可以只把 s = function() 拷贝出来命名成 u 方法,再把里面的 o.enc、o.mode、o.pad 替换成crypto-js 库的
- 验证结果,运行代码打印出 解密后的值,把 t 在控制台输出,会发现里面的值是一样的
三、python 解密验证结果,并分析 cookie 中是否又加密参数
- 修改 kanzhun.py 文件,把参数中的b、kiv换成对应请求中的,运行文件会发现结果已经解密,我这里遇到了编码问题,加了 subprocess.Popen = partial(subprocess.Popen, encoding=“utf-8”) 以及 open(‘kanzhun.js’,‘r’,encoding=‘UTF-8’) 解决,没遇到的可以忽略
- 分析 cookie 中是否又加密参数,把cookie中的字段全部注释,会发现加密数据依然可以解密成,说明 cookie 中的字段无加密参数影响请求
四、定位b、kiv加密位置
- 删除所有断点,点击搜索发送请求,关键字搜索 kiv,会发现有 kiv 赋值的地方,右击请求,点击在 sources 中打开,在打开的文件Ctrl+F搜索kiv,找到对应的位置并断点
- 点击搜索发送请求,点击跳过断点调试,直到看到 api_to/search/comprehensive.json 停下,分析代码,由此代码可看出 b、kiv 都在这个位置,分别对应 t、a ,而 a = (0,M.A)()、t = (0,M.mA)(n, {iv: a}).replace(///g, "").replace(///g, “_”).replace(/+/g, “-”).replace(/=/g, “~”),分析两段代码,会发现 a 是有 M.mA 函数生成,t 是由 M.mA、n、a生成,把 n 在控制台输出,会发现是参数的 明文信息,根据分析把代码复制到 kanzhun.js
- 分析 M._A 方法,鼠标悬浮 M._A,点击蓝色部分找到该方法,会发先 p 方法,把该方法复制到 kanzhun.js,并把 M._A 替换成 p
- 分析 M.mA 方法,鼠标悬浮 M.mA,点击蓝色部分找到该方法,会发现 h 方法,在该方法内部断点
- 结束此次调试,点击搜索发送请求,一直点击跳过断点调试,直到看到刚才的 h 方法,分析该方法内部e、t是由M.mA传参过来的,只有一个 l 方法需要分析,鼠标悬浮 l 方法,点击蓝色部分找到该方法,会看到一个 l 方法,方法内部是 AES 加密,而在代码下方是之前的请求解密方法,加密里面的 n 也是之前的 u 方法生成,把代码复制到 kanzhun.js,把方法名改为 encrypt,并导入 crypto-js 库,把代码中的 AES 相关的替换成库里面的,把 M.mA 替换成 encrypt,点击运行 kanzhun.js,会发现 b、kiv5可以生成成功
五、python 加密结果
- 修改 kanzhun.py 文件,运行后会发现接口请求成功,且解密后的数据正常