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