Tracing SUID Binary Exploitation via Setuid Syscall and Privilege Transition Correlation
Theory
Why This Matters
SUID (Set User ID) binaries run with the effective UID of their owner, not the invoking user. A SUID binary owned by root gives the invoking user root-level effective privileges for the duration of the process. Every Linux system ships with a small set of legitimate SUID binaries (passwd, ping, su), but attackers who gain write access to any directory can drop their own SUID binary, or locate a misconfigured legitimate SUID binary exploitable via GTFOBins. Detecting SUID exploitation requires understanding the setuid syscall in auditd records, recognising unusual UID transitions in process trees, and correlating shell history with filesystem evidence.
Core Concept
The setuid syscall (and its variants setreuid, setresuid) is recorded by auditd when a process changes its effective user ID. When a SUID binary is executed, the kernel automatically sets the process EUID to the file owner's UID before the binary's main() function runs — this transition is recorded if auditd has a rule watching for setuid syscalls.
Key forensic signature: a process with original UID > 0 executing a SUID binary and resulting in EUID = 0. The parent-child relationship in the process tree reveals the invoking shell or process, identifying the attacker's session.
Finding exploitable SUID binaries:
find / -perm -4000 -type f 2>/dev/null
This lists all SUID files. Unexpected entries (custom scripts with SUID, world-writable SUID directories, unusual binaries) are targets for investigation. GTFOBins documents which legitimate SUID binaries can be exploited for privilege escalation.
Useful auditd fields:
- uid: real UID of the process
- euid: effective UID (0 = root after SUID execution)
- auid: audit UID (original login user — persists across UID changes)
- exe: path of the executed binary
- key: audit rule tag (e.g., suid_exec)
Technical Deep-Dive
# auditd rule: monitor setuid/setgid syscalls
# /etc/audit/rules.d/suid.rules:
# -a always,exit -F arch=b64 -S setuid,setreuid,setresuid -F auid!=4294967295 -k suid_exec
# -a always,exit -F arch=b32 -S setuid,setreuid,setresuid -F auid!=4294967295 -k suid_exec
# Search for SUID escalation events (euid=0 with uid != 0)
ausearch -k suid_exec --interpret
| awk '/type=SYSCALL/{
if (/euid=root/ && !/uid=root/) print
}'
# Find all SUID files on the system
find / -perm -4000 -type f -ls 2>/dev/null
| awk '''{print $3, $5, $11}'''
# Check for SUID files in unusual locations (not /bin, /usr/bin, /sbin, /usr/sbin)
find / -perm -4000 -type f 2>/dev/null
| grep -vE "^/(bin|sbin|usr/bin|usr/sbin|usr/lib)"
# Correlate bash history with SUID binary execution
# Attacker typically runs: find / -perm -4000 then ./suid_binary
grep -r "-perm.*4000|./.*suid|suid_binary"
/home/*/.bash_history /root/.bash_history 2>/dev/null
# Check Sysmon Event 1 equivalent on Linux (auditd execve)
ausearch -m EXECVE --interpret 2>/dev/null
| grep -B5 "a0="./"" | head -40
# Python: parse auditd log to find SUID escalation events
import re
SYSCALL_RE = re.compile(
r'type=SYSCALL.*?uid=(d+).*?euid=(d+).*?auid=(d+).*?exe="([^"]+)".*?key="suid_exec"'
)
with open("/var/log/audit/audit.log") as fh:
for line in fh:
m = SYSCALL_RE.search(line)
if m:
uid, euid, auid, exe = m.groups()
if euid == "0" and uid != "0":
print(f"SUID ESCALATION: uid={uid} → euid=0 | auid={auid} | exe={exe}")
Analytical Methodology
- Search auditd records for setuid/setreuid/setresuid syscalls tagged with your suid_exec key. Filter for events where uid != 0 but euid = 0 — this is the definitive SUID escalation signature.
- Identify the executing binary (exe field). Look it up on GTFOBins to confirm it is a known escalation path. Note whether it is a legitimate system binary or a custom/dropped file.
- Trace the process tree: use the PID and PPID from the auditd record to identify the parent process. A parent process of bash or sh owned by a non-root user confirms interactive exploitation. A parent process of a web server indicates remote exploitation.
- Examine bash history for the attacking user (use AUID to identify the original login): look for
find / -perm -4000(reconnaissance), execution of the SUID binary (./binaryor full path), and subsequent commands executed as root. - Run
find / -perm -4000 -type f 2>/dev/nullon the forensic image. Compare against the known-good baseline. Any SUID binary not in the baseline was dropped by the attacker. - Check the SUID binary's file metadata: ownership (should be root), creation time (a recently created SUID binary is strong evidence of attacker activity), and whether it is in a world-writable directory.
- Examine subsequent auditd records from the same session (same AUID, PID range) after the SUID escalation. What did the attacker do with root access? Look for: shadow file reads, new account creation, cron installation, outbound connections.
- Document: exploited binary path, exploitation method (per GTFOBins), original user UID, AUID, escalation timestamp, and the first privileged action taken as root.
Common Analytical Errors
- Not having suid_exec auditd rules: If no setuid syscall audit rules are loaded, auditd will not record SUID escalation events. Verify rule coverage. Without auditd, fall back to Sysmon (if installed), auth.log su entries, and filesystem timeline analysis.
- Assuming only unexpected SUID binaries are exploitable: Many legitimate SUID binaries (find, vim, less, more, python2) are documented GTFOBins escalation paths. An attacker does not need to drop a custom binary if the system already has a misconfigured legitimate one.
- Missing 32-bit vs 64-bit syscall variants: auditd rules must be written for both
arch=b64andarch=b32to catch all setuid calls on 64-bit systems that may execute 32-bit binaries. A single-arch rule misses half the potential events. - Overlooking capabilities as an alternative to SUID: Linux capabilities (
getcap -r / 2>/dev/null) provide fine-grained privileges similar to SUID but not recorded as setuid syscall events. Check for binaries withcap_setuid+eporcap_net_admin+epas SUID-equivalent escalation paths.
NICE Framework Alignment
| Code | Work Role Knowledge / Skill / Task | Relevance |
|---|---|---|
| K0046 | Knowledge of intrusion detection methodologies | SUID exploitation is a standard local privilege escalation technique in Linux environments |
| K0145 | Knowledge of security event correlation tools | auditd setuid syscall correlation with process tree reconstruction is a Linux SIEM technique |
| K0187 | Knowledge of file type abuse by adversaries | ELF SUID binaries are a class of legitimate file type routinely abused for privilege escalation |
| S0047 | Skill in preserving evidence integrity | Forensic image acquisition preserves SUID bits and ownership metadata that live systems may change |
| T0049 | Decrypt seized data / analyze forensic artifacts | Parsing auditd binary log format and correlating SYSCALL and PATH record types for escalation analysis |
Further Reading
- GTFOBins (gtfobins.github.io) — SUID escalation techniques per binary
- Linux man page: capabilities(7) — Linux capability system as alternative to SUID
- auditd documentation: auditing setuid execution — rule syntax and output interpretation
- SANS FOR508: Advanced DFIR — Linux post-exploitation artefacts
- MITRE ATT&CK T1548.001: Setuid and Setgid — detection data sources and mitigations
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.