爬虫逆向之雷池waf
本文章中所有内容仅供学习交流使用,不用于其他任何目的。否则由此产生的一切后果均与作者无关!
雷池waf概念
雷池 WAF(SafeLine)是长亭科技开源的一款 Web 应用防火墙,部署在网站前面,把所有进来的 HTTP/HTTPS 流量先过一遍“安检”,再决定是否放行。
作用:
雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 SQL 注入
、XSS
、 代码注入
、命令注入
、CRLF 注入
、ldap 注入
、xpath 注入
、RCE
、XXE
、SSRF
、路径遍历
、后门
、暴力破解
、CC
、爬虫
等攻击。
一句话总结:雷池 WAF = 免费 + 一键安装 + 企业级 Web 安全防护,适合个人站、中小企业以及需要私有化部署的场景。免费使用。
这是官方文档:雷池 WAF | 下一代 Web 应用防火墙 | 免费使用
逆向目标:aHR0cHM6Ly93d3cuZ2RzZ2ouY29tL25vdGljZS8=
浏览器DevTool控制台检测
当清除cookies后,重新抓包会被检测到
并且控制台会被无限清除
自动化工具检测:
playwright测试
需要点击,模拟点击试一次
直接报当前环境被调试
selenium测试
同上
drissionpage测试
可以绕过检测
如何绕过控制台检测
打开脚本断点进行调试
到challenge.js到这里有判断是不是机器人的检测,分数越高,越像机器人,越容易被检测到。
从v函数进去,里面有多个检测点
一共有四十四个检测点,检测环境、控制台、自动化的。
像以下这些点就是检测自动化的
被检测到直接满分毕业,测试一下打开自动化,分数是多少
220分,太像机器人了。
逆向思路
那如何绕过反调试,并获取正常cookies,利用协议去请求呢?
这个值是我们要得出的
第一步:
直接源头注释替换文件,方便调试
第二步,第一次请求,请求首页获取issue_id值和sl-session
第一次报468
第三步:第二次请求,请求 issue
接口
issue_id值是第一次请求页面得内容
请求获取这两个重要的值
第四步,第三次请求,求verify接口
需要分析三个参数
issue_id参数由 issue
接口返回
visitorId 设备指纹
result 由issue返回参数在经过一系列加工返回
跟栈
这个文件是临时生成得文件
blob
重新刷新进入断点会消失
发现用来wasm模块加密
如何调用wasm模块,请看这一篇文章JS逆向之Wasm逆向过程-CSDN博客,有兴趣可以借助可以借助ai去分析成python代码或者js代码。以下是JS代码调用,python借助subprocess库去获取值
const fs = require('fs');
const wasmCode = fs.readFileSync('7cfa74f2.wasm');// const deasync = require('deasync');function aa(e) {e =JSON.parse(e)WebAssembly.instantiate(wasmCode, {"env": {},"wasi_snapshot_preview1": {}}).then(result => {const instance = result.instance;const reset = instance.exports.resetconst arg = instance.exports.argconst calc = instance.exports.calcconst ret = instance.exports.retaaaa = function() {return reset(),e.map(function(e) {return arg(e)}),Array(calc()).fill(-1).map(function() {return ret()})}()console.log(JSON.stringify(aaaa))})}
// aa([1,2,3,4,5,6,7,8,9])aa(process.argv[2])
python核心代码,记住,传入的字符串列表,在调用JS时强转为数组
result = subprocess.run(["node", "123.js",str(response.json()['data']['data'])], capture_output=True, text=True).stdout.strip()
顺利出值
接下来就算最后一个参数visitorId值
直接搜索参数
进入i.load()
发现就是个指纹库创建得,直接生成设备指纹
const Fingerprint2 = require('fingerprintjs2');
Fingerprint2.get(components => {
const values = components.map(component => component.value);
const murmur = Fingerprint2.x64hash128(values.join(''), 31);
console.log(murmur);
});
稍微整理,核心代码
const fs = require('fs');
const wasmCode = fs.readFileSync('7cfa74f2.wasm');// const deasync = require('deasync');const Fingerprint2 = require('fingerprintjs2');
Fingerprint2.get(components => {
const values = components.map(component => component.value);
const murmur = Fingerprint2.x64hash128(values.join(''), 31);
console.log(murmur);
});
function aa(e) {e =JSON.parse(e)WebAssembly.instantiate(wasmCode, {"env": {},"wasi_snapshot_preview1": {}}).then(result => {const instance = result.instance;const reset = instance.exports.resetconst arg = instance.exports.argconst calc = instance.exports.calcconst ret = instance.exports.retaaaa = function() {return reset(),e.map(function(e) {return arg(e)}),Array(calc()).fill(-1).map(function() {return ret()})}()console.log(JSON.stringify(aaaa))})}
// aa([1,2,3,4,5,6,7,8,9])aa(process.argv[2])
subprocess获取的值是字符串,强转类型
result = subprocess.run(["node", "123.js",str(response.json()['data']['data'])], capture_output=True, text=True).stdout.strip()
visitorId = result.split('\n')[0]
result = json.loads(result.split('\n')[1])
data = {"issue_id": response.json()['data']['issue_id'],"result":result,"serials": [],"client": {"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36","platform": "Win32","language": "zh-CN,zh","vendor": "Google Inc.","screen": [1920,1080],"visitorId": visitorId,"score": 100,"target": ["27"]}
}
顺利得出
第四次请求携带cookies顺利获取数据
cookies={"sl-challenge-jwt": response.json()['data']['jwt']}
总结:
绕过雷池到获取数据一共需要四次请求
第一次请求首页。状态码468,获取issue_id
第二次请求issue接口,data携带issue_id ,获取issue_id和列表
第三次请求issue接口,data携带issue_id,JS逆向跟栈调用wasm传入列表作为参数获取result,visitorId为设备指纹,通过fingerprintjs2获取即可。获取jwt参数也就是cookie键sl_jwt_session的值
第四次携带cookie成功获取数据