Skip to content

Instantly share code, notes, and snippets.

@bayotop
Last active January 1, 2018 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bayotop/57965f40b86c1c44327d37850bf6f3cf to your computer and use it in GitHub Desktop.
Save bayotop/57965f40b86c1c44327d37850bf6f3cf to your computer and use it in GitHub Desktop.
h1-212 CTF

Description

https://www.hackerone.com/blog/hack-your-way-to-nyc-this-december-for-h1-212

How I found the flag

I ran an obligatory port scan, checked the IP using shodan.io, and did some basic directory discovery. I found two open ports - 22 and 80 - and one directory /flag with a message from the creators.

As this wasn't really helpful, I tried to enumerate vhosts and found one resulting in a different response: admin.acme.org.

HTTP/1.1 200 OK
Date: Wed, 15 Nov 2017 16:22:08 GMT
Server: Apache/2.4.18 (Ubuntu)
Set-Cookie: admin=no
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8

Sending Cookie: admin=yes resulted in HTTP/1.1 405 Method Not Allowed. All methods seemed to be disallowed only POST returned HTTP/1.1 406 Not Acceptable. I instantly got the idea to change the content type to application/json. This was actually because shodan.io had cached results from an open 8080 port, that returned Content-Type: application/json.

The content should be an .com domain with a 212. subdomain according to error messages returned. After sending 212.acme.com I got {"next":"\/read.php?id=1"} After a few trial and error I realized that the read.php returns raw content that is returned from the domain sent to the server in the previous POST request.

At this point I got awfully long stuck. The first thing I did was registering a domain, which fits the requirements, and looking at the requests made by the server using netcat.

# nc -nvlp 11111
GET / HTTP/1.0
Host: 212.acme.com

Playing around for a bit I realized that I could request any IP / domain by providing this input: {"domain":"212\nANY.DOMAIN.OR.IP:PORT\n.com"}. During recon I learned that the server is hosted on Digital Ocean, therefore I tried to query DO's Metadata API. This revealed the servers private IP. The first thing I did was port scan using nmap's top 1000 ports. I repeated the process for 127.0.0.1. Nothing (yeah, I know...).

After this I went crazy fuzzing for command injection and local file disclosure. No success.

At this point we put heads together with @streaak (great guy) as I learned he is stuck at the same stage. After numerous other tries (e.g. I had a feeling the goal was to request /read.php?id=0 using the SSRF), @streaak pointed out that we should fully rescan the internal IPs.

After seeing that 127.0.0.1:1337 responds with "Hmm, where would it be?" I became kind of sad as I could have it like 12 hours ago when I initially scanned ports (I guess 1337 is not that common). Note for self: never skip ports again! Anyway, I instinctively knew it would be 127.0.0.1:1337/flag, because of the public /flag endpoint found during the initial recon. And there it was:

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment