爬虫小白-如何调试列表页链接与详情链接不一样并三种方式js逆向解决AES-ECB

news/2024/12/29 19:52:51/

目录

      • 一、网站分析
      • 二、定位监听
      • 三、熟悉AES-ECB
      • 四、调试分析
      • 五、node运行js
      • 六、Python执行js

一、网站分析

  • 三年前的案例,我的原始文章
  • 网站 ,如图我们直接点击标题进入到详情页,链接会发生跳转,且与我们在详情看到的链接,与在列表页看到的链接完全不一样,如果拿列表页的链接直接新建标签页打开的话,详情页也是403,而只有触发点击的模式才能拿看到真实的详情链接
  • 假详情链接 http://ggzy.zwfwb.tj.gov.cn:80/jyxxcggg/1025448.jhtml
  • 真详情链接 http://ggzy.zwfwb.tj.gov.cn/jyxxcggg/Hw5fFNS%5EhnOR3wD5T5hxxA.jhtml
    在这里插入图片描述
    在这里插入图片描述

二、定位监听

  • 谷歌浏览器点中a标签
    在这里插入图片描述
  • 火狐浏览器有自带的event事件监听在这里插入图片描述

三、熟悉AES-ECB

  • 1、分析前,需要熟悉下aes加密是什么,熟悉的可能是md5加密,md5加密是哈希算法,不可逆不能从结果推出明文;而aes是对称加密算法,区别之一可加密可解密,即可反推明文
    在这里插入图片描述
  • 2、 AES的ECB模式,只需要找到key密钥,就可以加密解密了 ,在线调试AES加密解密
    在这里插入图片描述
  • 3、AES加密解密代码

四、调试分析

  • 以谷歌浏览器为例子
    在这里插入图片描述

  • 开始添加断点,嗯~ 在定义变量这里打个断点试试,然后在点击列表链接,会发现js停在了断点处,然后咱们就一步一步的往下调试,会发现列表的url是如何加密的了,而其中最核心的加密算法,其实是用了CryptoJS的对称加密AES加密,并且使用的是ECB模式,Pkcs7填充,密钥在调试这部分的时候可以看到是何值
    在这里插入图片描述
    在这里插入图片描述

  • 抠出js:将整个js文件全部复制下来,在console面板可直接运行,以下是将关键js扣出来并在新建js脚本运行后的结果,大功告成,下面我用python来还原
    在这里插入图片描述

五、node运行js

  • 前端定义的CryptoJS我并没有直接复制,而是通过本地的node直接导入CryptoJS库,此时只需要将关键代码扣出来即可;
  • 本地需安装node环境,然后再安装crypto-js库: npm install crypto-js -g
  • 重要参数:key是密钥;指定模式默认ECB模式;padding是用来填充数据的,如果需要加密的数据的字节码的长度不是块大小的整数倍就需要填充
  • 方式1:扣js,缺啥补啥
    var CryptoJS = require('crypto-js');
    var req = function(hh) {
    var s = "qnbyzzwmdgghmcnm";
    var ee = "_blank";
    var aa = hh.split("/");
    var aaa = aa.length;
    var bbb = aa[aaa - 1].split('.');
    var ccc = bbb[0];
    var cccc = bbb[1];
    var r = /^\+?[1-9][0-9]*$/;
    if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {var srcs = CryptoJS.enc.Utf8.parse(ccc);var k = CryptoJS.enc.Utf8.parse(s);var en = CryptoJS.AES.encrypt(srcs, k, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});var ddd = en.toString();ddd = ddd.replace(/\//g, "^");ddd = ddd.substring(0, ddd.length - 2);var bbbb = ddd + '.' + bbb[1];aa[aaa - 1] = bbbb;var uuu = '';for (i = 0; i < aaa; i++) {uuu += aa[i] + '/'}uuu = uuu.substring(0, uuu.length - 1);return uuu;
    }
    }
    console.log(req("http://ggzy.xzsp.tj.gov.cn:80/jyxxcggg/948547.jhtml"));
    
  • 方式2:js自带的模块CryptoJS,加理解的逻辑
    var CryptoJS = require("crypto-js");
    var encrypt_req = function(key,text) {var l = CryptoJS.enc.Utf8.parse(text);var e = CryptoJS.enc.Utf8.parse(key);var a = CryptoJS.AES.encrypt(l, e, {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7})return a.toString()  // 此方式返回base64  // return a.ciphertext.toString() // 返回hex格式的密文  
    }// ECB模式加密base64
    console.log(encrypt_req('qnbyzzwmdgghmcnm', '1025528'));
    
    在这里插入图片描述

