I. Pose the problem
1. Introduction
OS command injection vulnerabilities are just a type of vulnerability that allows an attacker to “inject” and execute arbitrary commands corresponding to the operating system (OS) of the system. Therefore, this type of attack is also known as shell injection . This is one of the most dangerous vulnerabilities, usually rated in about
9.0 − 10.0 9.0 – 10.0 in CVSS score. Because when an attacker executes shell commands at the system will be able to directly penetrate the server, transferring the attack to other systems in the organization.
2. Distinguish Code injection and Command injection
To better understand this type of attack, in this article I will compare the characteristics between Code injection and Command injection .
Code injection | Command injection |
---|---|
General term for attacks that insert executable code into the target | Only specific execution of shell (OS) commands corresponding to the operating system at the system |
Payload inject can be any language like php, Ruby, Python, … | Payload inject are shell commands like id, whoami, ls, … and can vary with different operating systems |
Attackers mostly have root/admin privileges because the source code is often executed with high privileges | The attacker has the privileges of the compromised application, e.g. a web application often carries the www-data . privilege |
3. Some shell commands and special characters commonly used in OS command injection attacks
Since current systems often have servers running on the Ubuntu operating system platform, I will focus on the most commonly used commands in this operating system, with other operating systems for you to discover more on your own. .
When testing the OS command injection attack successfully on the target, we can exploit the system in the following ways: identify the current user with the whoami command, list filenames and directories with ls , read files with commands cat, tac, head, tail, …
The most “artistic” part is the combination of special characters with commands to bypass the filter from the system, executing commands for different purposes. The following table summarizes commonly used characters and their uses:
Commands | Meaning |
---|---|
cmd1 | cmd2 | The result of cmd1 becomes the parameter passed to cmd2, whether cmd1 executes successfully or fails, cmd2 executes |
cmd1 || cmd2 | cmd1 executes failed, then cmd2 executes |
cmd1 ; cmd2 | cmd1 executes successfully or fails will execute cmd2 |
cmd1 & cmd2 | cmd1 executes in the background, cmd1 and cmd2 execute concurrently |
cmd1 && cmd2 | cmd1 executes successfully then cmd2 executes |
( cmd1;cmd2; cmd3 ) | concurrently execute cmd1, cmd2, cmd3 |
In addition, there are many other useful characters and commands, which you can learn more and skillfully combine to bring great efficiency in the process of building attack payload.
Common functions for reading file content:
1 2 3 4 5 6 7 8 9 10 11 12 | highlight_file($filename); show_source($filename); print_r(php_strip_white($filename)); print_r(file_get_contents($filename)); readfile($filename); print_r(file($filename)); // var_dump fread(fopen($filename, "r"), $size); include($filename); // không phải file php include_once($filename); // không phải file php require($filename); // không phải file php require_once($filename); // không phải file php |
Common functions for directory browsing:
1 2 3 4 5 6 7 8 9 10 11 | print_r(glob("*")); // liệt kê các file trong thư mục hiện tại print_r(glob("/*")); // liệt kê các file trong thư mục gốc print_r(scandir(".")); print_r(scandir("/")); var_export(scandir("/")); var_dump(scandir("/")); $d=opendir(".");while(false!==($f=readdir($d))){echo"$fn";} $d=dir(".");while(false!==($f=$d->read())){echo$f."n";} $a=glob("/*");foreach($a as $value){echo $value." "}; $a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");} |
II. Analysis and exploitation of OS command injection vulnerabilities
1. Why can an attacker exploit the OS command injection vulnerability?
When a system uses direct user input (Cookie, HTTP Header, parameter, …) as a parameter passed to the execution in a shell command, where there are no protection mechanisms or processes loose filter will lead to Command injection vulnerability. The system will then unconditionally execute these dangerous inputs!
2. Some functions can lead to OS command injection
Every programming language has functions that support shell command execution, when using these functions be careful with input from the user, as I often say, the attacker also plays the role of the user!
2.1. PHP language
- system() function
Syntax: system(string $command, int &$result_code = null)
Execute and print the output of the $command
. Eg:
1 2 3 4 5 | if (isset($_GET['cmd'])) { $cmd = $_GET['cmd']; system($cmd); } |
- exec() function
Syntax: exec(string $command, array &$output = null, int &$result_code = null)
Execute the $command
. If there is a $output
variable, it will store the results in $output
as an array. Eg:
1 2 3 4 5 6 7 | $output = null; if (isset($_GET['cmd'])) { $cmd = $_GET['cmd']; exec($cmd, $output); var_dump($output); } |
- passthru() function
Syntax: passthru(string $command, int &$result_code = null)
Execute and print the output of the $command
. Eg:
1 2 3 4 5 | if (isset($_GET['cmd'])) { $cmd = $_GET['cmd']; passthru($cmd); } |
- shell_exec() function
Syntax: shell_exec(string $command)
Execute the $command
. Eg:
1 2 3 4 5 6 | if (isset($_GET['cmd'])) { $cmd = $_GET['cmd']; $output = shell_exec($cmd); echo $output; } |
- popen() function
Syntax: popen(string $command, string $mode)
Opens a “pipe” to the program specified in the $command
variable. Eg:
1 2 3 4 5 6 7 8 | if (isset($_GET['file'])) { $file = $_GET['file']; $content = popen($file, "r"); $read = fread($content, 2096); echo $read; pclose($content); } |
- proc_open() function
Syntax: proc_open(array|string $command, array $descriptor_spec, array &$pipes, ?string $cwd = null, ?array $env_vars = null, ?array $options = null)
Uses the same as popen()
but provides a greater degree of control over the execution of the program.
- Backtick character pair:
PHP will execute the contents of the parameters placed in the
pair as a shell command.
1 2 3 4 5 | if (isset($_GET['cmd'])) { $cmd = $_GET['cmd']; echo `$cmd`; } |
2.2. Python language
- system() function
Syntax: system(command)
- popen() function
Syntax: popen(cmd, mode='r', buffering=-1)
- Function subprocess.call()/subprocess.run()
Syntax: subprocess.call(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)
2.3. Java language
Note java.lang.Runtime.getRuntime().exec(command)