一、前置知识:理解JS逆向的基础
在学习断点调试前,需先掌握两个核心概念,这是读懂加密流程的关键:
1. 作用域
-
定义:变量的"生命周期",即变量可被访问的范围;
-
分类:
- 全局作用域:变量可在任意JS文件/函数中调用(如window对象下的变量);
- 局部作用域:变量仅能在当前函数/代码块中调用(如函数内声明的var/let/const变量);
-
逆向意义:加密函数若为局部作用域,直接在控制台调用会提示"未定义",需在断点暂停时(作用域生效)调用,或手动声明实例后复用。
2. 调用堆栈
- 定义:代码执行的"顺序记录",本质是函数调用的层级关系(栈结构:先进后出,显示顺序从下到上为执行顺序);
- 逆向意义:通过调用堆栈可"回溯加密流程"------若当前断点处数据已加密,向上查看堆栈的前序函数,即可找到加密函数的调用位置。
3. JS前端加密的核心流程
前端加密的本质是"数据提交前通过JS处理,再传给后端解密验证",典型流程:
- 用户输入账号/密码(原始数据);
- JS加密函数对原始数据处理(如RSA、AES加密);
- 加密后的数据通过AJAX/fetch发送给后端;
- 后端用对应算法解密,验证数据合法性。
4. 学习意义与应用场景
-
为什么学?:前端加密是攻防常见场景,掌握调试技巧可:
- 破解加密逻辑,实现密码枚举爆破;
- 发现AJAX泄露的后端接口,扩大测试范围;
- 检测参数提交过程中的漏洞(如加密逻辑可被绕过);
-
如何发现?:通过"全局搜索关键字"(如参数名、加密函数名)定位加密代码,再用断点调试追溯流程。
二、核心断点调试技巧(原理+案例)
技巧1:全局搜索+流程断点(最常用)
(1)原理
通过"全局搜索提交参数名(如username/password)、加密相关关键字(如encrypt/encode)"定位核心代码,在可疑函数(如登录函数Login)中设置断点,结合"作用域"和"调用堆栈"追溯加密流程。
(2)案例演示(ST快递会员登录)
- 抓包观察加密现象:
- 随意输入手机号/密码,点击登录,F12打开"网络"面板,找到登录请求;
- 发现username/password参数已被加密,无法直接识别加密方式。
- 全局搜索定位核心代码:
- 切换到"源代码"面板,按Ctrl+F全局搜索关键字(如Login/encrypt);
- 找到登录函数Login(),在函数内的AJAX提交代码处设置断点(点击代码行号左侧,出现蓝色箭头)。
- 断点调试追溯加密流程:
-
再次点击登录,程序暂停在断点处;
-
查看右侧"作用域"面板:发现username/password已加密,说明加密函数在当前断点前被调用;
-
查看"调用堆栈"面板(从下往上为执行顺序),追溯前序函数,发现加密逻辑就在Login()函数内部:
// Login函数内的加密逻辑 var username = encrypt($("#username").val()); // 加密后赋值 var password = encrypt($("#password").val()); var data = "username=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password);
- 复用加密函数:
-
鼠标悬浮在encrypt函数上,查看其定义文件,点击进入函数原型;
-
发现加密方式为JSEncrypt(RSA加密),且encrypt是局部函数:
-
直接在控制台调用encrypt("123456")会提示"未定义";
-
解决方案1:断点暂停时调用(此时作用域生效,可直接复用);
-
解决方案2:手动声明JSEncrypt实例后调用:
var r = new JSEncrypt(); // 声明实例 r.setPublicKey("公钥内容"); // 从作用域中获取公钥 r.encrypt("123456"); // 成功加密
-
-
注意:RSA加密为非对称加密,每次加密结果不同,但均可被后端私钥解密。
技巧2:标签断点(适配DOM更新场景)
(1)原理
对指定HTML标签设置断点,当标签发生"子树修改"(如插入隐藏域)或"属性修改"(如按钮变灰、显示loading)时,程序暂停。
- 适用条件:加密动作需伴随前端DOM更新(否则无法触发断点)。
(2)案例演示(edu登录站点)
- 定位目标标签:
- F12打开"元素"面板,找到登录按钮对应的HTML标签(如<button id="loginBtn">登录</button>);
- 右键标签,选择"断点"→"子树修改"和"属性修改"(同时开启,提高触发概率)。
- 触发断点并追溯:
- 输入账号/密码,点击登录,程序暂停在标签变化的触发代码处;
- 查看右侧"调用堆栈",向上追溯函数,寻找包含加密逻辑的代码;
- 注意:若加密过程不伴随DOM更新,标签断点无法触发,需换用其他方式。
技巧3:XHR断点(数据发送前暂停)
(1)原理
在XMLHttpRequest.send或fetch函数执行前暂停程序,即"数据发送的最后一刻"暂停,此时可查看加密后的数据和加密流程的前置函数。
- 适用场景:找不到加密函数时,直接拦截数据发送过程,逆向追溯加密逻辑。
(2)案例演示(edu登录站点)
- 设置XHR断点:
- F12切换到"源代码"面板,找到"XHR/提取"标签,点击"添加断点";
- 输入登录请求的路径(如user/login,支持模糊匹配),点击确定。
- 触发断点并定位加密逻辑:
-
点击登录,程序暂停在fetch/send函数调用处;
-
查看右侧"调用堆栈",向上追溯前序函数(如value函数);
-
在value函数中查看"作用域":发现原始密码(如admin123)和加密后的密码(如s变量),同时找到加密逻辑:
a = n.pwdInput.value; // 原始密码 var r = new JSEncrypt, o = C.RSACODE; // 声明JSEncrypt实例,获取公钥 r.setPublicKey(o); // 设置公钥 var s = r.encrypt(a); // 加密原始密码
- 复用加密逻辑:从作用域中复制公钥o,在控制台声明实例后调用加密函数,即可复用加密逻辑。
三、实战落地:结合BurpSuite实现批量爆破
掌握加密逻辑后,需批量复用加密函数实现爆破,核心思路:"复用加密函数→结合BurpSuite插件自动化加密→批量发包"。
(1)前置准备
- 工具依赖:
- phantomjs:用于执行JS加密函数(需安装并配置环境变量,或直接放在bin目录);
- BurpSuite插件JsEncrypter:用于调用phantomjs执行加密逻辑。
- 提取加密函数与公钥:
- 从断点调试中提取加密函数(如JSEncrypt相关代码),保存为JSEncrypt.js;
- 从作用域中复制公钥(如RSA公钥字符串)。
(2)配置步骤
- 本地编写加密脚本:
-
在phantomjs的bin目录下创建phantomjs_server.js,编写加密逻辑:
// 引入加密函数文件 phantom.injectJs("JSEncrypt.js"); // 自定义加密函数(复用从案例中提取的逻辑) function new_encrypt(payload) { var r = new JSEncrypt, o = "305c300d06092a864886f70d0101010500034b003048024100959684a0076fd2a8fc1589469cf8c95f16ef67490c519f4d274373f29cee64cf6a0db8ad8953122c5b3664e4a48acd34d9b95c0ae62a31be612632e1c49154db0203010001"; r.setPublicKey(o); var newpayload = r.encrypt(payload); return newpayload; } // 插件调用的处理函数 function js_encrypt(payload){ var newpayload = new_encrypt(payload); return newpayload; }
- 启动phantomjs服务:
-
打开命令行,进入phantomjs的bin目录,执行:
phantomjs --ssl-protocol=any --web-security=no phantomjs_server.js
- BurpSuite配置插件:
- 安装JsEncrypter插件,点击"Connect"连接服务(返回true表示成功);
- 测试加密:输入原始字符串(如123456),点击"Test",验证加密结果正确。
(3)实战爆破
- 抓包并发送到Intruder:
- 在BurpSuite中抓登录请求,右键发送到"Intruder"模块;
- 标记需要爆破的参数(如password对应的加密字段)。
- 配置Payload处理:
- 切换到"Payloads"面板,导入密码字典;
- 点击"Payload Processing"→"Add",选择"Invoke Burp Extension",选中JsEncrypter插件;
- 点击"Start Attack"开始爆破,插件会自动将字典中的原始密码加密后发送。
三、核心总结
- 断点技巧选型:
- 优先用"全局搜索+流程断点":适用大多数加密场景,高效定位加密函数;
- 标签断点:仅适用于"加密伴随DOM更新"的场景(如按钮变灰、加载动画);
- XHR断点:找不到加密函数时,拦截数据发送前一刻,逆向追溯流程。
- 核心思路:定位加密函数→追溯加密流程(调用堆栈)→复用加密逻辑(控制台/本地脚本)→批量应用(BurpSuite插件)。
- 关键细节:
- 局部作用域的加密函数需在断点生效时调用,或手动声明实例;
- RSA加密每次结果不同,但均可解密,无需担心结果不一致;
- 实战中爆破需注意频率控制,避免触发防护机制。
学习本讲的核心是"多练",建议复现案例中的两个登录站点,熟练掌握三种断点的设置和调用堆栈的追溯,才能应对不同的JS加密场景。如果复现过程中遇到"断点不触发""加密函数调用失败",可优先检查:断点位置是否正确、作用域是否生效、公钥/加密函数是否完整。