My H1–212 CTF writeup

Dec 5, 2017 · 6 min read

Hello everyone,

This is my writeup for H1–212 CTF. Hope you guys like it.

It all started when hackerone blogged about their CTF and I got so excited and fired up my laptop.
One thing Jobert told in the slack channel was to read his tweet carefully. So that’s what I did.
The blog post clearly said-

An engineer of launched a new server for a new admin panel at
He is completely confident that the server can’t be hacked.
He added a tripwire that notifies him when the flag file is read.
He also noticed that the default Apache page is still there, but according to him that’s intentional and doesn’t hurt anyone.
Your goal? Read the flag!

Visiting would give a default apache page. Now this is nothing new when you’re targetting huge scoped programs when it comes to bug bounties.
Going through the source code didn’t return anything useful.
Now, reading the blogpost again, you will see that the engineer is actually a member of but visiting doesn’t return anything. So the most obvious conclusion here is that could be one of the virtual hosts of
So I fired up virtual-host-discovery and ran ruby scan.rb — ip= — | grep and got the following output-

Looking at the blog post once again, An engineer of launched a new server for a new *admin* panel Hence ** was the obvious way to go.
On visiting we are presented with an empty screen and looking at the source code won’t give any information.

Firing up burp, we can see a request like this-

The most interesting paramter here is admin=no and every hacker’s goal is to be admin. So on sending it to repeater I changed it to admin=yes and I got a 405 Method Not Allowed.
On Trying different HTTP verbs, I got the same error except POST. POST returned a 406 Not Acceptable which was different from what the other verbs returned and hence caught my attention.
On googling what that error is for, I immediately stumbled on this stackoverflow thread
The solution here was to add a Content-Type Header to the request. Adding Content-Type header along with the value application/json did the trick.
Now I got the following reponse-

Now the thing about 418 I’m a teapot response is that it is an actual protocol called Hyper Text Coffee Pot Control Protocol and it has an RFC too. On researching a bit I came to know that it is returned whenever there is an error.
And the json response stated the same —

{“error”:{“body”:”unable to decode”}}

So my intitial guess was we need to pass something in the parameter to get it to work.
So I passed the following-

Which means that we needed to pass a domain in the request.
So I tried the following-

This meant that we needed a subdomain with 212. I later on came to know that we also needed .com as the tld.
So I ran a simple google dork — site:212.*.com and got a domain
I then did the following-

Here you can see the response-


So I decided to pass /read.php?id=174 in the same exact request. So I sent the same request to a new repeater tab and did the same. it returned a 405 Method Not Allowed error.
So I tried out different methods and since I used the same request, I got an interesting response-

This looked like a Base64 encoded data. So I used an online base64 decoder() to decode it and I got the source code of the page.
So this was interesting to me as it was a potential SSRF. So I gave `` as the value for “domain” and it returned the same Base64 data. This was something to do with id parameter value.
So I had to bypass the checks for 212 and .com by using Line feed(\n) and the payload looked like this-


Using this, I got a new parameter value which was 3 more than the initial one. An interesting thing I noticed here was that whenever we give an invalid domain, the parameter value is incremented by 1 and by 3 when it is valid.
Trying to pass this parameter value in the GET request would not work. So I reduced the parameter value by 1 and tried it and it worked. I got the following-

As you would’ve already guessed, this was the source code for the default apache page in

Now you know you have an SSRF vulnerable website and hence I tried everything one would do with SSRF attacks. First I tried to access the Digital Ocean Metadata. That didn’t give any fruitful information except some internal IPs.
Next, I tried to access some default apache directories. None of them worked except /server-status which again wasn’t any use for the CTF.
The final option was to port scan the localhost. Now portscanning the entire 65535 ports is a huge pain so I asked my friend who already solved it to give me a range in which I should port scan. He told 1 to 9000 will do.
Now I fired up intruder and gave the following options-

Now we also needed the second request for this to work so I ran the following after the initial scan was completed -

I went in steps of 400 as it would be easier for me to keep track of everything.

This ended up in me hitting port 1337 which returned the following base64 encoded value-


Which on decoding gave-

Hmm, where would it be?

And the answer to that queston was obviously /flag cuz that’s where the flag should be xD.
On accessing that I got the following base64 encoded data-


Which on decoding gives -

FLAG: CF,2dsV\/]fRAYQ.TDEp`w”M(%mU;p9+9FD{Z48X*Jtt{%vS($g7\S):f%=P[Y@nka=<tqhnF<aq=K5:BC@Sb*{[%z”+@yPb/nfFna<e$hv{p8r2[vMMF52y:z/Dh;{6

And that my friends was how I got the flag.

This CTF was beyond amazing. I got to learn new concepts like HTCPCP. Writing this report was a good learning experience too. Since I collaborated with one of the hackers(bayotop) for a small part of the CTF, it helped me learn about team work.
Thanks hackerone for organizing this amazing CTF.

Best regards,


Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade