JS逆向-断点调试与反绕过技巧
📝 渗透测试角度优化笔记:JS逆向基础、反调试与实战应用
1. JS逆向与Web安全的关联
JS逆向是前端分析的核心技术,它并非孤立的代码审计,而是与Web安全测试紧密相连。其主要应用场景包括:
- 突破前端防护:分析登录加密、Sign签名、参数混淆等机制,为后续的暴力破解、数据篡改、接口越权等攻击铺路。
- 发现隐藏攻击面:从JS文件中提取API接口、敏感参数、甚至硬编码的密钥或调试信息。
- 逻辑漏洞挖掘:分析前端折扣计算、验证码生成、支付逻辑等,寻找可被利用的业务缺陷。
2. 开发者工具(F12)核心面板使用指南
面板名称 | 核心功能 | 在逆向与安全测试中的应用 |
👁️元素 (Elements) | 查看和实时编辑页面的HTML结构与CSS样式。 | 用于定位与数据提交相关的DOM元素(如表单字段、隐藏值),或观察页面元素的变化(如验证码图片刷新)。 |
🖥️控制台 (Console) | 执行任意JavaScript代码,查看日志和错误信息。 | 1. 测试变量/函数:在断点处,可直接在控制台输入变量名查看其值,或调用已加载的函数。 |
🌐网络 (Network) | 监控所有网络请求的详情(Header、参数、响应)。 | 核心入口: |
📜源代码/来源 (Sources) | 核心调试面板。可查看所有加载的资源(JS、CSS)、设置断点、单步执行、查看调用栈和作用域。 | 逆向主战场: |
📦应用程序 (Application) | 查看和管理本地存储(Cookie、LocalStorage、SessionStorage)、缓存等。 | 用于检查前端存储的敏感信息(如令牌、用户信息),或分析存储对应用状态的影响。 |
3. 核心逆向技术:断点调试六种姿势
断点是暂停代码执行、观察运行时状态的最有效手段。以下是六种常用断点及其在逆向中的应用场景:
断点类型 | 如何设置 | 主要应用场景 |
🔵正常断点 | 在Sources面板的代码行号上单击。 | 基础调试。分析核心加密函数、参数生成逻辑的每一步执行过程。 |
🟡条件断点 | 右键行号 → “添加条件断点”,输入条件表达式。 | 精准定位。只在满足特定条件(如 |
🌸日志断点 | 右键行号 → “添加日志断点”,输入要输出的表达式。 | 插桩分析。无需暂停代码,仅在命中断点时输出日志。非常适合分析复杂的虚拟机和混淆代码,可以打印出关键寄存器和变量的值。 |
📡XHR断点 | Sources → XHR/提取断点 → “+”添加URL包含的关键字。 | 定位请求。当希望拦截所有包含特定关键字(如 |
🖱️事件断点 | Sources → 事件监听器断点 → 展开并勾选目标事件(如 | 分析交互。用于调试由用户操作触发的功能,特别是滑块验证码、图片点击等场景,可以捕捉到事件处理函数。 |
🌳DOM断点 | 元素面板 → 右键目标元素 → 中断 → 子树修改/属性修改/节点移除。 | 追踪DOM变化。当页面元素被动态修改、添加或删除时(如翻页加载、弹窗出现),可以断下并追溯修改DOM的JS代码。 |
4. 调用堆栈分析:理清代码执行逻辑
当断点触发时,调用堆栈 (Call Stack)面板会显示当前函数的调用链。在逆向中,它的作用是:
- 追溯源头:从当前断点位置(如加密函数内部)向上查看,找到是谁调用了这个函数,最终找到参数传入的起点。
- 理解流程:分析整个加密逻辑的执行顺序,避免在嵌套的异步回调或复杂的函数调用中迷失方向。
5. 反调试技术概览
反调试的目的是阻止或干扰开发者工具的调试功能,使逆向分析者难以动态跟踪代码执行。根据其实现方式,主要分为以下几类:
类别 | 代表技术 | 检测原理 | 绕过思路 |
无限循环/断点 | 无限Debugger | 利用 | 禁用所有断点、替换文件、条件断点。 |
键盘事件监听 | 监听F12、Ctrl+Shift+I等 | 监听 | 修改事件监听、Burp替换响应、油猴脚本。 |
环境特征检测 | 检测窗口大小差异、 | 通过比较窗口内外尺寸、 | Hook相关函数、修改返回结果、使用无头浏览器。 |
时间差异检测 | 测量代码执行时间 | 调试状态下代码执行速度变慢,通过时间差判断。 | 设置条件断点跳过检测、修改时间计算逻辑。 |
非浏览器检测 | 检测User-Agent、 | 识别自动化工具或非标准浏览器环境。 | 伪造User-Agent、模拟浏览器环境。 |
6. 常见反调试技术详解与绕过实战
6.1 无限Debugger
- 原理:在关键代码前插入
debugger;语句,或通过setInterval不断触发,导致调试器无限暂停。``javascript
(function() {
function evil() {
debugger;
setTimeout(evil, 100);
}
evil();
})();
`` - 绕过方法:
*禁用所有断点:在Sources面板点击“Deactivate breakpoints”按钮(或按Ctrl+F8),临时忽略所有debugger断点。
*设置条件断点:在debugger行上右键选择“条件断点”,输入false,使其永远不触发。
*替换文件:使用Burp Suite或油猴插件,将响应中的debugger替换为空白。
6.2 键盘事件监听阻止打开调试工具
- 原理:监听
keydown事件,当按F12或Ctrl+Shift+I等组合键时,阻止默认行为或弹窗警告。``javascript
document.addEventListener('keydown', function(e) {
if (e.key === 'F12' || (e.ctrlKey && e.shiftKey && e.key === 'I')) {
e.preventDefault();
return false;
}
});
`` - 绕过方法:
*使用菜单打开:在浏览器菜单中手动选择“开发者工具”。
*Burp替换:拦截响应,移除事件监听代码。
*油猴脚本:注入脚本解除事件监听,如window.removeEventListener('keydown', listener, true)。
6.3 检测开发者工具状态
- 原理:利用
console.log调用次数、console.profile、Function.prototype.toString等方法判断调试器是否打开。``javascript
var c = 0;
setInterval(function() {
console.log(c++);
if (c > 100) alert('调试中!');
}, 100);
`` - 绕过方法:
*Hookconsole.log:在控制台执行console.log = function(){},使其失效。
*修改检测逻辑:通过Burp或油猴替换相关代码,或使用Object.defineProperty重写属性。
6.4 时间差检测
- 原理:在调试模式下,代码执行速度会显著变慢。通过测量两段代码之间的时间差,判断是否处于调试状态。
``javascript
var start = Date.now();
for (var i = 0; i < 10000000; i++) { /* 空循环 */ }
var end = Date.now();
if (end - start > 100) alert('调试中!');
`` - 绕过方法:
*跳过检测:在Date.now()处设置条件断点,修改返回值。
*使用脚本自动化:用无头浏览器(如Puppeteer)运行,避免手动调试。
6.5 非浏览器环境检测
- 原理:检测
navigator.webdriver、navigator.plugins、window.chrome等属性,识别自动化工具。 - 绕过方法:
*使用puppeteer-extra并安装stealth插件,模拟真实浏览器。
*手动修改属性:在控制台执行Object.defineProperty(navigator, 'webdriver', {get: () => undefined})。
7. 实战应用思路:从逆向到漏洞利用
将以上技巧串联起来,形成从发现到利用的闭环:
- 捕获目标:在网络面板找到包含可疑参数(如
sign、token)的请求。 - 定位代码:右键请求 → “启动器” 查看调用栈,或在Sources面板中全局搜索加密参数名。
- 设置断点:
* 如果找到了疑似加密函数,在函数入口处设置正常断点。
* 如果想拦截所有API请求,设置XHR断点。
* 如果是验证码点击,设置事件断点。 - 触发与调试:重新触发操作(如点击登录),代码在断点处暂停。此时:
* 查看作用域,观察变量值,找到生成sign的原始数据和算法。
* 利用调用堆栈,向上追溯,理解数据流。
* 在控制台中测试函数,或修改变量值观察影响。 - 模拟与验证:
* 分析清楚后,可以使用Python、Node.js等语言模拟出加密算法。
* 在Burp Suite中构造请求,使用模拟的算法生成合法参数,尝试绕过前端限制进行漏洞测试(如越权、爆破、篡改价格)。
关键技巧:
- 先禁用所有断点:快速跳过无限
debugger。 - 使用XHR断点定位请求:如果加密由请求触发,直接对请求URL设XHR断点,定位发送位置,绕过前端检测。
- 利用条件断点精准暂停:在可疑函数入口设条件断点,避免频繁暂停。
- 结合Burp替换响应:将服务器返回的JS文件中的反调试代码删除,然后重放请求。
8. 常用工具与插件
- 油猴插件(Tampermonkey):编写脚本动态修改页面代码,移除反调试。
- Burp Suite:拦截响应,使用“Match and Replace”功能删除反调试代码。
- Chrome DevTools 内置功能:
*禁用断点:Ctrl+F8
*黑盒脚本:在Sources面板右键JS文件,选择“Blackbox Script”,忽略该文件的断点。
*条件断点:在行号上右键设置。 - Puppeteer/Playwright:自动化浏览器,配合
--auto-open-devtools-for-tabs参数调试。
9. 总结
JS逆向是连接前端分析与后端漏洞挖掘的桥梁。掌握开发者工具的使用,特别是六种断点的灵活运用和调用堆栈的分析,是解开前端黑盒的关键。从网络请求入手,顺藤摸瓜找到加密逻辑,再通过断点调试还原算法,最终将成果应用到渗透测试中。
同时,反调试技术是JS逆向中的一道门槛,但并非不可逾越。掌握常见的反调试原理及其绕过方法,可以帮助你在渗透测试中顺利突破前端限制,深入分析加密逻辑。
核心目标:获取签名算法、提取加密参数,从而更有效地进行漏洞挖掘(如越权、注入、爆破等)。希望本笔记能成为你工具箱中实用的一页。
