Learn about a vulnerability allowing you to execute commands through a vulnerable app, and its remediations.
Site Link: https://tryhackme.com/r/room/oscommandinjection
Task 1 Introduction (What is Command Injection?)
In this room, we’re going to be covering the web vulnerability that is command injection. Once we understand what this vulnerability is, we will then showcase its impact and the risk it imposes on an application.
Then, you’re going to be able to put this knowledge into practice, namely:
- How to discover the command injection vulnerability
- How to test and exploit this vulnerability using payloads designed for different operating systems
- How to prevent this vulnerability in an application
- Lastly, you’ll get to apply theory into practice learning in a practical at the end of the room.
To begin with, let’s first understand what command injection is. Command injection is the abuse of an application’s behaviour to execute commands on the operating system, using the same privileges that the application on a device is running with. For example, achieving command injection on a web server running as a user named joe will execute commands under this joe user — and therefore obtain any permissions that joe has.
Command injection is also often known as “Remote Code Execution” (RCE) because of the ability to remotely execute code within an application. These vulnerabilities are often the most lucrative to an attacker because it means that the attacker can directly interact with the vulnerable system. For example, an attacker may read system or user files, data, and things of that nature.
For example, being able to abuse an application to perform the command whoami to list what user account the application is running will be an example of command injection.
Command injection was one of the top ten vulnerabilities reported by Contrast Security’s AppSec intelligence report in 2019. (Contrast Security AppSec., 2019) https://www.contrastsecurity.com/security-influencers/insights-appsec-intelligence-report. Moreover, the OWASP framework constantly proposes vulnerabilities of this nature as one of the top ten vulnerabilities of a web application (OWASP framework) https://owasp.org/www-project-top-ten/.
Answer the questions below
Read me!
Task 2 Discovering Command Injection
This vulnerability exists because applications often use functions in programming languages such as PHP, Python and NodeJS to pass data to and to make system calls on the machine’s operating system. For example, taking input from a field and searching for an entry into a file. Take this code snippet below as an example:
In this code snippet, the application takes data that a user enters in an input field named $title to search a directory for a song title. Let’s break this down into a few simple steps.
1. The application stores MP3 files in a directory contained on the operating system.
2. The user inputs the song title they wish to search for. The application stores this input into the $title variable.
3. The data within this $title variable is passed to the command grep to search a text file named songtitle.txt for the entry of whatever the user wishes to search for.
4. The output of this search of songtitle.txt will determine whether the application informs the user that the song exists or not.
Now, this sort of information would typically be stored in a database; however, this is just an example of where an application takes input from a user to interact with the application’s operating system.
An attacker could abuse this application by injecting their own commands for the application to execute. Rather than using grep to search for an entry in songtitle.txt, they could ask the application to read data from a more sensitive file.
Abusing applications in this way can be possible no matter the programming language the application uses. As long as the application processes and executes it, it can result in command injection. For example, this code snippet below is an application written in Python.
Note, you are not expected to understand the syntax behind these applications. However, for the sake of reason, I have outlined the steps of how this Python application works as well.
- The “flask” package is used to set up a web server
- A function that uses the “subprocess” package to execute a command on the device
- We use a route in the webserver that will execute whatever is provided. For example, to execute whoami, we’d need to visit http://flaskapp.thm/whoami
Answer the questions below:
2.1 What variable stores the user’s input in the PHP code snippet in this task?
Answer: $title
2.2 What HTTP method is used to retrieve data submitted by a user in the PHP code snippet?
Answer: Get
2.3 If I wanted to execute the id command in the Python code snippet, what route would I need to visit?
Answer: /id
Task 3 Exploiting Command Injection
You can often determine whether or not command injection may occur by the behaviours of an application, as you will come to see in the practical session of this room.
Applications that use user input to populate system commands with data can often be combined in unintended behaviour. For example, the shell operators ;, & and && will combine two (or more) system commands and execute them both. If you are unfamiliar with this concept, it is worth checking out the Linux fundamentals module to learn more about this.
Command Injection can be detected in mostly one of two ways:
- Blind command injection
- Verbose command injection
I have defined these two methods in the table below, where the two sections underneath will explain these in greater detail.
Method
Description
Blind
This type of injection is where there is no direct output from the application when testing payloads. You will have to investigate the behaviours of the application to determine whether or not your payload was successful.
Verbose
This type of injection is where there is direct feedback from the application once you have tested a payload. For example, running the whoami command to see what user the application is running under. The web application will output the username on the page directly.
Detecting Blind Command Injection
Blind command injection is when command injection occurs; however, there is no output visible, so it is not immediately noticeable. For example, a command is executed, but the web application outputs no message.
For this type of command injection, we will need to use payloads that will cause some time delay. For example, the ping and sleep commands are significant payloads to test with. Using ping as an example, the application will hang for x seconds in relation to how many pings you have specified.
Another method of detecting blind command injection is by forcing some output. This can be done by using redirection operators such as >. If you are unfamiliar with this, I recommend checking out the Linux fundamentals module. For example, we can tell the web application to execute commands such as whoami and redirect that to a file. We can then use a command such as cat to read this newly created file’s contents.
Testing command injection this way is often complicated and requires quite a bit of experimentation, significantly as the syntax for commands varies between Linux and Windows.
The curl command is a great way to test for command injection. This is because you are able to use curl to deliver data to and from an application in your payload. Take this code snippet below as an example, a simple curl payload to an application is possible for command injection.
curl http://vulnerable.app/process.php%3Fsearch%3DThe%20Beatles%3B%20whoami
Detecting Verbose Command Injection
Detecting command injection this way is arguably the easiest method of the two. Verbose command injection is when the application gives you feedback or output as to what is happening or being executed.
For example, the output of commands such as ping or whoami is directly displayed on the web application.
Useful payloads
I have compiled some valuable payloads for both Linux & Windows into the tables below.
Linux
Windows
Answer the questions below:
3.1 What payload would I use if I wanted to determine what user the application is running as?
Answer: whoami
3.2 What popular network tool would I use to test for blind command injection on a Linux machine?
Answer:ping
3.4 What payload would I use to test a Windows machine for blind command injection?
Answer: timeout
Task 4 Remediating Command Injection
Command injection can be prevented in a variety of ways. Everything from minimal use of potentially dangerous functions or libraries in a programming language to filtering input without relying on a user’s input. I have detailed these a bit further below. The examples below are of the PHP programming language; however, the same principles can be extended to many other languages.
Vulnerable Functions
In PHP, many functions interact with the operating system to execute commands via shell; these include:
- Exec
- Passthru
- System
Take this snippet below as an example. Here, the application will only accept and process numbers that are inputted into the form. This means that any commands such as whoami will not be processed.
- The application will only accept a specific pattern of characters (the digits 0–9)
- The application will then only proceed to execute this data which is all numerical.
These functions take input such as a string or user data and will execute whatever is provided on the system. Any application that uses these functions without proper checks will be vulnerable to command injection.
Input sanitisation
Sanitising any input from a user that an application uses is a great way to prevent command injection. This is a process of specifying the formats or types of data that a user can submit. For example, an input field that only accepts numerical data or removes any special characters such as >
, &
and /
.
In the snippet below, the filter_input
PHP function is used to check whether or not any data submitted via an input form is a number or not. If it is not a number, it must be invalid input.
Bypassing Filters
Applications will employ numerous techniques in filtering and sanitising data that is taken from a user’s input. These filters will restrict you to specific payloads; however, we can abuse the logic behind an application to bypass these filters. For example, an application may strip out quotation marks; we can instead use the hexadecimal value of this to achieve the same result.
When executed, although the data given will be in a different format than what is expected, it can still be interpreted and will have the same result.
Answer the questions below:
4.1 What is the term for the process of “cleaning” user input that is provided to an application?
Answer: sanitisation
The process of cleaning or filtering user input to ensure that it conforms to the expected format and type. In web applications, sanitization is used to prevent malicious data from being processed by the application, such as preventing Command Injection, SQL Injection, or Cross-Site Scripting (XSS).
Task 5 Practical: Command Injection (Deploy)
Deploy the machine attached to this task; it will be visible in the split-screen view once it is ready.
Test some payloads on the application hosted on the website visible in split-screen view to test for command injection. Refer to this cheat sheet https://github.com/payloadbox/command-injection-payload-list, if you are stuck or wish to explore some more complex payloads.
Find the contents of the flag located in /home/tryhackme/flag.txt. You can use a variety of payloads to achieve this — I recommend trying multiple.
Use this handy web application to test the availability of a device by entering it’s IP address in the field below. For example, 127.0.0.1
127.0.0.1: This is the local IP address (also known as “localhost”). It’s a valid input for the application’s form since the application is expecting an IP address to ping.
;
allows you to inject additional commands after the normal operation of the web application. This is a command injection technique.
Next Step: Let’s attempt to add a command that checks the current user
127.0.0.1; whoami
;
allows us to inject additional commands after the normal operation of the web application. This is a command injection technique.
whoami: This command returns the username of the account currently running the application or script.
The output result from the command injection is that the application is running as the web server user www-data. This is a common user account used by web servers like Apache or Nginx to execute web applications securely with limited permissions.
Next step: Now let’s attempt to retrieve the flag by displaying the contents of /home/tryhackme/flag.txt
127.0.0.1; cat /home/tryhackme/flag.txt
Answer the questions below:
5.1 What user is this application running as?
Answer: www-data
5.2 What are the contents of the flag located in /home/tryhackme/flag.txt?
Answer: THM{COMMAND_INJECTION_COMPLETE}
Task 6 Conclusion
Well done for making it to the end of this room. To recap, we’ve learned about the following elements of command injection:
- How to discover the command injection vulnerability
- How to test and exploit this vulnerability using payloads designed for different operating systems
- How to prevent this vulnerability in an application
- Applying your learning by performing command injection in a practical application
As you will have probably discovered, there are multiple payloads that can be used to achieve the same goal. I highly encourage you to go back to the practical element of this task and try some alternative methods of retrieving the flag.
Answer the questions below:
Terminate the vulnerable machine from task 5
“Great job on completing the challenge! You’ve gained valuable skills that will help you better understand and protect against web vulnerabilities in real-world scenarios.”