suid_binary_execution_ver

📸 Lab Session: SUID Binary Execution Verification

Terminal screenshot showing a Linux bash session on ubuntu-linux-2404 that demonstrates SUID behavior by creating and testing a compiled C program named whoami.sh. The terminal displays chmod, ls, and execution commands with output showing real UID equals 1000 (parallels user) and effective UID equals 0 (root), confirming that the SUID bit successfully changes execution context for compiled binaries. The session also shows password prompts and kernel warnings about SUID on scripts being ignored. Text visible includes file permissions (-rwxr-xr-x), user/group information (parallels), and explanatory echo statements about script execution and privilege handling.

🎯 Goal

Build a correct mental model of Linux privilege escalation foundations by understanding:

  • What SUID, SGID, and Sticky Bit actually do
  • How Linux really handles execution identity
  • Why some configurations are dangerous — and others only look dangerous
  • How attackers enumerate and reason about privilege boundaries

This day was about mechanics, not exploits.


🧠 Key Concepts (Before Touching Commands)

Linux privilege escalation is not magic.
It is about execution context.

Every process has:

  • a real UID/GID (who launched it)
  • an effective UID/GID (whose permissions it runs with)

Special permission bits exist to intentionally bend this rule — and that’s where things can go wrong.


🔧 Lab Work & Observations

1️⃣ SUID on Scripts (The Trap)

I created a simple shell script and set the SUID bit on it.

Even though:

  • the filesystem showed the s bit
  • file reported it as setuid

Linux did not change the effective UID at runtime.

Why?

  • Modern Linux kernels ignore SUID on scripts
  • Interpreters + environment variables + race conditions are inherently unsafe

➡️ This is not a bug.
➡️ This is a security decision.

Key insight:

Filesystem permissions ≠ kernel execution behavior.


2️⃣ Real SUID: Compiled Binary

I then built a small C program printing:

  • real UID
  • effective UID

When the binary was:

  • compiled (ELF)
  • owned by root
  • marked with SUID

Running it as a normal user clearly showed:

  • real UID = my user
  • effective UID = root

🔥 This is real SUID behavior.

No guessing. No theory. Just mechanics.


3️⃣ Enumerating SUID Files (Attacker View)

I enumerated SUID binaries using:

find / -perm -4000 2>/dev/null

Important realization:

  • Most SUID binaries are expected and hardened

  • Attackers don’t panic — they filter

I analyzed examples like:

  • Xorg.wrap → legacy, historically vulnerable, environment-dependent

  • chfn → boring but input-parsing (interesting in older systems)

  • snap-confine → security boundary creator (high-impact if broken)

Lesson:

The most interesting SUID binaries are often the ones enforcing security, not the obvious ones.


4️⃣ SGID: Quiet Privilege Changes

SGID doesn’t usually give root — but it can:

  • grant access to powerful groups

  • enable sideways privilege escalation

  • act as a stepping stone

Enumerated with:

find / -perm -2000 2>/dev/null

Key takeaway:

SGID is a horizontal privilege change — subtle, but real.


5️⃣ Sticky Bit: Damage Containment

Checked /tmp permissions:

ls -ld /tmp

Observed:

  • world-writable directory

  • sticky bit enabled (t)

Sticky bit:

  • does not grant privileges

  • prevents users from deleting each other’s files

Attackers don’t exploit sticky bit —
they exploit its absence.


6️⃣ PATH, Cron, Services (Previewed, Not Mastered)

I also introduced:

  • writable directories in $PATH

  • cron jobs

  • root-owned services

Important realization:

These are not vulnerabilities on their own.

They become dangerous only when chained with:

  • SUID binaries

  • unsafe scripts

  • trusted execution contexts

This part needs deeper, slower treatment — scheduled for later.


🧩 Mental Model (The Real Outcome)

By the end of the day, the model became clear:

  • SUID → vertical privilege jump (dangerous)

  • SGID → horizontal privilege shift (subtle)

  • Sticky bit → containment, not escalation

  • PATH / cron / services → exploit enablers, not exploits

Privilege escalation is not about running commands.
It’s about breaking trust boundaries.


🧠 Lessons Learned

What worked

  • Building my own binaries instead of trusting examples

  • Verifying everything with id, file, and real output

  • Thinking like an attacker, not a tutorial follower

What broke

  • Initial assumptions about SUID on scripts

  • Treating enumeration commands as “find exploit buttons”

Why it broke

  • Confusing filesystem metadata with kernel execution rules

  • Not separating capability from exploitability

Fix / takeaway

  • Always verify who a program actually runs as

  • Treat enumeration as judgment training, not exploit hunting

  • Slow down when concepts start chaining — depth beats speed