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

目录

      • 一、网站分析
      • 二、定位监听
      • 三、熟悉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.mzph.cn/news/15360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React 中的常见 API 和生命周期函数

目录 useStateuseEffectuseRefdangerouslySetInnerHTML生命周期函数 constructorcomponentDidMountstatic getDerivedStateFromPropsshouldComponentUpdatecomponentDidUpdatecomponentWillUnmount useState useState 是 React 的一个 Hook&#xff0c;用于在函数组件中添加…

iOS开发-格式化时间显示刚刚几分钟前几小时前等

iOS开发-格式化时间显示刚刚几分钟前几小时前等 在开发中经常遇到从服务端获取的时间戳&#xff0c;需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。 主要用到了NSCalendar、NSDateComponents这两个类 NSString *result nil;NSCalendarUnit components (NSC…

【后端面经】微服务构架 (1-6) | 隔离:如何确保心悦会员体验无忧?唱响隔离的鸣奏曲!

文章目录 一、前置知识1、什么是隔离?2、为什么要隔离?3、怎么进行隔离?A) 机房隔离B) 实例隔离C) 分组隔离D) 连接池隔离 与 线程池隔离E) 信号量隔离F) 第三方依赖隔离二、面试环节1、面试准备2、基本思路3、亮点方案A) 慢任务隔离B) 制作库与线上库分离三、章节总结 …

@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnClass

一、ConditionalOnBean ConditionalOnBean 是 Spring Boot 中的一个条件注解&#xff0c;用于在 Spring 容器中存在指定类型的 Bean 时才会生效。 具体解释如下&#xff1a; 当使用 ConditionalOnBean 注解在某个配置类或 Bean 的声明上时&#xff0c;Spring Boot 会检查 Sp…

以智慧监测模式守护燃气安全 ,汉威科技“传感芯”凸显智慧力

城市燃气工程作为城市基建的重要组成部分&#xff0c;与城市居民生活、工业生产紧密相关。提升城市燃气服务质量和安全水平&#xff0c;也一直是政府和民众关注的大事。然而&#xff0c;近年来居民住宅、餐饮等工商业场所燃气事故频发&#xff0c;时刻敲响的警钟也折射出我国在…

MySQL高级篇第4章(逻辑架构)

文章目录 1、逻辑架构剖析1.1 服务器处理客户端请求1.2 Connectors1.3 第一层&#xff1a;连接层1.4 第二层&#xff1a;服务层1.5 第三层&#xff1a;引擎层1.6 存储层1.7 小结 2、SQL执行流程2.1 MySQL 中的 SQL执行流程2.2 MySQL8中SQL执行原理2.3 MySQL5.7中SQL执行原理2.4…

9条建议告诉你如何正确处理PCB设计布线

一、关于PCB布线线宽 1、布线首先应满足工厂加工能力&#xff0c;首先向客户确认生产厂家&#xff0c;确认其生产能力&#xff0c;如图1所示。如客户无要求&#xff0c;线宽参考阻抗设计模板。 图1 PCB板厂线宽要求 2、阻抗模板&#xff0c;根据客户提供的板厚及层数要求&…

LeetCode208.Implement-Trie-Prefix-Tree<实现 Trie (前缀树)>

题目&#xff1a; 思路&#xff1a; tire树&#xff0c;学过&#xff0c;模板题。一种数据结构与算法的结合吧。 代码是&#xff1a; //codeclass Trie { private:bool isEnd;Trie* next[26]; public:Trie() {isEnd false;memset(next, 0, sizeof(next));}void insert(strin…

【环境配置】使用Docker搭建LAMP环境

这篇文章不是介绍DOCKER是什么&#xff0c;也不是阐述DOCKER的核心&#xff1a;镜像/容器和仓库之间的关系,它只是一篇让刚刚接触DOCKER的初学者&#xff0c;在没有完全了解DOCKER是什么之前,也能尽快的在Linux系统下面通过DOCKER来搭建一个LAMP环境&#xff0c;这是其一&#…

工作中遇到的关于配置问题

工作中遇到的问题 想记录一下 一个程序员小白每天遇到的问题 1.创建了一个Maven的web工程&#xff0c;但是启动一直是404&#xff0c;原服务器未能找到目标资源 解决办法&#xff1a; 选择deployment&#xff0c;点击加号选择war格式就OK啦 目录里面无法创建类&#xff0…

WPF实战学习笔记26-首页导航

修改UI&#xff0c;添加单击行为&#xff0c;并绑定导航命令 修改文件&#xff1a;Mytodo.Views.IndexView.xaml ,在导航梯形添加内容 <DataTemplate><BorderMargin"10"Background"{Binding Color}"CornerRadius"5"Opacity"0.9&…

Rust- 闭包

A closure in Rust is an anonymous function you can save in a variable or pass as an argument to another function. You can create the closure using a lightweight syntax and access variables from the scope in which it’s defined. Here’s an example of a clo…

深蓝学院C++基础与深度解析笔记 第13章 模板

1. 函数模板 ● 使用 template 关键字引入模板&#xff1a; template<typename T> //声明&#xff1a;T模板形参void fun(T); // T 函数形参template<typename T> //定义void fun(T) {...}– 函数模板不是函数 –…

什么是Java中的集成测试?

Java中的集成测试&#xff08;Integration Test&#xff09;是一种测试方法&#xff0c;用于测试多个模块或组件之间的交互和集成。在Java中&#xff0c;集成测试通常使用单元测试框架&#xff08;如JUnit&#xff09;编写和运行。 对于初学者来说&#xff0c;集成测试可能有些…

【C/C++】类之间的纵向关系——继承的概念

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

六、初始化和清理(2)

本章概要 垃圾回收器 finalize() 的用途你必须实施清理终结条件垃圾回收器如何工作 垃圾回收器 程序员都了解初始化的重要性&#xff0c;但通常会忽略清理的重要性。毕竟&#xff0c;谁会去清理一个 int 呢&#xff1f;但是使用完一个对象就不管它并非总是安全的。Java 中有…

分享一篇详尽的关于如何在 JavaScript 中实现刷新令牌的指南

介绍 刷新令牌允许用户无需重新进行身份验证即可获取新的访问令牌&#xff0c;从而确保更加无缝的身份验证体验。这是通过使用长期刷新令牌来获取新的访问令牌来完成的&#xff0c;即使原始访问令牌已过期也是如此。 通常&#xff0c;当用户登录时&#xff0c;服务器会生成一对…

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;以其轻量级和高效能而广受欢迎。在本教程中&#xff0c;我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1&#xff1a;更新系统 在安装任何软件之前&#xff0c;让我们先更新系统的软件包列表和已安…

关于提示词 Prompt

Prompt原则 原则1 提供清晰明确的指示 注意在提示词中添加正确的分割符号 prompt """ 请给出下面文本的摘要&#xff1a; <你的文本> """可以指定输出格式&#xff0c;如&#xff1a;Json、HTML提示词中可以提供少量实例&#xff0c;…

大数据面试题:Kafka的单播和多播

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 参考答案&#xff1a; 1、单播 一条消息只能被某一个消费者消费的模式称为单播。要实现消息单播&#xff0c;只要让这些消费者属于同一个消费者组即…