Introducción
Con la infraestructura de red ya definida en OPNsense con el artículo anterior, el siguiente paso consiste en preparar las máquinas virtuales que formarán parte del laboratorio del CTF. A partir de este punto, cada VM deberá integrarse correctamente en las redes DMZ e interna, respetando la segmentación previamente establecida.
Instalación de las máquinas virtuales
Realizaremos la instalación en VirtualBox de dos máquinas virtuales Debian Linux con el menor número de herramientas instaladas ya que se instalarán posteriormente las que sean necesarias. Para agilizar el tiempo de instalación se puede utilizar la version de instalación por red de Debian. Los requerimientos de las máquinas serán de 2 núcleos de CPU, 2 GB de RAM, y 8 GB de almacenamiento.
En el proceso de instalación únicamente se seleccionará el servidor SSH. Como usuario menos privilegiado en el sistema utilizaremos server, con una contraseña poco compleja pero diferente en las dos máquinas. En torno a la contraseña del usuario root utilizaremos una compleja resistente a ataques de fuerza bruta.
Configuración de las interfaces de red
Es necesario recordar que en la configuración de red es necesario especificar las redes internas a las que pertenecerá la máquina virtual y la dirección MAC configurada en OPNsense para que el servidor DHCP sepa que dirección IP asignar a las máquinas. Así configuramos las interfaces de red de la máquina virtual VM1.
Y así configuramos la interfaz de red de la máquina virtual VM2.
Pero para realizar la instalación necesitamos acceso a Internet, por lo que al principio utilizaremos interfaces NAT para al final configurar las interfaces anteriores. También podemos dar a las interfaces acceso a Internet mediante la modificación de las reglas de firewall de OPNsense.
Configuración de las máquina virtual VM1
Iniciaremos la configuración de la máquina virtual mediante una conexión utilizando el protocolo SSH y escalando al usuario root para en primer lugar activar la segunda interfaz de red de la máquina ya que por defecto no se encuentra activada. Ésta será la que de acceso al usuario a la red interna.
$ ssh server@192.168.0.2
server@vm1:~$ su root
root@vm1:/home/server# ip a
...
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether d0:09:b6:a2:69:ce brd ff:ff:ff:ff:ff:ff
altname enxd009b6a269ce
inet 192.168.0.2/24 brd 192.168.0.255 scope global dynamic noprefixroute enp0s3
valid_lft 85853sec preferred_lft 75053sec
inet6 fe80::68d6:ff71:af93:ec17/64 scope link
valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether a2:20:0e:a9:56:a8 brd ff:ff:ff:ff:ff:ff
altname enxa2200ea956a8
root@vm1:/home/server# echo -e "\nallow-hotplug enp0s8\niface enp0s8 inet dhcp" >> /etc/network/interfaces
root@vm1:/home/server# systemctl restart networking
Ahora instalamos las herramientas que necesitamos en el sistema: SUDO, Docker, nftables.
root@vm1:/home/server# apt install sudo docker.io docker-compose nftables
Luego configuraremos la vulnerabilidad en la que el usuario server podrá ejecutar un comando como el usuario administrador, less, para leer los registros del sistema, disponiendo una funcionalidad para desplegar una consola interactiva.
root@vm1:/home/server# echo -e "\nserver ALL=(root) NOPASSWD: /usr/bin/less /var/log/installer/syslog" >> /etc/sudoers
Ahora utilizaremos Docker para configurar una instancia de WordPress vulnerable mediante una copia de un archivo de configuración antiguo para acceder al panel de administrador y la subida de un plugin malicioso para obtener ejecución remota de comandos. Utilizaremos Docker Compose para desplegar el entorno con la siguiente configuración docker-compose.yaml. Configuraremos la contraseña del usuario para acceder a la máquina mediante SSH utilizando la variable de entorno AUTOMATION_TOKEN.
services:
db:
image: mariadb:10
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=1Hpk7A52uDeEwFSOrTKr
- MYSQL_DATABASE=wordpress
- MYSQL_USER=server
- MYSQL_PASSWORD=iEX8VxWG5J0zdYfhXikT
web:
image: wordpress:6
restart: unless-stopped
depends_on:
- db
environment:
- WORDPRESS_DB_USER=server
- WORDPRESS_DB_PASSWORD=iEX8VxWG5J0zdYfhXikT
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_NAME=wordpress
- AUTOMATION_TOKEN=yingyang
ports:
- 80:80
Iniciamos el entorno mediante el despliegue del contenedor que contendrá la base de datos MariaDB y del contenedor que contendrá el servidor web que alojará WordPress.
root@vm1:~# cd /root
root@vm1:~# vi docker-compose.yaml
root@vm1:~# docker compose up -d
[+] Running 3/3
✔ Network tmp_default Created
✔ Container tmp-db-1 Started
✔ Container tmp-web-1 Started
Ahora configuraremos la instancia de WordPress mediante su asistente web. Dispondremos de una contraseña generada aleatoriamente de la que tomaremos nota para iniciar sesión posteriormente.
Tras configurar la aplicación web y obtener acceso al panel de administración volveremos a la consola y desplegaremos una consola interactiva mediante Docker al contenedor web.
root@vm1:~# docker exec -it tmp-web-1 bash
Creamos una copia del archivo wp-config.php en el archivo wp-config.php.bak y lo editamos añadiendo las credenciales generadas anteriormente. Modificaremos cualquiera de los parámetros que se encuentran en el archivo, en este caso define( 'DB_USER', getenv_docker('WORDPRESS_DB_USER', 'example username') ); y define( 'DB_PASSWORD', getenv_docker('WORDPRESS_DB_PASSWORD', 'example password') );
root@e310ba85af9b:/var/www/html# cp wp-config.php wp-config.php.bak
root@e310ba85af9b:/var/www/html# nano wp-config.php.bak
Tras obtener el usuario acceso al panel de administración podrá obtener ejecución remota de comandos mediante la subida de un plugin malicioso que despliegue una terminal inversa. Obtendrá la contraseña del usuario server mediante la enumeración de las variables de entorno y podrá iniciar sesión mediante SSH para luego escalar privilegios hacia root utilizando la vulnerabilidad configurada anteriormente.
Finalmente creamos reglas de firewall persistentes para solo permitir el acceso a la máquina desde la red LAN, desde los clientes VPN y desde la máquina VM2. Suponemos que la dirección IP de la máquina VM2 tiene un octeto más que la VM1 (.2 a .3).
root@vm1:~# nft add table inet lab
root@vm1:~# nft add chain inet lab input '{ type filter hook input priority 0 ; }'
root@vm1:~# nft add rule inet lab input ip saddr 10.0.10.0/24 accept
root@vm1:~# nft add rule inet lab input iif "enp0s3" ip saddr 100.100.100.0/24 accept
root@vm1:~# nft add rule inet lab input iif "enp0s8" ip saddr 172.16.0.3 accept
root@vm1:~# nft add rule inet lab input iif "enp0s3" reject
root@vm1:~# nft add rule inet lab input iif "enp0s8" reject
root@vm1:~# mkdir -p /etc/nftables
root@vm1:~# nft list table inet lab > /etc/nftables/lab.rules
root@vm1:~# echo -e '\ninclude "/etc/nftables/lab.rules"' >> /etc/nftables.conf
root@vm1:~# systemctl enable nftables
root@vm1:~# systemctl start nftables
Configuración de la máquina virtual VM2
Iniciaremos la configuración de la máquina virtual mediante una conexión utilizando el protocolo SSH y escalando al usuario root para en primer lugar instalar las herramientas que necesitamos en el sistema: SUDO, Docker, nftables, KeePassXC.
root@vm1:/home/server# apt install sudo docker.io docker-compose nftables keepassxc
root@vm2:/home/server# cd
Desplegamos el servidor FTP utilizando Docker Compose con el siguiente archivo de configuración docker-compose.yaml.
services:
ftp-server:
container_name: my-ftp-server
restart: unless-stopped
environment:
- FTP_PASS=anonymous
- FTP_USER=anonymous
image: garethflowers/ftp-server
ports:
- "20-21:20-21/tcp"
- "40000-40009:40000-40009/tcp"
volumes:
- "/root/ftp_root:/home/anonymous"
Creamos el directorio /root/ftp_root, que será el directorio raíz del servidor FTP dónde se guardarán los archivos e inicializamos el contenedor.
root@vm2:~# docker compose up -d
[+] Running 5/5
✔ ftp-server Pulled
✔ 1f3e46996e29 Pull complete
✔ 2d99d708cc3e Pull complete
✔ cd0faf35dc26 Pull complete
✔ 1288b7737817 Pull complete
[+] Running 2/2
✔ Network root_default Created
✔ Container my-ftp-server Started
Ahora creamos el archivo que contiene contraseñas de KeePass mediante la elaboración de una nueva base de datos KeePass y de una nueva entrada, en este caso RootCreds.
root@vm2:~# keepassxc-cli db-create ftp_root/passwords.kdbx -p
root@vm2:~# keepassxc-cli add ftp_root/passwords.kdbx RootCreds -u root -p
Finalmente creamos reglas de firewall persistentes para solo permitir el acceso a la máquina desde la red LAN, y desde la máquina VM1. Suponemos que la dirección IP de la máquina VM1 tiene un octeto menos que la VM1 (.3 a .2).
root@vm2:~# nft add table inet lab
root@vm2:~# nft add chain inet lab input '{ type filter hook input priority 0 ; }'
root@vm2:~# nft add rule inet lab input ip saddr 10.0.10.0/24 accept
root@vm2:~# nft add rule inet lab input iif "enp0s3" ip saddr 172.16.0.2 accept
root@vm2:~# nft add rule inet lab input iif "enp0s3" reject
root@vm2:~# mkdir -p /etc/nftables
root@vm2:~# nft list table inet lab > /etc/nftables/lab.rules
root@vm2:~# echo -e '\ninclude "/etc/nftables/lab.rules"' >> /etc/nftables.conf
root@vm2:~# systemctl enable nftables
root@vm2:~# systemctl start nftables
Conclusión
Tras completar la configuración de las máquinas de laboratorio en VirtualBox, el entorno queda plenamente configurado y preparado para ser resulto por los usuarios. Como siguientes pasos, se encontraría la resolución paso a paso del entorno.