2026-06-17
Linux PrivEsc — Abusing sudo, Weak Permissions & Custom Binaries
Theme of the day: Linux local privilege escalation — abusing sudo, weak file permissions, and custom binaries. Recurring lesson: the hint names the technique class — read it literally, then enumerate to confirm.
> Methodology notes only — generic examples and placeholder names throughout. No specific target, account, or solution details.
1. Know your ground — container awareness
Before picking a vector, confirm the environment and your current privilege:
cat /proc/1/cgroup # paths showing /docker/<id> = Docker container
ls -la /.dockerenv # exists in most Docker containers
systemd-detect-virt -c # prints "docker"/"lxc" if containerized
id; whoami # are you already root? what groups?
Key takeaway: run id and check for a container first. If you're already uid=0 inside a container, "abusing sudo" is moot and the objective shifts to host breakout (docker.sock, dangerous capabilities). Privilege + environment decide the whole approach.
2. Abusing sudo — sudo -l and Baron Samedit
sudo -l is the command that drives every sudo privesc. Patterns to read for: NOPASSWD entries, (root) run-as, env_keep/LD_PRELOAD, wildcards/influençable scripts, and old sudo versions.
The trap: when sudo -l reports "user may not run sudo", people abandon sudo entirely. But CVE-2021-3156 (Baron Samedit) is a heap overflow in argument parsing that triggers before the sudoers check — so it works for any local user with no sudo rights and no password.
sudo --version | head -1 # vulnerable: <= 1.8.31p2 and 1.9.0–1.9.5p1
# non-destructive vuln test — heap error/segfault = vulnerable, clean usage: = patched
sudoedit -s '\' $(python3 -c 'print("A"*1000)')
Other sudo CVEs to keep in pocket: CVE-2019-14287 (sudo -u#-1), CVE-2023-22809 (sudoedit -s / EDITOR arg injection).
Key takeaway: a sudo version string is itself an exploit primitive. "May not run sudo" ≠ "sudo is safe."
3. Weak file permissions
When a box hints "look for file permissions," hunt writable things root cares about:
# Files writable by you that are OWNED BY ROOT — the money shot
find / -uid 0 -writable -type f 2>/dev/null | grep -vE '^/(proc|sys)'
# World-writable files and directories
find / -perm -0002 -type f 2>/dev/null
find / -perm -0002 -type d 2>/dev/null
# Crown-jewel targets, checked explicitly
ls -l /etc/passwd /etc/shadow /etc/sudoers /etc/sudoers.d/* /etc/crontab
Payoffs: writable /etc/passwd → UID-0 user; writable /etc/shadow → overwrite root's hash; readable /etc/shadow → crack offline; writable /etc/sudoers → grant yourself NOPASSWD; writable root-owned cron/service script → reverse shell or chmod +s /bin/bash.
Key takeaway: "file permissions" hints almost always mean writable + privileged-owner. Lead with -uid 0 -writable, not a blind world-writable sweep.
4. Custom binary / custom shell
When the hint points at a custom privileged binary (GTFOBins won't list custom binaries), reverse it for a shell:
# confirm privilege
sudo -l ; find / -perm -4000 -type f 2>/dev/null ; ls -l <binary>
# enumerate flags
<binary> --help ; <binary> -h ; <binary> # bare run may drop into a menu
# reverse it when help is thin
strings <binary> | less # hardcoded paths, system()/popen(), hidden flags
ltrace <binary> 2>&1 | less # watch system()/exec*()/fopen()
strace -f <binary> 2>&1 | grep -E 'exec|open' # what it really runs/reads
Three jackpots: a system() call on a bare command name → PATH hijack (export PATH=/tmp:$PATH); a flag taking a command/filename you control; a shell it launches. Restricted/custom-shell escapes: injection chars (; | $() \\ &&) in input fields; pager/editor-as-root escapes (vi → :!/bin/sh, less/man → !/bin/sh, awk 'BEGIN{system("/bin/sh")}').
Key takeaway: for custom binaries, strings/ltrace is your GTFOBins. A bare command name in a system() call = PATH hijack nearly every time.
Cross-cutting themes
- The hint names the technique class. "May not run sudo" → sudo binary CVE; "file permissions" → writable+root-owned; "binary flags / custom shell" → reverse the binary. Read literally, then enumerate to confirm.
id+ environment first, vector second.- Empty output is not proof of absence — full-path
sbintools before concluding "nothing here." - Version strings are primitives. sudo, the kernel, any service banner — check the number before assuming it's hardened.