1. 项目概述:当AI遇上前端加密逆向
最近在搞Web安全测试,特别是渗透测试和漏洞挖掘时,前端加密算法这块硬骨头真是让人又爱又恨。爱的是,它往往是核心业务逻辑的保护壳,一旦突破,价值巨大;恨的是,面对那些经过混淆、压缩、甚至自定义的JavaScript加密函数,手动逆向分析耗时耗力,效率极低。一个登录接口的加密参数,可能就得花上半天甚至更久去跟代码、下断点、分析逻辑。
于是,一个想法自然就冒出来了:能不能让AI来干这个活?不是那种简单的脚本辅助,而是真正实现一个智能化的、端到端的自动化逆向分析流程。这个项目,就是围绕“AI自动化实现前端加密算法逆向分析”展开的一次深度探索。它的核心目标,是利用人工智能技术,特别是自然语言处理(NLP)和程序分析(Program Analysis)的能力,自动识别、理解并逆向出前端JavaScript代码中的加密算法逻辑,最终生成可复用的解密函数或关键参数提取规则。
这不仅仅是写个爬虫抓个包那么简单。它要解决的是从“看到一堆乱码JS”到“清楚知道这个 encryptData 函数如何工作”之间的认知鸿沟。对于安全研究员、渗透测试工程师、甚至前端开发(想了解第三方库或做代码审计)来说,这都是一件能极大提升效率的“利器”。想象一下,把目标网站的登录请求丢给系统,它自动分析出加密方式(比如AES-CBC,密钥是某个动态生成的字符串),并给出对应的Python或Node.js解密代码,这能省下多少喝咖啡(其实是熬夜)的时间。
2. 核心思路与技术选型
要实现这个目标,我们不能蛮干,得有一套清晰的、分层的技术架构。整个流程可以拆解为几个核心阶段: 代码获取与预处理 、 关键函数定位与提取 、 AI辅助的代码理解与逻辑还原 ,以及最终的 算法复现与验证 。
2.1 整体架构设计
一个健壮的自动化系统,必须考虑鲁棒性和可扩展性。我设计的核心流程如下:
2.2 为什么选择Playwright + AI模型?
在工具选型上,我经过了多轮对比和实测。
浏览器自动化方面 ,早期考虑过Selenium,但其对现代Web应用(尤其是大量使用Shadow DOM、复杂事件监听的应用)的支持和调试能力不如Playwright和Puppeteer。Puppeteer只支持Chromium系,而Playwright支持Chromium、Firefox、WebKit三大引擎,对于需要应对不同环境或检测浏览器特异性代码的场景更有优势。更重要的是,Playwright的 网络监听( page.on(\’request\’) ) 和 执行上下文追踪( page.evaluateOnNewDocument 结合 console.trace 注入) 功能非常强大,能精准地捕获请求发起时刻的调用栈,这是逆向定位加密函数的关键。
AI模型方面 ,这是项目的灵魂。纯粹的规则匹配(如搜索 CryptoJS 、 encrypt 等关键词)太脆弱,无法应对混淆、重命名或自定义实现。我们需要一个能“理解”代码语义的模型。有几种路径:
- 基于预训练代码模型微调 :这是目前最可行的方案。像CodeBERT、CodeT5、或更强大的开源模型如StarCoder、DeepSeek-Coder,它们在海量代码上预训练,对编程语言的语法、语义有深刻理解。我们可以收集一个高质量的前端加密代码数据集(包括常见库使用和自定义实现),对模型进行微调,让它学会识别加密模式。例如,输入一段代码,让它输出结构化标签: {\”algorithm\”: \”AES-CBC\”, \”key_source\”: \”window._globalKey\”, \”iv\”: \”fixed_string_12345678\”, \”padding\”: \”PKCS7\”} 。
- 大语言模型(LLM)提示工程 :直接使用GPT-4、Claude-3或开源的Llama 3等模型,通过精心设计的提示词(Prompt)让其分析代码。优点是无需训练,灵活性强。缺点是对长代码上下文有限制、分析深度可能不足、每次调用有成本且速度慢,不适合全自动化流水线。它可以作为辅助或对疑难代码进行“专家会诊”。
- 符号执行与动态分析 :这是更传统但强大的程序分析技术。通过构建代码的抽象语法树(AST),进行数据流分析,追踪密钥、明文等敏感数据的传递路径。这种方法非常精确,但实现复杂,对混淆代码的抗性较弱,且容易遇到路径爆炸问题。
综合考虑开发周期、效果和可落地性,我选择了 “微调专用代码模型”为主,“LLM提示工程”为辅 的混合策略。核心的、常见的模式由专用模型快速、准确地识别;遇到极其复杂或新颖的混淆,再调用LLM进行深度推理。
注意 :微调模型需要高质量的数据集。我们可以从公开的CTF题目、GitHub上的前端加密示例、以及自己构造的样本中获取。数据需要清洗、去重,并打好精细的标签。这是一个费时但至关重要的基础工作。
3. 核心模块实现细节
3.1 动态捕获与代码关联
这是整个系统的“眼睛”。目标是:当用户在页面上点击登录时,不仅能抓到加密后的请求体,还要知道是哪个JS函数生成了它。
import asyncio
from playwright.async_api import async_playwright
async def capture_encrypted_request(url, action_selector):
\”\”\”
捕获目标动作触发的加密请求及其调用栈。
:param url: 目标页面URL
:param action_selector: 触发加密操作的按钮选择器,如 \’#login-btn\’
\”\”\”
async with async_playwright() as p:
# 使用Chromium,可配置为 headless=False 便于调试
browser = await p.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()
# 关键:监听所有请求
target_request = None
target_stack = None
def on_request(request):
nonlocal target_request, target_stack
# 筛选感兴趣的请求,例如包含特定路径或方法
if \’/api/login\’ in request.url and request.method == \’POST\’:
target_request = request
# 尝试从请求初始化信息中获取堆栈(需配合注入脚本)
# 这里是一个简化示

