目标网址
‘aHR0cHM6Ly93d3cueW91emhpY2FpLmNvbS9udjEvMDEwMTAxMDAwMTAxMDEwMS5odG1s’

分析

打开控制台抓包,第一次状态码203,会生成cookie,第二次访问会带上该cookie

知道了是cookie加密,使用hook定位到加密位置

Object.defineProperty(document, "cookie", {get: function(val){return val;},set: function(val){debugger;return val;}
})

定位到位置,点击上层堆栈

参数b就是我们想要的值

黑盒调用

把整个js代码复制出来,在代理器下运行,看它需要哪些环境
不了解代理器的可以看这几篇文章
https://zhuanlan.zhihu.com/p/30299114
https://www.cnblogs.com/tugenhua0707/p/10291909.html#_labe0
https://zhuanlan.zhihu.com/p/60791215
proxy代理器我放到最后面
然后加句打印b的值

因为js代码是动态加载的,需要把每一次返回的js代码进行替换执行拿到b的值
把补的环境单独拿出来
直接上代码

import requests
import execjsclass spider:def __init__(self):self.session = requests.Session()self.headers = {'Connection': 'keep-alive','Pragma': 'no-cache','Cache-Control': 'no-cache','sec-ch-ua': '"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','Sec-Fetch-Site': 'none','Sec-Fetch-Mode': 'navigate','Sec-Fetch-User': '?1','Sec-Fetch-Dest': 'document','Accept-Language': 'zh-CN,zh;q=0.9',}# js环境self.js_env = """var CryptoJS = require("crypto-js");let navigator = {userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",platform: "Win32",appCodeName: "Mozilla",language: "zh-CN",webdriver: false,cookieEnabled: true,appVersion: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",};Object.defineProperties(navigator,{[Symbol.toStringTag]: {value:"Navigator"}})location = {pathname: 'www.youzhicai.com',href: 'https://www.youzhicai.com/nv1/0101010001010101.html',host: 'www.youzhicai.com',reload: function (){},}document = {}window = {navigator: navigator,location: location,document: document,};"""# 调用cookieself.get_cookie = """function getcookie(){return b}"""def run(self):response = self.session.get('https://www.youzhicai.com/nv1/0101010001010101.html', headers=self.headers)js_code = response.text.replace("<script>", "").replace("</script>", "")# 拼接js代码执行all_code = self.js_env + js_code + self.get_cookiecontext = execjs.compile(all_code)# 执行函数cookie = context.call("getcookie")print("第一次的cookie:", cookie)# 添加cookierequests.utils.add_dict_to_cookiejar(self.session.cookies, {"spvrscode": cookie})response = self.session.get('https://www.youzhicai.com/nv1/0101010001010101.html', headers=self.headers)print(response.text)if __name__ == '__main__':spider = spider()spider.run()

成功拿到页面

proxy代理器

