一、hook技术简介
1. Hook技术定义
Hook技术是一种通过拦截和修改程序执行流程来实现功能扩展或行为改变的技术。在前端开发中,它主要指通过重写JavaScript函数或方法来监控或改变其原有行为。
2. Hook实现原理
Hook技术的可行性基于以下几个关键因素:
-
客户端执行控制权:浏览器环境赋予客户端对JavaScript的完全解释权
-
JavaScript语言特性:
-
弱类型系统允许变量和函数的动态重定义
-
函数是一等公民,可以被替换和传递
-
原型链机制使得方法替换成为可能
-
-
作用域机制:Hook需要确保在相同作用域内操作才能生效
3. Hook的应用价值
Hook技术在前端逆向和安全分析中具有重要作用:
-
快速定位加密逻辑:相比传统断点调试更高效
-
动态分析能力:实时监控函数调用和数据流
-
非侵入式调试:不需要修改原始代码即可进行分析
-
降低逆向复杂度:简化加密算法的定位过程
4. Hook实施流程
4.1 目标定位
-
明确需要Hook的对象(函数、方法、API等)
-
常见目标包括:
-
加密函数(如CryptoJS相关方法)
-
网络请求相关(XMLHttpRequest、fetch)
-
特定业务逻辑函数
-
4.2 Hook逻辑编写
4.3 调试技巧
-
作用域确认:确保Hook代码与目标函数在同一作用域
-
错误处理:添加try-catch防止Hook导致页面崩溃
-
性能考量:避免在频繁调用的函数上使用复杂Hook逻辑
-
链式Hook:支持多次Hook同一函数时的执行顺序管理
5. 高级Hook技巧
-
条件Hook:根据调用参数决定是否触发debugger
-
原型链Hook:通过修改原型方法影响所有实例
-
事件Hook:拦截和修改事件监听器
-
定时器Hook:监控setTimeout/setInterval调用
6. 注意事项
-
页面兼容性:某些网站会检测Hook行为
-
性能影响:复杂Hook可能影响页面性能
-
作用域隔离:注意闭包和模块化带来的作用域限制
-
反Hook措施:部分网站会采用函数签名校验等方法防止Hook
二、HOOK方法
站点:https://www.hanghangcha.com/hhcreport
在 JavaScript 中,JSON.stringify() 和 JSON.parse() 是两个关键方法,主要用于 JavaScript 对象与 JSON 字符串之间的相互转换。JSON.stringify() 负责将 JavaScript 对象序列化为 JSON 字符串,便于网络传输或存储;而 JSON.parse() 则用于将接收到的 JSON 字符串反序列化为 JavaScript 对象,以便程序处理。
然而,在涉及敏感数据(如用户名和密码)传输时,必须格外注意安全性。明文传输密码是极其危险的,即使使用 JSON.stringify() 封装,若未加密,数据仍可能被窃取。因此,最佳实践包括:
-
强制使用 HTTPS,确保数据传输过程加密,防止中间人攻击。
-
避免直接传输明文密码,前端应对密码进行哈希处理(如 SHA-256 + Salt),仅发送哈希值,而非原始密码。
-
防范 JSON 注入和 XSS 攻击,使用
try-catch安全解析 JSON,并在服务端严格校验数据。
此外,可通过 replacer 函数过滤敏感字段,或使用格式化输出(如 JSON.stringify(obj, null, 2))方便调试。总之,JSON.stringify() 和 JSON.parse() 是数据交互的核心工具,但必须结合安全措施,才能确保敏感信息的安全传输。
(function (){
var parse_=JSON.parse
JSON.parse=function(bc){
debugger
return parse_(bc) // 调用原本的JSON.parse
}
})()
这段代码实现了一个典型的 JavaScript 函数劫持(Hook)技巧,通过重写 JSON.parse 方法嵌入调试逻辑。其核心思路是:
-
备份原生方法
使用立即执行函数(IIFE)创建闭包环境,先通过var parse_ = JSON.parse保存原始方法引用,避免方法丢失。 -
方法重写
将JSON.parse替换为自定义函数,在新函数中首先执行debugger语句强制触发调试断点,使代码执行暂停在开发者工具中。 -
透明传输
最终仍调用备份的原始方法parse_(bc)完成实际解析工作,确保不影响正常业务逻辑,实现"拦截但不阻断"的效果。
典型应用场景
-
数据流分析:监控前端接收的 JSON 数据结构和内容
-
安全审计:检测可能的恶意 JSON 数据注入
-
逆向工程:分析第三方网站的数据处理逻辑
-
异常调试:定位 JSON 解析异常的调用上下文
注意事项
-
仅限开发环境使用,生产环境需移除否则会导致性能问题
-
调试完成后应通过
JSON.parse = parse_恢复原始方法 -
可扩展性强,可在 debugger 前后添加日志等自定义逻辑
这种 Hook 技巧体现了 JavaScript 的动态特性,是前端调试和逆向分析的常用手段,但需注意使用边界,避免滥用影响代码健壮性。
三、HOOK cookie操作
1.认识方法
WEBAPI地址:Web API | MDN
Object.defineProperty 为对象的属性赋值,替换对象属性
基本语法:Object.defineProperty(obj,prop,descriptor),它的作用就是直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,接收的三个参数含义如下:
- obj:需要定义属性的当前对象;
- prop:当前需要定义的属性名;
// 定义一个对象 user,包含 age 属性
user = {
age: '123'
}
// 将 user.age 的值保存到变量 aa 中(初始值为 '123')
aa = user.age
// 使用 Object.defineProperty 对 user.age 属性进行拦截(数据劫持)
Object.defineProperty(user, "age", {
// getter 方法:当读取 user.age 时触发
get: function() {
console.log('有人读取了 age 属性') // 可以添加读取监听
return aa // 返回之前存储的值
},
// setter 方法:当设置 user.age 时触发
set: function(newVal) {
console.log("有人修改了 age 属性,新值是:", newVal) // 打印修改日志
aa = newVal // 更新存储的值
}
})
// 测试读取(会触发 getter)
console.log(user.age) // 输出:123
// 测试修改(会触发 setter)
user.age = '23342' // 控制台会打印:"有人修改了 age 属性,新值是: 23342"
// 再次读取验证修改结果
console.log(user.age) // 输出:23342
2.hook cookie示例
目标站点:A股市场_同花顺行情中心_同花顺财经网
cookie 钩子用于定位 cookie 中关键参数生成位置,以下代码演示了当cookie中匹配到了 v , 则插入断点:
(function(){
cookie_val=document.cookie
Object.defineProperty(document,'cookie',{
set:function(new_val){
debugger
cookie_data=new_val
},
get:function(){
return cookie_val
},
})
})()
四、HOOK XHR请求
定义了一个变量 open 保留原始 XMLHttpRequest.open 方法,然后重写 XMLHttpRequest.open 方法,判断如果字符串值在URL里首次出现的位置-1,即URL里包含 analysis 字符串,则执行 debugger 语句,会立即断下。
(function(){
var _open=window.XMLHttpRequest.prototype.open
window.XMLHttpRequest.prototype.open=function (method,url,async){
debugger
return _open.apply(this,arguments)
}
})()
五、XMLHttpRequest 与拦截器
1.XMLHttpRequest
-
文档地址:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
-
XMLHttpRequest(XHR) 对象用于服务器交互。通过XMLHttpRequest 可以在刷新页面的情况下请求特定URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX编程中被大量使用。
-
可以理解为是ajax的底层操作
XMLHttpRequest.open()
方法初始化一个新创建的请求,或重新初始化一个请求。
xhrReq.open(method,url,async);
XMLHttpRequest.send()
发送请求。如果请求是异步的(默认),那么该方法将在请求发送后立即返回。
方法接受一个可选的参数,其作为请求主体;如果请求方法是GET或者HEAD,则将请求主体设置为null。
xhrReq.send(body)
XMLHttpRequest.setRequestHeader()
设置HTTP请求头的值。必须在 open() 之后、send()之前调用 setRequestHeader()方法。
myReq.setRequestHeader(header,value); // headers['key']=value
XMLHttpRequest.onreadystatechange
当 readyState 属性发生变化时,调用的事件处理器。
http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice#szseGem
// http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice#szseGem
var xhr =new XMLHttpRequest()
// 初始化
xhr.open('post','http://www.cninfo.com.cn/new/disclosure',true)
// 加请求头
xhr.setRequestHeader('accept','*/*')
// 接收响应
xhr.onreadystatechange = function (){
console.log(xhr.response);
}
// 发送请求
xhr.send('column=szse_gem_latest&pageNum=2&pageSize=30&sortName=&sortType=&clusterFlag=true')
2.拦截器
- 请求拦截器:在发送请求之前,可以借助一些函数来对请求的内容和参数做一些检测。若有问题可以直接取消请求。
- 响应拦截器:当服务器返回响应数据时,响应拦截器会在我们拿到结果前预先处理响应数据。例如对响应数据做一些格式化处理,或者当响应失败时,可以做一些失败提醒和记录。
// npm install axios
axios = require('axios')
//设置请求拦截器
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功')
config.headers['sign'] = '小孩'
return config;
}, function (error) {
console.log('请求拦截器 失败')
return Promise.reject(error);
});
//设置响应拦截器
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功')
console.log('调解密函数进行解密数据')
//return response;
return response.data; //修改响应数据
}, function (error) {
console.log('响应拦截器 失败')
return Promise.reject(error);
});
// 发送请求
// function(res){
// console.log(res) == res=>console.log(res) //箭头函数
// }
axios.get('http://httpbin.org/get').then(res=>console.log(res))
// 不是所有的网址都有拦截器
// 加载html --> 加载js代码 --> 用户触发事件(ajax) --> 构造请求对象 -->请求拦截器 -->发送请求 --> 返回数据 --> 响应拦截器(解密) --> 请求成功的回调 success done then
7230

被折叠的 条评论
为什么被折叠?



