vendredi 3 juillet 2015

No one expect command execution !



Unix is a beautiful world where your shell gives you the power of launching any command you like. But sometimes, command can be used to launch another commands, and that's sometimes unexpected.



For example, here is how you can launch arbitrary command from tar:
But with a little research, it seems there is ton of way to achieve this with popular unix commands. The rules are simple:
  • don't launch the command from the shell
  • use a side effect of another command
  • have the command executed
I used a little script, called runme.sh:
mitsurugi@mitsu:~/tmp$ cat runme.sh
#! /bin/bash
echo "The name's 0xMitsurugi!"
echo "Remember it!"
mitsurugi@mitsu:~/tmp$


If it's printed on the script, you win. Here we go, without any ordering:

1/ tcpdump

$ tcpdump -n -i lo -G1 -w /dev/null -z ./runme.sh
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
The name's 0xMitsurugi!
Remember it!
The name's 0xMitsurugi!
Remember it!
^C6 packets captured
12 packets received by filter
0 packets dropped by kernel
$
Because each packet (-G), we rotate the file (-w) with the specified program (-z).

2/ tar

$ tar c a.tar -I ./runme.sh a
tar: a.tar: Cannot stat: No such file or directory
The name's 0xMitsurugi!
Remember it!
tar: Exiting with failure status due to previous errors
$
Because you can specify any compress program (-I) you want on command line for tar and we don't care for errors.

3/ zip

$ zip z.zip a -T -TT ./runme.sh
The name's 0xMitsurugi!
Remember it!
test of z.zip OK
$

zip is a nice boy which can autotest its zip file (-T), and test decompression with another program (-TT).

4/ ftp (and many others...)

A lot of program can give you access back to shell, I choose ftp because it's an old unix utility.
$ ftp
ftp> ! ./runme.sh
The name's 0xMitsurugi!
Remember it!
ftp>

and also, vi, gdb, etc.. you can even escape an ssh session with ~^Z

5/ man

This one is just for fun, but you have to give full path of program. The -P switch change the default pager program.
$ man -P /tmp/runme.sh man
The name's 0xMitsurugi!
Remember it!

$

6/ git (and man, and...)

If you have access to environment variable, there is a lot of fun to do:
$ export PAGER=./runme.sh
$ git -p help
The name's 0xMitsurugi!
Remember it!
$

And yes, it works with "man" the same way, andu surely many other which define a PAGER env variable.

But wait, there's more to do with git. If you can write to any directory in $PATH, you can do:
$ export PATH=/tmp:$PATH
$ ln -sf /tmp/runme.sh /tmp/git-help
$ git --exec-path=/tmp help
The name's 0xmitsurugi
remember it!
$

Although I don't have any idea to play with, I'm sure someone will find out :-) For an unknown reason, the --exec-path must be in $PATH in order to be executed.

7/ The most unexpected: bash $HOME variable

And yes, there is a way for subshells:
$ pwd
/tmp
$ ls -la .bashrc
lrwxrwxrwx 1 mitsurugi mitsurugi    8 juin  19 14:03 .bashrc -> runme.sh
$ export HOME=.
$ bash
The name's 0xMitsurugi!
Remember it!

$
I was almost 100% sure this would fail if I hadn't tried it.

8/ awk (and many others)

That's too easy when you have a "system" command:
$ awk 'BEGIN {system("./runme.sh")}'
The name's 0xMitsurugi!
Remember it!

$
and I'm sure there are a lot more.


That's all for today, I'm sure there are many more, don't be shy and send me (twitter, mail, blog) your best unexpected command execution :-)