JS 逆向在渗透测试中的 1-4 级实战应用:从信息收集到算法破解

JS逆向在渗透测试中的1-4级实战应用
我把JS逆向技术分成了5级,本文主要介绍1-4级的应用,第5级为自动化攻击链构建,在这里写的话就篇幅过长了,所以放在下一个文章中。
一、1级:JS文件定位与基础分析
1.1 关键JS文件挖掘技巧
流量监控与抓包使用Burp Suite的Proxy模块拦截HTTP请求,通过
XHR/fetch
过滤定位动态加载的JS文件。# 在Burp Repeater中重放请求并分析响应头 GET /static/js/encrypt.js HTTP/1.1 Host: target.com
URL路径特征分析常见敏感路径模式(一个JS案例):
/api/signature.js // 签名逻辑 /utils/crypto.js // 加密工具 /auth/verify.js // 认证验证
<!doctype html> <html lang="zh"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="Cache-Control" content="no-cache" /> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> <meta name="apple-mobile-web-app-capable" content="yes"> <style> * { touch-action: pan-y; /* 签名的时候滑动会报错,使用全局样式样式去掉 */ } </style> </head> <body> <div class="htmleaf-container"> <div class="container"> <div class="row"> <div class="col-xs-12"> <p>请签名:</p> <div class="js-signature"></div> <p> <button id="saveBtn" class="btn btn-default" disabled>预览</button> <button id="clearBtn" class="btn btn-default" >重写</button> <input type="file" id="imgTest" type="file" onchange="imgChange(event)" accept=".gif,.jpg,.jpeg,.png"> </p> <div id="signature"> <p>写上签名并点击预览</p> <div></div> </div> </div> </div> </div> </div> <script src="https://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script> <script src="./js/jq-signature.js"></script> <script type="text/javascript"> $(document).on('ready', function() { if ($('.js-signature').length) { var _width = 600; var _height = 200; var rate = 0; if(screen.width<_width){ rate = _width/screen.width; _width = _width/rate - 15; _height = _height/rate ; } $('.js-signature').jqSignature({autoFit: false,width:_width,height: _height}); } $('.js-signature').on('jq.signature.changed', function() { $('#saveBtn').attr('disabled', false); }); $('#clearBtn').on('click',function(){ $('#signature').html('<p>写上签名并点击预览</p><div></div>'); $('.js-signature').jqSignature('clearCanvas'); $('#saveBtn').attr('disabled', true); }) $('#saveBtn').on('click',function(){ var dataUrl = $('.js-signature').jqSignature('getDataURL'); console.debug(dataUrl); var img = $('<img>').attr('src', dataUrl); $('#signature p').html($('<p>').text("签名预览如下:")); $('#signature div').html(img); }) }); function imgChange(e) { console.info(e.target.files[0]);//图片文件 var dom =$("input[id^='imgTest']")[0]; console.info(dom.value); console.log(e.target.value); var reader = new FileReader(); reader.onload = (function (file) { return function (e) { var img = $('<img>').attr('src',this.result); $('#signature div').html(img); $('.js-signature').jqSignature('setData',this.result); $('#saveBtn').attr('disabled', false); }; })(e.target.files[0]); reader.readAsDataURL(e.target.files[0]); } </script> </body> </html>
案例:电商平台登录加密分析在Network面板中发现login.js
加载后,password
参数由明文变为哈希值:
// 原始请求
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=admin&password=123
// 加密后请求
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=admin&password=21232f297a57a5a743894a0e4a801fc3
1.2 敏感信息提取技术
字符串搜索工具链
# 使用Python提取JS中的Base64字符串 grep -oP '(?<=btoa\().*?(?=\))' *.js | base64 -d
正则表达式实战匹配可能的加密函数:
import re
pattern = re.compile(r'(aesEncrypt|rsaSign|md5Hash)\s*\(')
with open('main.js', 'r') as f:
matches = pattern.findall(f.read())
print(matches) # 输出所有加密函数名
二、2级:基础混淆与字符串解密
2.1 自动化去混淆工具链
de4js高级用法
# 递归处理多层混淆并生成可读性代码 de4js -r -m -o clean/ obfuscated/
手动修复技巧处理eval
包裹的Base64字符串:
// 混淆代码
eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%6c%6f%63%61%74%69%6f%6e%3d%22%68%74%74%70%73%3a%2f%2f%65%78%61%6d%70%6c%65%2e%63%6f%6d%22'));
// 修复后
document.location = "https://example.com";
2.2 字符串加密破解实战
多层嵌套解密脚本
import base64 import urllib.parse encrypted = "JUUyJTg1JThGJUUzJTlDJThGJUU0JUJEJTlG" decoded = base64.b64decode(encrypted).decode('utf-8') decoded = urllib.parse.unquote(decoded) print(decoded) # 输出原始字符串
案例:CMS后台XSS漏洞利用破解eval(unescape(...))
包裹的恶意脚本:
// 混淆代码
eval(unescape('%77%69%6e%64%6f%77%2e%61%6c%65%72%74%28%27%58%53%53%27%29'));
// 修复后
window.alert('XSS');
三、3级:动态调试与反反爬对抗
3.1 调试器绕过技术
反调试检测绕过
// 禁用debugger语句 (function () { var oldDebugger = window.debugger; window.debugger = function () { // 空实现 }; })(); // 绕过setInterval检测 var oldSetInterval = window.setInterval; window.setInterval = function (fn, delay) { return oldSetInterval(fn, delay + 1000); };
内存数据抽取工具使用Chrome DevTools的
Memory
面板查找aesKey
变量:
录制内存快照 → 2. 搜索关键词 → 3. 右键"Reveal in Sources"
3.2 动态加载JS分析
WebSocket监听实战
// 在控制台注入代码监听WebSocket消息 var oldWebSocket = WebSocket; WebSocket = function (url) { this.ws = new oldWebSocket(url); this.ws.onmessage = function (e) { console.log('WebSocket Message:', e.data); }; };
案例:某金融平台风控逻辑逆向通过Hookwindow.WebSocket
方法,捕获动态加载的风控JS文件:
var originalOpen = WebSocket.prototype.open;
WebSocket.prototype.open = function (url) {
if (url.includes('risk.js')) {
console.log('发现风控JS:', url);
}
originalOpen.apply(this, arguments);
};
四、4级:加密算法逆向与复现
4.1 对称加密逆向实战
AES-CBC模式破解
通过console.log
注入获取密钥和IV:
console.log('aesKey:', window.aesKey);
console.log('iv:', window.iv);
Python复现解密逻辑:
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)
4.2 非对称加密破解案例
RSA公私钥提取在JS文件中搜索
setPublicKey
和setPrivateKey
:
var publicKey = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...';
var privateKey = '-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSj...';
- Python模拟加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
key = RSA.importKey(publicKey)
cipher = PKCS1_v1_5.new(key)
encrypted = cipher.encrypt(b'password')
五、实战案例:从抓包到漏洞利用
5.1 漏洞挖掘流程
抓包分析:发现某SaaS平台API请求含
sign
参数GET /api/data?token=abc123&sign=456 HTTP/1.1
JS逆向:定位到
sign
由md5(token+timestamp+secret)
生成密钥泄露:通过内存快照获取
window.secret = 'secure_key'
- 漏洞利用:构造恶意请求访问敏感数据
5.2 自动化脚本开发
import requests
import hashlib
import time
def generate_sign(token, secret):
timestamp = str(int(time.time()))
raw = f"{token}{timestamp}{secret}"
return hashlib.md5(raw.encode()).hexdigest()
# 构造恶意请求
token = 'admin_token'
secret = 'secure_key'
sign = generate_sign(token, secret)
url = f"https://target.com/api/data?token={token}&sign={sign}"
response = requests.get(url)
print(response.json()) # 输出敏感数据
六、总结与延伸
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
文章目录