【高难度】如何将脚本注入到DedicatedWorkerGlobalScope作用域中?
本帖最后由 qq1063823095 于 2024-4-4 00:32 编辑> 本帖最后由 qq1063823095 于 2024-4-4 00:25 编辑
需求:
想劫持其中一个叫做“d365”的请求上的参数,但是调试了半天发现,好家伙,这个请求不是从主页上面发起的请求,是一个叫做“YCIy5nf-CXdG.js”文件中发起的。
更加离谱的是,这个请求发起的地方,不在window的作用域,而是叫一个DedicatedWorkerGlobalScope作用域
脚本中引入了ajaxhook,首页的请求都可以拦截到,就是"d365"这个请求拦截不到
bing查了很久,加上GPT问了半天,没搞懂Worker这个东西,有知道的大佬破局吗?
脚本注入的网页地址为 Azure的存储账户中的存储浏览器(如图)(隐私信息已打码)
!(data/attachment/forum/202404/03/163236oyj7e7f9xjjwbxnm.png)
附上调试过程(隐私信息已打码):
!(data/attachment/forum/202404/03/163556ptkpfdf2dpdufjuz.png)
附上脚本(部分)(代码中使用了 grant none 让其注入到全局window):
```
// ==UserScript==
// @match *://portal.azure.cn/*
// @match https://hosting.azureportal.chinacloudapi.cn/*
// @match https://b2ccrminterfacesaprd.blob.core.chinacloudapi.cn/*
// @require https://unpkg.com/ajax-hook@3.0.3/dist/ajaxhook.js
// @grant GM_cookie
// @grant none
// @connect chinacloudsites.cn
// @connect portal.azure.cn
// ==/UserScript==
(function () {
// 'use strict';
HookFetch();
window.aaa = 111;
function HookFetch() {
ah.proxy({
//请求发起前进入
onRequest: (config, handler) => {
console.log(config.url);
handler.next(config);
},
//请求发生错误时进入,比如超时;注意,不包括http状态码错误,如404仍然会认为请求成功
onError: (err, handler) => {
console.log(err.type);
handler.next(err);
},
//请求成功后进入
onResponse: (response, handler) => {
// console.log(response.response)
handler.next(response);
},
});
}
})();
```
***
2024-4-4 00:18:39 更新(补充实例代码,就是模拟了原网页的一个demo)
index.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.8.0/jquery-1.8.0.js"></script>
</head>
<body></body>
</html>
<script>
// 实例化一个Web Worker
var worker = new Worker("./worker.js");
worker.postMessage({
url: "http://example.com/api",
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
// 这里发起一次ajax请求
$.ajax({
url: "/?name=index.html",
type: "Get",
});
</script>
```
worker.js
```javascript
self.onmessage = function (event) {
// 这里发起一次http请求
var xhr = new XMLHttpRequest();
xhr.open('GET', '/?name=worker', true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
self.postMessage(xhr.responseText);
}
};
xhr.send();
};
```
脚本(和原来没变化,只加入了run-at)
```javascript
// ==UserScript==
// @name hook web worker
// @namespace http://tampermonkey.net/
// @version 2024-04-03
// @descriptiontry to take over the world!
// @author You
// @match *://*/*
// @require https://unpkg.com/ajax-hook@3.0.3/dist/ajaxhook.js
// @grant GM_cookie
// @grant none
// @connect chinacloudsites.cn
// @connect portal.azure.cn
// @run-at document-start
// ==/UserScript==
(function () {
// 'use strict';
HookFetch();
window.aaa = 111;
function HookFetch() {
ah.proxy({
//请求发起前进入
onRequest: (config, handler) => {
console.log(config.url);
handler.next(config);
},
//请求发生错误时进入,比如超时;注意,不包括http状态码错误,如404仍然会认为请求成功
onError: (err, handler) => {
console.log(err.type);
handler.next(err);
},
//请求成功后进入
onResponse: (response, handler) => {
// console.log(response.response)
handler.next(response);
},
});
}
})();
```
运行结果
!(data/attachment/forum/202404/04/002350srpblfthrl5lj5l1.png)
通过上述运行结果看到,还是只有index.html注入成功了,而worker.js中没有注入成功(如果worker.js也注入了的话,控制台会打印name=worker这个请求)
demo和原网页稍微有一点区别的地方在于,Azure中的worker有window对象,demo没有(只有self),不过对象类型是一样的(通过打印self可以看到是一样的) 没账号进不去
不过感觉你这个可能更像没加run-at导致没提前注入上 李恒道 发表于 2024-4-3 20:04
没账号进不去
不过感觉你这个可能更像没加run-at导致没提前注入上
注入到首页了,也有相应的拦截数据,只不过在“YCIy5nf-CXdG.js”文件的“DedicatedWorkerGlobalScope”作用域下没有注入成功,并且打印了对应window,和全局的window不一样,这里就涉及到了Worker的东西了(我就不太清楚了) 盲猜一下应该要hook原生的Worker函数,然后通过注入特定代码来实现劫持,不过检索了一下许多hook库,貌似都没有hook Worker相关的功能 改了下例子,目前Worker封闭性还是比较强的
我利用Worker初始化自己的Js然后通过ImportScript实现的共享作用域
不过由于破坏了原有的引用,所以XHR在你的例子里会失效
但是看你网页截图的代码也是blob
所以如果改掉例子应该是可以实现hook的
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.8.0/jquery-1.8.0.js"></script>
</head>
<body></body>
</html>
<script>
const hookCode = `self.onmessage = function (event) {
const xhrOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function () {
console.log('hook success',this);
return xhrOpen.apply(this, arguments);
};
if (event?.data?.init) {
importScripts(event.data.url);
}
};
`;
const acturalCode = `self.onmessage = function (event) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com/api", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
self.postMessage(xhr.responseText);
}
};
xhr.send();
};
`;
const blob = new Blob(, { type: "application/javascript" });
const acturaclBlob = new Blob(, {
type: "application/javascript",
});
const originWorker = Worker;
window.Worker = function (url) {
const eneity = new originWorker(URL.createObjectURL(blob));
eneity.postMessage({
init: true,
url: url,
});
return eneity;
};
// 实例化一个Web Worker
var worker = new Worker(URL.createObjectURL(acturaclBlob));
worker.postMessage({
url: "http://example.com/api",
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
// 这里发起一次ajax请求
$.ajax({
url: "/?name=index.html",
type: "Get",
});
</script>
``` 劫持Worker,读取文件内容为字符串,再通过拼接/替换字符串来实现请求的劫持,然后生成blob,再URL.createObjectURL生成一个blob链接,最后调用原Worker来实例化。实现起来还挺复杂的,可能需要用到同步xhr来读取文件(因为实例化过程是同步的)。 劫持Worker实例 30~83行
https://greasyfork.org/zh-CN/scripts/454823-%E5%B7%AB%E6%9C%AF%E6%94%BE%E7%BD%AE-idle-mancery-%E5%82%BB%E7%93%9C%E5%BC%8F%E4%BF%AE%E6%94%B9%E8%84%9A%E6%9C%AC/code
页:
[1]