最近在进行某网站的JavaScript逆向分析时,我遇到了一个有趣的现象:当我尝试定位一个名为m
的加密参数(值为MTIwMTE3NDQxODk1NTY1NjkA
这样的Base64字符串)时,调试器却带我来到了一个看似无关的事件处理配置对象。这促使我深入研究了JavaScript逆向工程中精准定位加密参数的技巧,今天就将这些经验完整分享给大家。
在逆向过程中,我们经常会遇到这样的情况:
期望找到加密参数m
的生成逻辑
实际定位到的却是类似下面的代码:
{ "global": {}, "special": { "load": {"noBubble": true}, "focus": {"delegateType": "focusin"} // 其他事件配置... } }
变量名冲突:m
作为短变量名在多个上下文中使用
执行时机错位:加密代码可能在事件触发后才执行
作用域污染:原型链或闭包中的同名变量干扰
工具类型 | 推荐工具 | 用途说明 |
---|---|---|
浏览器工具 | Chrome DevTools | 核心调试工具 |
抓包工具 | Fiddler/Charles | 网络请求分析 |
反混淆工具 | Babel AST Explorer | 解析混淆代码 |
Hook框架 | Tampermonkey | 动态注入调试代码 |
使用开发者工具的Network面板
筛选XHR/Fetch请求
找到包含目标参数的请求
技巧:右键请求 → Copy → Copy as cURL,可完整复现请求
// 在控制台注入调用栈追踪代码 function traceParam(paramName) { const originalSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(body) { if(body.includes(paramName)) { console.trace(`发现参数 ${paramName}`); debugger; } return originalSend.call(this, body); }; } traceParam('m');
常见加密特征正则表达式:
// Base64特征 /(btoa\(|atob\(|Buffer\.from\(|['"]\w{20,}['"]:\s*function\([^)]*\)\s*{)/ // 哈希特征 /(createHash\(|update\(|digest\(|md5|sha1|sha256)/ // 对称加密 /(CryptoJS\.AES|aes-\d{3}-cbc|enc\.Utf8|enc\.Base64)/
// 监控特定对象属性变化 const target = {}; Object.defineProperty(target, 'm', { set: function(value) { console.log('m被设置为:', value); debugger; return value; } });
参数格式 | 可能算法 | 识别特征 |
---|---|---|
m=MTIwMTE3... |
Base64编码 | 结尾可能有=或A |
sign=7a3256ab... |
MD5/HMAC | 32/64位十六进制 |
_token=eyJhbGci... |
JWT | 三段式点分隔 |
data=U2FsdGVk... |
AES加密 | 开头常见"Salted" |
以Base64参数MTIwMTE3NDQxODk1NTY1NjkA
为例:
// 解码测试 const decoded = atob("MTIwMTE3NDQxODk1NTY1NjkA"); console.log(decoded); // 可能输出:"1201174418956569\x00" // 逆向分析: // 1. 可能是时间戳(1201174418) + 随机数(956569) // 2. 末尾\x00是填充字符
// 绕过常见的反调试检测 window._devtools = undefined; Object.defineProperty(window, 'chrome', { get: () => undefined }); // 禁用debugger语句 const _debugger = Function.prototype.constructor; Function.prototype.constructor = function() { if(!arguments[0].includes('debugger')) { return _debugger.apply(this, arguments); } };
// Tampermonkey自动化Hook脚本 (function() { 'use strict'; // Hook所有加密函数 const cryptoPatterns = [ 'encrypt', 'encode', 'sign', 'md5', 'aes', 'hash' ]; cryptoPatterns.forEach(pattern => { const orig = window[pattern]; if(orig) { window[pattern] = function() { console.group(`加密函数 ${pattern} 被调用`); console.log('参数:', arguments); console.trace(); console.groupEnd(); debugger; return orig.apply(this, arguments); }; } }); })();
现象:
每个请求都有_sign
参数
参数值每次请求都不同
逆向过程:
发现参数生成在utils.js
中
核心逻辑如下:
function generateSign(params) { const secret = "d3d9446802a44259"; const sorted = Object.keys(params).sort(); let signStr = sorted.map(k => `${k}=${params[k]}`).join('&'); return CryptoJS.MD5(signStr + secret).toString(); }
破解方案:
// 在控制台复现签名算法 function mockSign(params) { // 复制网站的实现逻辑... }
确认目标参数在网络请求中的位置
分析参数值的编码/加密特征
设置精准的条件断点
验证参数生成算法的可复现性
书籍:《JavaScript逆向工程实战》
工具:AST Explorer(分析代码结构)
社区:看雪学院、GitHub逆向项目
重要提示:本文所有技术仅限合法合规的技术研究,请遵守相关法律法规和网站的使用条款。
通过系统化的方法和工具链,我们可以高效准确地定位JavaScript中的加密参数生成位置。记住,逆向工程就像侦探破案,需要耐心、细致的观察和科学的分析方法。希望这篇指南能为您的逆向工程之旅提供实质性的帮助!