六、Python执行js

  • python调用js三种方式:
    • 要么用python现有的模块替换js相同的逻辑,即python还原
    • 要么通过execjs/ py_mini_racer等执行
    • 要么通过node部署服务开接口执行
  • python的execjs库调用js
    """通过execjs执行js"""
    import execjs  # pip install execjs
    from loguru import logger
    list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml'
    with open('./aes.js', "r", encoding='utf-8') as f:ctx = execjs.compile(f.read())
    true_url = ctx.call('req', list_url)
    logger.info(f"详情的url:{list_url} >真实的url: {true_url}")#######分割线#######
    import execjs  # pip install execjs
    from loguru import logger
    list_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml'
    ccc = list_url.split('/')[-1].rstrip('.jhtml')
    with open('./aes.js', "r", encoding='utf-8') as f:ctx = execjs.compile(f.read())
    suffix = ctx.call('encrypt_req', 'qnbyzzwmdgghmcnm', '1025528').replace('/', '^')[:-2]
    true_url = f"http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/{suffix}.jhtml"
    logger.info(f"详情的url:{list_url} >真实的url: {true_url}")
  • python自带的aes库还原逻辑:pip install pycryptodome
    from loguru import logger
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    import base64def aes_ecb_encrypt_text(decrypt_text: str, key: str) -> str:"""加密AES_ECB明文:param decrypt_text: 待加密的字符串:param key: 密钥:return:  加密后的数据"""aes2 = AES.new(key.encode('utf-8'), AES.MODE_ECB)encrypt_text = aes2.encrypt(pad(decrypt_text.encode('utf-8'), AES.block_size, style='pkcs7'))encrypt_text = str(base64.encodebytes(encrypt_text), encoding='utf-8').replace("\n", "")return encrypt_textlist_url = 'http://ggzy.zwfwb.tj.gov.cn:80/jyxxcgjg/1025528.jhtml'
    ccc = list_url.split('/')[-1].rstrip('.jhtml')
    decrypt_str = ccc
    key_str = "qnbyzzwmdgghmcnm"
    encrypt_str = aes_ecb_encrypt_text(decrypt_str, key_str).replace('/', '^')[:-2]
    true_url = list_url.replace(decrypt_str, encrypt_str)
    logger.info(f"详情的url:{list_url} >真实的url: {true_url}")
    
    在这里插入图片描述

http://www.ppmy.cn/news/993120.html

相关文章

前端面试题 —— Vue (三)

目录 一、v-model 可以被用在自定义组件上吗&#xff1f;如果可以&#xff0c;如何使用&#xff1f; 二、描述下Vue自定义指令 &#xff08;1&#xff09;自定义指令基本内容 &#xff08;2&#xff09;使用场景 &#xff08;3&#xff09;使用案例 三、Vue是如何收集依赖…

前端请求传输token到后端的两种方式

谈谈 cookie & session & jwt - 掘金 前端在每次请求时把token放在请求头中发送给后端&#xff0c;目前有两种方式&#xff1a; 一是通过cookie的形式&#xff0c;即把token放在cookie中&#xff0c;每次浏览器会自动帮我们带过去&#xff0c;不需要我们自己设置。 二…

美颜SDK开发指南:优化直播人像表现

在当今社交媒体和直播平台的流行趋势下&#xff0c;越来越多的用户渴望在直播中展现更加自信和美丽的一面。本文将探讨美颜SDK的开发指南&#xff0c;介绍其优化直播人像表现的重要性以及关键的技术要点。 一、用户为什么离不开美颜&#xff1f; 美颜SDK作为一种集成在直播应用…

php://filter绕过死亡exit

文章目录 php://filter绕过死亡exit前言[EIS 2019]EzPOP绕过exit 参考 php://filter绕过死亡exit 前言 最近写了一道反序列化的题&#xff0c;其中有一个需要通过php://filter去绕过死亡exit()的小trick&#xff0c;这里通过一道题目来讲解 [EIS 2019]EzPOP 题目源码&#…

IT职场笔记

MySQL笔记之一致性视图与MVCC实现 一致性读视图是InnoDB在实现MVCC用到的虚拟结构&#xff0c;用于读提交&#xff08;RC&#xff09;和可重复度&#xff08;RR&#xff09;隔离级别的实现。 一致性视图没有物理结构&#xff0c;主要是在事务执行期间用来定义该事物可以看到什…

【LeetCode】解码方法(动态规划)

解码方法 题目描述算法流程编程代码代码优化 链接: 解码方法 题目描述 算法流程 编程代码 class Solution { public:int numDecodings(string s) {int n s.size();vector<int> dp(n);dp[0] s[0] ! 0;if(n 1) return dp[0];if(s[1] < 9 && s[1] > 1) d…

牛客网Verilog刷题——VL49

牛客网Verilog刷题——VL49 题目解析答案 题目 从A时钟域提取一个单时钟周期宽度脉冲&#xff0c;然后在新的时钟域B建立另一个单时钟宽度的脉冲。A时钟域的频率是B时钟域的10倍&#xff1b;A时钟域脉冲之间的间隔很大&#xff0c;无需考虑脉冲间隔太小的问题。电路的接口如下图…

一个女程序员的成长之路

2013年大学毕业了&#xff0c;带着迷茫与好玩&#xff0c;我还年轻的心态&#xff0c;开始在郑州寻觅工作机会&#xff0c;最后很荣幸的在一家小公司入职了&#xff0c;工作的内容是给种植大棚的用户打电话&#xff0c;推销农药。每天就是在网上各种农业平台上面找号码&#xf…