let rawindexof = String.prototype.indexOf
String.prototype.indexOf = function (str) {var res = rawindexof.call(this, str)console.log(`[String] "${this}" is indexof "${str}", res is ${res}`)return res
}let mynavigator = {userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",platform: "Win32",appCodeName: "Mozilla",language: "zh-CN",webdriver: false,cookieEnabled: true,appVersion: "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
};
Object.defineProperties(mynavigator, {[Symbol.toStringTag]: {value: "Navigator"}
})let myhistory = {};
let myscreen = {height: 768,width: 1366,colorDepth: 24,};
let mylocation = {pathname: 'www.youzhicai.com',href: 'https://www.youzhicai.com/nv1/0101010001010101.html',host: 'www.youzhicai.com',
};
let Document = function Document(){}
let HTMLDocument = function HTMLDocument(){}
Object.setPrototypeOf(HTMLDocument, Document.prototype)
Object.defineProperties(HTMLDocument.prototype, {[Symbol.toStringTag]: {value: "HTMLDocument"}
})
let mydocument = {createElement: function (){return {};},getElementsByTagName: function (str){console.log(str)if(str == "meta"){let metaRes = []metaRes["meta-pro"] = {"content": {"length": 6}}return metaRes}},};
// 为document指向原型
Object.setPrototypeOf(mydocument, HTMLDocument.prototype)
let Image = function (){}let mywindow = {XMLHttpRequest: function () {},sessionStorage: {},localStorage: {},navigator: mynavigator,scrollTo: function (){},addEventListener: function () {},attachEvent: function () {},screen: myscreen,location: mylocation,chrome: {},document: mydocument,history: myhistory
};
Object.defineProperties(global, {[Symbol.toStringTag]: {value: "Window"}
})
let rawstringify = JSON.stringify;
JSON.stringify = function (Object) {if ((Object?.value ?? Object) === global) {return "global"} else {return rawstringify(Object)}
}function getMethodHandler(WatchName) {let methodhandler = {apply(target, thisArg, argArray) {let result = Reflect.apply(target, thisArg, argArray)console.log(`[${WatchName}] apply function name is [${target.name}], argArray is [${argArray}], result is [${result}].`)return result},construct(target, argArray, newTarget) {var result = Reflect.construct(target, argArray, newTarget)console.log(`[${WatchName}] construct function name is [${target.name}], argArray is [${argArray}], result is [${result}].`)return result;}}return methodhandler
}function getObjhandler(WatchName) {let handler = {get(target, propKey, receiver) {let result = Reflect.get(target, propKey, receiver)if (result instanceof Object) {if (typeof result === "function") {console.log(`[${WatchName}] getting propKey is [${propKey}] , it is function`)//return new Proxy(result,getMethodHandler(WatchName))} else {console.log(`[${WatchName}] getting propKey is [${propKey}], result is [${result}]`);}return new Proxy(result, getObjhandler(`${WatchName}.${propKey}`))}console.log(`[${WatchName}] getting propKey is [${propKey?.description ?? propKey}], result is [${result}]`);return result;},set(target, propKey, value, receiver) {if (value instanceof Object) {console.log(`[${WatchName}] setting propKey is [${propKey}], value is [${value}]`);} else {console.log(`[${WatchName}] setting propKey is [${propKey}], value is [${value}]`);}return Reflect.set(target, propKey, value, receiver);},has(target, propKey) {var result = Reflect.has(target, propKey);console.log(`[${WatchName}] has propKey [${propKey}], result is [${result}]`)return result;},deleteProperty(target, propKey) {var result = Reflect.deleteProperty(target, propKey);console.log(`[${WatchName}] delete propKey [${propKey}], result is [${result}]`)return result;},getOwnPropertyDescriptor(target, propKey) {var result = Reflect.getOwnPropertyDescriptor(target, propKey);console.log(`[${WatchName}] getOwnPropertyDescriptor  propKey [${propKey}] result is [${result}]`)return result;},defineProperty(target, propKey, attributes) {var result = Reflect.defineProperty(target, propKey, attributes);console.log(`[${WatchName}] defineProperty propKey [${propKey}] attributes is [${attributes}], result is [${result}]`)return result},getPrototypeOf(target) {var result = Reflect.getPrototypeOf(target)console.log(`[${WatchName}] getPrototypeOf result is [${result}]`)return result;},setPrototypeOf(target, proto) {console.log(`[${WatchName}] setPrototypeOf proto is [${proto}]`)return Reflect.setPrototypeOf(target, proto);},preventExtensions(target) {console.log(`[${WatchName}] preventExtensions`)return Reflect.preventExtensions(target);},isExtensible(target) {var result = Reflect.isExtensible(target)console.log(`[${WatchName}] isExtensible, result is [${result}]`)return result;},ownKeys(target) {var result = Reflect.ownKeys(target)console.log(`[${WatchName}] invoke ownkeys, result is [${result}]`)return result},apply(target, thisArg, argArray) {let result = Reflect.apply(target, thisArg, argArray)console.log(`[${WatchName}] apply function name is [${target.name}], argArray is [${argArray}], result is [${result}].`)return result},construct(target, argArray, newTarget) {var result = Reflect.construct(target, argArray, newTarget)console.log(`[${WatchName}] construct function name is [${target.name}], argArray is [${argArray}], result is [${result}].`)return result;}}return handler;
}const navigator = new Proxy(Object.create(mynavigator), getObjhandler("navigator"));
const history = new Proxy(Object.create(myhistory), getObjhandler("history"))
const screen = new Proxy(Object.create(myscreen), getObjhandler("screen"));
const location = new Proxy(mylocation, getObjhandler("location"));
const document = new Proxy(mydocument, getObjhandler("document"));
const window = new Proxy(Object.assign(global, mywindow), getObjhandler("window"));//checkproxy()
module.exports = {window,navigator,screen,location,Image,document,history,Document
}

在运行的ja文件前面添加导入

let {window,navigator,location,screen,Image,document,history,Document
} = require('Proxy.js');

算法还原

分析把这段代码拿出来,一点点还原

可以在上面找到它的密钥和需要加密的字符串

结果是一样的

可以看到这是一个DES加密算法

流程是第一次请求拿到js代码,从中拿到密钥和需要加密的字符串,再有python加密进行请求

代码

from pyDes import des, ECB, PAD_PKCS5
import binascii
import requests
import reclass spider:def __init__(self):self.session = requests.Session()self.headers = {'Connection': 'keep-alive','Pragma': 'no-cache','Cache-Control': 'no-cache','sec-ch-ua': '"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','Sec-Fetch-Site': 'none','Sec-Fetch-Mode': 'navigate','Sec-Fetch-User': '?1','Sec-Fetch-Dest': 'document','Accept-Language': 'zh-CN,zh;q=0.9',}def des_encrypt(self, KEY, s):"""DES 加密:param s: 原始字符串:return: 加密后字符串,16进制"""secret_key = KEY  # 密码iv = secret_key  # 偏移# secret_key:加密密钥,CBC:加密模式,iv:偏移, padmode:填充des_obj = des(secret_key, ECB, iv, pad=None, padmode=PAD_PKCS5)# 返回为字节secret_bytes = des_obj.encrypt(s, padmode=PAD_PKCS5)# 返回为16进制return binascii.b2a_hex(secret_bytes)def run(self):response = self.session.get('https://www.youzhicai.com/nv1/0101010001010101.html', headers=self.headers)a = re.findall(";var a= '(.*?)';", response.text)[0]b = re.findall(";var b = '(.*?)';", response.text)[0]print(a)print(b)cookie = self.des_encrypt(a, b).decode()print("第一次的cookie:", cookie)# 添加cookierequests.utils.add_dict_to_cookiejar(self.session.cookies, {"spvrscode": cookie})response = self.session.get('https://www.youzhicai.com/nv1/0101010001010101.html', headers=self.headers)print(response.text)if __name__ == '__main__':spider = spider()spider.run()

请求成功

某网站cookie加密黑盒调用与算法还原相关推荐

  1. 2019年末逆向复习系列之Boss直聘Cookie加密字段__zp_stoken__逆向分析

    郑重声明:本项目的所有代码和相关文章, 仅用于经验技术交流分享,禁止将相关技术应用到不正当途径,因为滥用技术产生的风险与本人无关. 这篇文章是公众号<云爬虫技术研究笔记>的<2019 ...

  2. 国家税务总局全国增值税发票查验平台网站js逆向分析及全逆向算法还原

    本文教程针对的是2021年7月2日时国税查验平台的js分析,其中版本号为V2.0.06_009.主要分析内容为key9和flwq39以及fplx这3个参数的算法,其中key9分为获取验证码阶段和查验阶 ...

  3. 保存登录信息的Cookie加密技术

    https://www.cnblogs.com/VectorZhang/p/5425283.html 保存登录信息的Cookie加密技术 所有需要账户登录的website 基本都会想到这样一个问题, ...

  4. 【转】Postman系列五:Postman中电商网站cookie、token检验与参数传递实战

    一:Postman中电商网站cookie实战 Postman接口请求使用cookie两种方式: 1.直接在header(头域)中添加cookie,适用于已知请求cookie头域的情况 2.使用Post ...

  5. linux加密框架 crypto 通用算法注册接口__crypto_register_alg注册流程

    函数介绍 __crypto_register_alg函数实现向加密框架注册算法(包括静态算法和动态算法)的功能,输入参数为算法说明alg,注册成功时返回算法注册用的算法幼虫larval,注册失败时返回 ...

  6. ecb gcm java 加密,AES GCM和ECB加密软件,附算法源码和工程文件

    [实例简介] AesTestTool为加密软件,支持GCM 和 ECB两种模式 128bit秘钥 GCM算法是一个C++工程,"C++gcm算法工程"目录里面有源码 加密软件是用C ...

  7. Linux加密和安全篇(一)gpg、对称和非对称加密、哈希算法

    对于linux运维工作者而言,加密技术已经很早就用于数据的存储和数据之间的交换.我们可以会为了防止你的网站.服务器或者系统,我们会使用一些手段来防止一些恶意的攻击或者访问.一下就对linux的安全和加 ...

  8. 应用JAVA进行密码加密的一种算法

    应用JAVA进行密码加密的一种算法 发表于<河北科技大学学报>(2007-7 Vol.28,P122) 摘要:在这篇文章中将要介绍一种简单的密码不可逆加密算法的实现,代码采用的是java语 ...

  9. 【LKH算法体验】Python调用LKH算法求TSP问题

    [LKH算法体验]Python调用LKH算法求TSP问题 一.LKH算法简介 Keld Helsgaun 是丹麦 罗斯基勒大学计算机科学专业的名誉副教授. 他于 1973 年在 哥本哈根大学获得DIK ...

  10. 软件测试测cookie,什么是Cookie测试和网站Cookie测试用例?

    在今天的文章中,我们正在谈论网站Cookie测试.在现代Web测试中使用Cookie是最常见的事情.我们将首先集中在什么是Cookie,以及他们如何在Web应用程序测试中工作.此外,我们将看到如何测试 ...

最新文章

  1. 初学者css常见问题_5分钟内学习CSS Grid-初学者教程
  2. pom配置之:distributionManagementsnapshot快照库和release发布库
  3. ngx_http_redis_module配置使用
  4. 平安京服务器维护不能打字,《决战!平安京》:玩的真的累,我真的是服了这破游戏的举报系统...
  5. java linkedlist 方法_Java LinkedList getFirst()方法与示例
  6. 【多线程编程学习】java多线程基于数据分割的大文件下载器
  7. linux上听FM程序,安装和使用Odio在Linux上收听FM收音机的方法
  8. ie6不支持png图片的解决办法
  9. 进程间能否传递指针?
  10. WinForm 对EXCEL 的操作(三)
  11. [再学Python] - 4 - 循环
  12. redis bitmap存储入门
  13. python模块:array数组模块
  14. 零跑汽车上半年表现亮眼,全域自研能力加持下业绩高速增长
  15. order by排序的用法
  16. 基于matlab进行图像处理学习——从入门到入魔
  17. java驱动音响设备发音_XP环境下驱动正常、声卡正常但音响没声音怎么解决?
  18. Java调用支付宝身份认证接口
  19. python 计算快递费
  20. Excel如何间隔插入空白列

热门文章

  1. DNS(域名系统)是什么?
  2. Joyful Pandas--综合练习
  3. 小小总结之渗透测试面试题以及答案
  4. 第三章:Servlet、ServletConfig、ServletContext
  5. 冰封王座笑话:各英雄临死前说的话
  6. c# rar解压大小_C#解压、压缩RAR文件
  7. MMGG聚焦| Mines of Dalarnia-土地预售在即
  8. Easy Connect 当前IE代理启用了自动配置脚本,不允许使用CS客户端登录
  9. 【毕业设计】46-基于单片机的智能卫浴系统设计(原理图工程+仿真工程+源代码+答辩论文+答辩PPT)
  10. win10应用商店里的应用提取