Browse CTFs New CTF Sign in

Tracing SUID Binary Exploitation via Setuid Syscall and Privilege Transition Correlation

web_injection_logic Difficulty 1–5 30 min certifiable

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

  1. 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.
  2. 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.
  3. 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.
  4. 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 (./binary or full path), and subsequent commands executed as root.
  5. Run find / -perm -4000 -type f 2>/dev/null on the forensic image. Compare against the known-good baseline. Any SUID binary not in the baseline was dropped by the attacker.
  6. 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.
  7. 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.
  8. 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=b64 and arch=b32 to 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 with cap_setuid+ep or cap_net_admin+ep as 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.