qq1063823095 发表于 2024-4-3 16:39:00

【高难度】如何将脚本注入到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可以看到是一样的)

李恒道 发表于 2024-4-3 20:04:15

没账号进不去

不过感觉你这个可能更像没加run-at导致没提前注入上

qq1063823095 发表于 2024-4-3 23:07:11

李恒道 发表于 2024-4-3 20:04
没账号进不去

不过感觉你这个可能更像没加run-at导致没提前注入上

注入到首页了,也有相应的拦截数据,只不过在“YCIy5nf-CXdG.js”文件的“DedicatedWorkerGlobalScope”作用域下没有注入成功,并且打印了对应window,和全局的window不一样,这里就涉及到了Worker的东西了(我就不太清楚了)

qq1063823095 发表于 2024-4-4 00:54:33

盲猜一下应该要hook原生的Worker函数,然后通过注入特定代码来实现劫持,不过检索了一下许多hook库,貌似都没有hook Worker相关的功能

李恒道 发表于 2024-4-4 01:04:23

改了下例子,目前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>

```

cxxjackie 发表于 2024-4-4 23:47:58

劫持Worker,读取文件内容为字符串,再通过拼接/替换字符串来实现请求的劫持,然后生成blob,再URL.createObjectURL生成一个blob链接,最后调用原Worker来实例化。实现起来还挺复杂的,可能需要用到同步xhr来读取文件(因为实例化过程是同步的)。

steven026 发表于 2024-4-5 00:52:20

劫持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]
查看完整版本: 【高难度】如何将脚本注入到DedicatedWorkerGlobalScope作用域中?