OS Command Injection (also known as Shell Injection) is a type of injection vulnerability wherein commands injected by an attacker are executed as system commands on the host operating system.
OS Command Injection attacks are caused by insufficient input validation, although they are only possible if the web application code incorporates operating system calls with user input embedded in the invocation.
Not to be confused with Code Injection, OS Command Injection extends the preset functionality of the application to execute system commands, whereas Code Injection attacks allow the attacker to add their own code to be executed by the application. In certain circumstances, Code Injection could be promoted to OS Command Injection by using the facilities provided by the language.
OS Command Injection vulnerabilities are language agnostic, potentially appearing in any language with the provision to call a system shell command. Unfortunately, their ubiquity is a result of many programming languages, application development frameworks, and database platforms providing OS command execution facilities as value add for application designers looking for expedience to implement new features.
Command Injections are one of a number of injection attacks, all of which are very prevalent and capable of extremely high levels of compromise. Indeed, OWASP has listed injection attacks as the number 1 web application security risk since 2013.
Malicious attackers can leverage OS Command Injection vulnerabilities to gain a foothold in the hosting infrastructure, pivot to connected systems throughout the organisation, execute unauthorised commands and fully compromise the confidentiality, integrity and availability of the application and the underlying system.
There is no better publicly known breach that better illustrates the catastrophic fallout resulting from a successfully executed OS Command Injection than the infamous Equifax breach. Attackers were able to penetrate Equifax’s systems by using a Command Injection attack, enabled by a vulnerability in a popular web framework.
OS Command Injections can be orchestrated on Windows and Unix systems, and they can affect any language that invokes a command via system shell.
The classic scenario is a vulnerable program that calls the
system() function to execute commands by concatenating unsanitized input. The following example illustrates the creation of a compressed archive file by executing the
zip command to compress a file that comes from a user-provided
system("zip archive.zip " + filename)
An attacker can exploit the code by leveraging special shell characters to append arbitrary commands at the end of the original one.
The example below illustrates this in action; by sending
x; rm important_file in the
filename parameter, the system shell command would result in the following:
zip archive.zip x; rm important_file
; is used to stack multiple commands, in this example, the attacker would terminate the first command in order to inject a second malicious command execution that removes an important file from the disk.
Developers must use structured mechanisms that automatically enforce the separation between data and code.
Importantly, OS Command Injection vulnerabilities can be entirely prevented if developers stringently avoid OS Command call outs from the application layer. Alternative methods of implementing necessary levels of functionality almost always exist.
If invoking the command shell is unavoidable, endeavor not to use functions that call out using a single string; rather, opt for functions that require a list of individual arguments. These functions typically perform appropriate quoting and filtering of arguments.
Verify that the application protects against OS command injection and that operating system calls use parameterized OS queries or use contextual command line output encoding.