翼度科技»论坛 编程开发 python 查看内容

一个案例入门补环境

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
此分享只用于学习用途,不作商业用途,若有冒犯,请联系处理
反爬前置信息

站点:aHR0cDovLzEyMC4yMTEuMTExLjIwNjo4MDkwL3hqendkdC94anp3ZHQvcGFnZXMvaW5mby9wb2xpY3k=
接口:/xjzwdt/rest/xmzInfoDeliveryRest/getInfoDeliveryList
破解结果预览


何谓补环境

补环境其实是补浏览器有而Node没有的环境,即补BOM和DOM的对象,一切环境补的结果都是向浏览器实际结果靠齐,入门补环境只需要记住缺啥补啥这个技巧,当运行提示缺少某个环境,则直接在浏览器运行该环境是啥结果然后补上该结果。

反爬机制

站点有两个反爬项,请求体加密和响应结果解密


逆向研究

补环境处理的是关键代码,所以我们还是要定位到关键代码位置拿到关键代码
找到接口的调用堆栈,点击下面图片标识的堆栈进入代码

在1处打上断点重新发起请求,在2处可以看到这里已经实现请求体加密了,那我们得往前走,也就是点击3处标识堆栈

然后在1处打上断点重新发起请求,点击2处进入函数引用代码位置

这里就能看到关键代码了,它重新封装了ajax,请求体加密和响应结果解密都是在这里进行的

但是我们要补的不是这个位置,因为我们又不是直接构建请求的,我们要破解的只是加解密,所以要补的是window.sm2Util.encrypt和window.sm2Util.aesDecrypt,而它们都在sm2Util.js文件中,接下来我们直接补sm2Util.js代码就行。
注意直接拿全部代码,不要格式化

补环境

先直接运行代码,发现报下面所示错误,这是因为window不是Node的环境,这里一般是使用global替代

补好window环境后再次运行报下面所示错误,继续补navigator

补好navigator环境后再次运行报下面所示错误,这是因为在浏览器环境下exports是undefined,但是在Node环境下exports是Object对象,所以这里我们要处理

补好exports后就不会报错了

打印看看发现能拿到想要的方法了,这里就初步补好环境了,要确定是否真正补全了还得运行一下代码,我们就拿调试时拿到的请求体加密原文进行调试

ok,这里测试的请求体加密成功了,说明encrypt补好了,接下来测试下响应文本解密,直接拿接口返回的响应文本测试即可

ok,这里测试的响应文本解密也成功了,也就说明咱们补好了。

补环境补充-挂代理

上面讲解遇到缺失的环境都是对象本身,所以我们能直接知道缺了啥,然后对此做出处理。
但是如果缺失的是对象某个参数呢,比如下图所示我们是没法知道是哪个对象哪个参数出的问题的。大家可能会说不是有代码位置提示吗,但是这是在明文代码下能清楚提示,遇到混淆代码就不行了,所以我们需要挂代理

所谓挂代理其实就是使用Proxy对象,它是一种对象代理机制,可以在对象和函数之间添加一个中间层,从而实现对对象和函数的拦截和控制。
使用下面这段代码,添加想要监控的对象
  1. function getEnv(proxy_array) {
  2.     for (var i = 0; i < proxy_array.length; i++) {
  3.         handler = `{\n
  4.             get: function(target, property, receiver) {\n
  5.                    console.log('方法:get','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);
  6.                    return target[property];
  7.             },
  8.             set: function(target, property, value, receiver){\n
  9.                     console.log('方法:set','    对象:${proxy_array[i]}','    属性:',property,'    属性类型:',typeof property,'    属性值类型:',typeof target[property]);
  10.                     return Reflect.set(...arguments);
  11.             }
  12.         }`;
  13.         eval(`
  14.             try {
  15.                 ${proxy_array[i]};
  16.                 ${proxy_array[i]} = new Proxy(${proxy_array[i]}, ${handler});
  17.             } catch (e) {
  18.                 ${proxy_array[i]} = {};
  19.                 ${proxy_array[i]} = new Proxy(${proxy_array[i]}, ${handler});
  20.             }
  21.         `)
  22.     }
  23. }
复制代码
这样它会打印出调用的对象、属性等信息,这不就清晰多了。

我们在本案例测试,可以看到代码使用的全部环境了,然后看到哪些环境或者属性是undefined就把它补好。

代码展示
  1. import json
  2. import subprocess
  3. from functools import partial
  4. import requests
  5. subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")  # 修改全局编码
  6. import execjs  # 必须在修改编码后引入
  7. with open('sm2Utils.js', 'r', encoding='utf8') as fr:
  8.     str_data = fr.read()
  9. js_code = execjs.compile(str_data)
  10. headers = {
  11.     "Accept": "application/json, text/javascript, */*; q=0.01",
  12.     "Accept-Language": "zh-CN,zh;q=0.9",
  13.     "Content-Type": "application/json;charset=UTF-8",
  14.     "Origin": "Origin",
  15.     "Referer": "Referer",
  16.     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
  17.     "X-Requested-With": "XMLHttpRequest",
  18.     "encrypt": "1"
  19. }
  20. url = "url "
  21. params = {
  22.     "foreSessionClusterIntercept": "true"
  23. }
  24. post_data = {"token": "Epoint_WebSerivce_**##0601",
  25.              "params": {"categuids": "4bcbbec7-2428-403a-8eed-b0db5c0e01a5", "titlename": "", "currpage": 0,
  26.                         "pagesize": 10}}
  27. print('encrypt data: ', json.dumps(post_data, separators=(',', ':')))
  28. data = js_code.call('encrypt', json.dumps(post_data, separators=(',', ':')))
  29. print('encrypt result: ', data)
  30. response = requests.post(url, headers=headers, params=params, data=data, verify=False)
  31. print('request result: ', response.text)
  32. decrypt_result = js_code.call('decrypt', response.text)
  33. print('decrypt result: ', decrypt_result)
复制代码
来源:https://www.cnblogs.com/ranbox/p/18469586
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具