python爬虫hook定位技巧、反调试技巧、常用辅助工具

一、浏览器调试面板介绍

在这里插入图片描述

二、hook定位、反调试

Hook 是一种钩子技术,在系统没有调用函数之前,钩子程序就先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,也可以强制结束消息的传递。简单来说,修改原有的 JS 代码就是 Hook。
Hook 技术之所以能够实现有两个条件:

  • 客户端拥有JS的最高解释权,可以决定在任何时候注入JS,而服务器无法阻止或干预。服务端只能通过检测和混淆的手段,另 Hook 难度加大,但是无法直接阻止。
  • JS 是一种弱类型语言,同一个变量可以多次定义、根据需要进行不同的赋值,而这种情况如果在其他强类型语言中则可能会报错,导致代码无法执行。js 的这种特性,为我们 Hook 代码提供了便利。
    注意:JS 变量是有作用域的,只有当被 hook 函数和 debugger断点在同一个作用域的时候,才能 hook 成功。
  1. 定位header关键字
    (function (){var org = window.XMLHttpRequest.prototype.setRequestHeader;window.XMLHttpRequest.prototype.setRequestHeader = function (key,value){//在请求中发现某个关键字,断点if(key=='value'){debugger}return org.apply(this,arguments)}
    })()
    
  2. window对象的属性
    // 定义hook属性
    var window_flag_1 = "_t";
    var window_flag_2 = "ccc";
    var key_value_map = {};
    var window_value = window[window_flag_1];
    // hook
    Object.defineProperty(window, window_flag_1, {get: function(){console.log("Getting",window,window_flag_1,"=",window_value);//debuggerreturn window_value},set: function(val) {console.log("Setting",window, window_flag_1, "=",val);window_value = val;key_value_map[window[window_flag_1]] = window_flag_1;set_obj_attr(window[window_flag_1],window_flag_2);
    });
    function set_obj_attr(obj,attr){var obj_attr_value = obj[attr];Object.defineProperty(obj,attr, {get: function() {console.log("Getting", key_value_map[obj],attr, "=", obj_attr_value);//debuggerreturn obj_attr_value;},set: function(val){console.log("Setting", key_value_map[obj], attr, "=", val);obj_attr_value = val;});
    }
    
  3. 定位cookie关键字,示例网站:http://q.10jqka.com.cn/
    
    (function() {"use strict";var cookieTemp = "";Object.defineProperty(document, "cookie", {writable: false, // 表示能否修改属性的值,即值是可写的还是只读configurable: false, // 表示能否通过 delete 删除属性、能否修改属性的特性,或者将属性修改为访问器属性set: function(val) {if (val.indexOf("cookie的参数名称") != -1) {debugger ;}cookieTemp = val;return val;},get: function() {return cookieTemp;}})
    }
    )();
  • 访问网站,打开控制台,查看请求头,cookie中v已加密
    在这里插入图片描述
  • 新建代码片段cookie,并点击运行
    在这里插入图片描述
  • 在个股行情下切换tab重新发送请求,一直点击跳过下一个函数调用,看到setCookie时,会发现Fn是键值v,n是value值,rt.update()是生成n的函数,鼠标悬浮到函数中,点击悬浮框中的链接,会跳到rt.update函数中,cookie定位成功
    在这里插入图片描述
  1. 定位url关键字,示例网站:https://www.ynjzjgcx.com/dataPub/enterprise
(function () {var open = window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open = function (method, url, async) {if (url.indexOf("key") != -1) {debugger;}return open.apply(this, arguments);};
})();
  • 打开网址,完成验证码验证,会发现请求中params参数已加密
    在这里插入图片描述
  • 新建url代码片段,点击运行
    在这里插入图片描述
  • 点击搜索,完成验证码验证,一直点击跳过下一个函数调用,遇到then方法进入点击进入该函数,之所以进入该函数是因为一直点击跳过下一个函数调用在作用域看不到明文信息,所以可能加密是在请求拦截器中处理的
    在这里插入图片描述
  • 进入该函数后,一直点击跳过下一个函数调用,会发现响应拦截器Vt.interceptors.response,在该文件再去找请求拦截器Vt.interceptors.request,并在请求拦截器中打点
    在这里插入图片描述
  • 跳过断点调试,再点击搜索,完成验证码验证,会进入请求拦截器函数,一直点击跳过下一个函数调用,会发现加密参数,是经过gwe函数加密的,定位成功
    在这里插入图片描述
  1. 定位JSON.stringify、JSON.parse,一般用于请求和响应是密文,示例网站:http://birdreport.cn/home/activity/page.html
    '''请求是密文'''
    (function() {var _stringify = JSON.stringify;JSON.stringify = function(ps) {console.log("Hook JSON.stringify ——> ", ps);debugger;return _stringify(ps);  // 不改变原有的执行逻辑 }
    })();'''响应是密文'''(function() {var _parse = JSON.parse;JSON.parse = function(ps) {console.log("Hook JSON.parse ——> ", ps);debugger;return _parse(ps);  // 不改变原有的执行逻辑 }
    })(); 
    
  • 访问网站,打开控制面板,找到请求会发现,参数、响应结果、请求头中Sign和Requestid已加密
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 定位参数加密位置,新建json_stringify代码片段,点击运行
    在这里插入图片描述
  • 点击分页重新发送请求,会发现明文参数,且加密位置就在Call Stack(栈)中的某个位置
    在这里插入图片描述
  • 点击第一个栈,在这里发现了请求头中的Sign和Requestid分别对应变量d和f,在方法最前面打个断点,点击never pause here(永不停留),直到断点结束,切换分页
    在这里插入图片描述
  • 切换分页后会发现已经定位到刚才断点的位置,一直点击跳过下一个函数调用,会发现e变量是明文参数,再继续看下面会发现e变量经过了encrypt.encryptUnicodeLong函数的处理,在控制台输入b.data、d、f回车打印出b.data值,点击deactivate breakpoints(禁用断点),再点击never pause here(永不停留)跳过当前断点,再切回Network对比请求中的参数、header中的Sign和Requestid会发现和控制台中一样
    在这里插入图片描述
  • 定位响应加密位置,新建json_parse代码片段,点击运行
    在这里插入图片描述
  • 点击分页重新发送请求,遇到断点点击never pause here(永不停留)跳过当前断点,直到看见控制态输出明文信息
    在这里插入图片描述
  • 再去栈中点击第一个,会发现res是返回结果,而res.data使用了BIRDREPORT_APIJS.decode该方法解密,在控制台输入decode_str点击回车,会发现明文信息
    在这里插入图片描述
  1. constructor构造器构造出来的debugger反调试,示例网站:http://www.spolicy.com/
    var _constructor = constructor;
    Function.prototype.constructor = function(s) {if (s == "debugger") {console.log(s);return null;}return _constructor(s);
    }
    
  • 访问网站,打开控制面板,会发现,页面一直在debugger,点击栈中的 ’a‘,在控制台输出代码中红色地方会发现这是constructor构造器构造出来的debugger
    在这里插入图片描述
  • 在右侧代码片段创建,constructor_debugger,输入constructor构造器构造出来的debugger反调试代码,并点击运行,会发现反调试成功
    在这里插入图片描述
  1. 浏览器debugger反调试,示例网站:http://www.10010.com/net5/074/
  • 访问网站,打开控制面板,会发现,页面一直在debugger
    在这里插入图片描述
  • 鼠标右击debugger行,点击never pause here(永不停留)
    在这里插入图片描述
  • 点击never pause here后,再点击恢复脚本执行,如再遇到debugger,重复上述步骤,直到不再遇到debugger,会发现反调试成功
    在这里插入图片描述
  1. 多种debugger类型反调试,示例网站:https://www.nmpa.gov.cn/
  • 访问网站,打开控制面板,鼠标右击debugger行,点击never pause here(永不停留),再点击恢复脚本执行
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/47a312fb8eb442fda71705f5203aa202.png
  • 在右侧代码片段创建,constructor_debugger,输入constructor构造器构造出来的debugger反调试代码,并点击运行,会发现反调试成功
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/bb42989fe667415f9643b410e718555c.png
  1. 定时debugger反调试
    setInterval = function () {}
    
  • 创建测试html文件
    <!doctype html>
    <html>
    <head><meta charset="utf-8">
    </head>
    <body>
    <h1 id="h1"></h1>
    </body>
    <script>var h1 = document.getElementById('h1')function test() {debugger};setInterval(test, 100);h1.innerHTML = 'hello word';
    </script>
    </html>
    
  • 浏览器打开该html,在打开控制台会发现一直在debugger,在setInterval处打个断点,并刷新页面
    在这里插入图片描述
  • 在代码片段新建setInterval_debugger,并点击运行,点击跳过当前断点,会发现反调试成功
    在这里插入图片描述
  1. 修改响应文件debugger反调试
  • 创建测试html文件
    <!doctype html>
    <html>
    <head><meta charset="utf-8">
    </head>
    <body>
    <h1 id="h1"></h1>
    </body>
    <script>var h1 = document.getElementById('h1')function test() {debugger};setInterval(test, 100);h1.innerHTML = 'hello word';
    </script>
    </html>
    
  • 浏览器打开该html,在打开控制台会发现一直在debugger,点击Overrides新建文件夹xxx,右击文件选择Override content(覆盖内容)
    在这里插入图片描述
  • 修改保存到本地的文件,删除debugger,Ctrl+s保存刷新页面,会发现调试成功
    在这里插入图片描述
  1. eval构造器构造出来的debugger反调试
    (function() {'use strict';var eval_ = window.eval;window.eval = function(x) {eval_(x.replace("debugger;", "  ; "));}
    ;window.eval.toString = eval_.toString;
    }
    )();
    
  2. 通用反调试
    (function() {var _constructor = unsafeWindow.Function.prototype.constructor;unsafeWindow.Function.prototype.constructor = function() {var fnContent = arguments[0];if (fnContent) {if (fnContent.includes('debugger')) { var caller = Function.prototype.constructor.caller; // Non-standard hack to get the function callervar callerContent = caller.toString();if (callerContent.includes(/\bdebugger\b/gi)) { // Eliminate all debugger statements from the caller, if anycallerContent = callerContent.replace(/\bdebugger\b/gi, '');eval('caller = ' + callerContent); // Replace the function}return (function () {});}}return _constructor.apply(this, arguments);};
    })();
    
三、其他定位
  1. 元素定位断点定位,示例网站:https://oauth.d.cn/auth/goLogin.html
  • 打开网站,输入用户名密码登录会发现,密码被加密
    在这里插入图片描述
  • 定位到立即登录元素,找到事件监听,点击:goLogin.html,进入该元素点击事件方法内
    在这里插入图片描述
  • 在方法内打个断点,随便输入用户名密码点击立即登录,图中所示,会发现密码在红色标记的rsa方法中加密
    在这里插入图片描述
  1. XHR断点定位,示例网站:https://oauth.d.cn/auth/goLogin.html
  • 打开网站,输入用户名密码登录会发现,密码被加密
    在这里插入图片描述
  • 点击headers,复制请求中的路径:auth/login
    在这里插入图片描述
  • 点击sources,把赋值好的路径添加到XHR/fetch中,再点击登录
    在这里插入图片描述
  • 一直点击,跳过下一个函数调用,图中红色标记位置
    在这里插入图片描述
  • 直到在作用域中,遇到明文密码信息,赋值变量到搜索框(Ctrl+F),就能找到加密的位置
    在这里插入图片描述
  1. 方法栈定位, 栈是一种先进后出的特殊线性表结构,可以在断点定位、元素定位之后,使用方法栈定位缩小加密位置范围,示例网站:https://oauth.d.cn/auth/goLogin.html
  • 打开网站,输入用户名密码登录会发现,密码被加密
    在这里插入图片描述
  • 点击headers,复制请求中的路径:auth/login
    在这里插入图片描述
  • 点击sources,把赋值好的路径添加到XHR/fetch中,再点击登录
    在这里插入图片描述
  • 会发现在call stack下有个列表,这从点击到发送请求的栈,加密代码一定在这个栈中,点击绿色标记,在作用域中会发现明文密码信息,赋值变量到搜索框(Ctrl+F),就能找到加密的位置
    在这里插入图片描述
    在这里插入图片描述
四、爬虫辅助工具
  1. https://curlconverter.com/,谷歌浏览器F12,左击请求,选择Copy>Copy as cURL(bash),黏贴到网站输入框,会自动生成python爬虫代码
  2. https://www.sojson.com/encrypt_md5.html md5加密,验证md5加密是否被魔改,如果未被模块,可以使用nodejs cryptoc插件模拟加密和算法库;用于生成加密参数的js文件
  3. https://spidertools.cn/#/crypto,爬虫工具库,包括加解密、json格式化、html格式化、json对比等功能
  4. chrome插件:XPath Helper,可以在浏览器中xpath语法
  5. chrome插件:FeHelper,JSON格式化工具
  6. chrome插件:tampermonkey(篡改猴),hook脚本工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/169797.html

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

相关文章

掌握未来技术趋势:深度学习与量子计算的融合

掌握未来技术趋势&#xff1a;深度学习与量子计算的融合 摘要&#xff1a;本博客将探讨深度学习与量子计算融合的未来趋势&#xff0c;分析这两大技术领域结合带来的潜力和挑战。通过具体案例和技术细节&#xff0c;我们将一睹这两大技术在人工智能、药物研发和金融科技等领域…

CnosDB 在最近新发布的 2.4.0 版本中增加对时空函数的支持。

CnosDB 在最近新发布的 2.4.0 版本中增加对时空函数的支持。 概述 时空函数是一种用于描述时空结构和演化的函数。它在物理学、数学和计算机科学等领域中都有广泛的应用。时空函数可以描述物体在时空中的位置、速度、加速度以及其他相关属性。 用法 CnosDB 将使用一种全新的…

[工业自动化-16]:西门子S7-15xxx编程 - 软件编程 - 西门子仿真软件PLCSIM

目录 前言&#xff1a; 一、PLCSIM仿真软件 1.1 PLCSIM仿真软件基础版&#xff08;内嵌&#xff09; 1.2 PLCSIM仿真软件与PLCSIM仿真软件高级版的区别&#xff1f; 1.3 PLCSIM使用 前言&#xff1a; PLC集成开发环境是运行在Host主机上&#xff0c;Host主机与PLC可以通过…

Android---内存泄漏的优化

内存泄漏是一个隐形炸弹&#xff0c;其本身并不会造成程序异常&#xff0c;但是随着量的增长会导致其他各种并发症&#xff1a;OOM&#xff0c;UI 卡顿等。 为什么要将 Activity 单独做预防&#xff1f; 因为 Activity 承担了与用户交互的职责&#xff0c;因此内部需要持有大…

从0到1实现一个前端监控系统(附源码)

目录 一、从0开始 二、上报数据方法 三、上报时机 四、性能数据收集上报 收集上报FP 收集上报FCP 收集上报LCP 收集上报DOMContentLoaded 收集上报onload数据 收集上报资源加载时间 收集上报接口请求时间 五、错误数据收集上报 收集上报资源加载错误 收集上报js错…

clouldcompare工具使用

文章目录 1.界面1.1 布局1.3 视觉显示方向1.4 放大镜1.5 建立旋转中心2.快速入门2.1 剪裁2.2 多点云拼接 1.界面 1.1 布局 参考&#xff1a;https://blog.csdn.net/lovely_yoshino/article/details/129595201 1.3 视觉显示方向 1.4 放大镜 1.5 建立旋转中心 2.快速入门 2.1 …

网络原理-UDP/TCP详解

一. UDP协议 UDP协议端格式 由上图可以看出&#xff0c;一个UDP报文最大长度就是65535. • 16位长度&#xff0c;表示整个数据报&#xff08;UDP首部UDP数据&#xff09;的最大长度&#xff08;注意&#xff0c;这里的16位UDP长度只是一个标识这个数据报长度的字段&#xff0…

灵活运用Vue指令:探究v-if和v-for的使用技巧和注意事项

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、作…

计算机毕业设计 基于Springboot的影院购票管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

SpringBoot 缓存之 @Cacheable 详细介绍

一、简介 1、缓存介绍 Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache&#xff08;JSR-107&#xff09;注解简化我们的开发。&#xfeff; 其…

2023.11.11 hive中的内外部表的区别

一.内部表操作 ------------------------------1内部---------------------------- --建库 create database hive2; --用库 use hive2; --删表 drop table t1; --建表 create table if not exists t1(id int,name string,gender string ); --复制内部表 --复制表结构:CREATE T…

深入理解 TCP;场景复现,掌握鲜为人知的细节

握手失败 第一次握手丢失了&#xff0c;会发生什么&#xff1f; 当客户端想和服务端建立 TCP 连接的时候&#xff0c;首先第一个发的就是 SYN 报文&#xff0c;然后进入到 SYN_SENT 状态。 在这之后&#xff0c;如果客户端迟迟收不到服务端的 SYN-ACK 报文&#xff08;第二次…