Fortificación de comunicación entre Wordpress y MySQL: Evita el Network Packet Manipulation

En varios artículos hemos hablado de cómo hacer Network Packet Manipulation a entornos de bases de datos. Hablamos de cómo ownear MySQL colocándonos en medio de la comunicación del cliente y el servidor. En otro artículo comentamos como hackear Wordpress con la misma técnica. Al final todo se basa en que el tráfico entre las aplicaciones web y la base de datos puede ir sin cifrar, así es por defecto en la instalación de los motores de base de datos. En el artículo de hoy nos pondremos del lado del Blue Team y hablaremos de cómo fortificar tu Wordpress cifrando las comunicaciones entre éste y el MySQL.

Punto 0. Mi Wordpress por defecto

Partimos del siguiente esquema:
  • Máquina A con dirección IP 192.168.56.103 tiene instalada un Wordpress.
  • Máquina B con dirección IP 192.168.56.106 tiene instalado y configurado MySQL por defecto.

Si analizamos las peticiones se puede ver como accediendo al Wordpress, entre la máquina 192.168.56.103 y 192.168.56.106 se realizan una serie de consultas a la base de datos. Estos paquetes son susceptibles de ser manipulados. 


Punto 1. Fortificando MySQL con SSL

En este punto lo que vamos a hacer es preparar los tres componentes necesarios para que MySQL acepte conexiones bajo SSL. En primer lugar hay que consultar si la compilación de MySQL que se está utilizando permite utilizar SSL, si no fuera así habría que instalar una versión más nueva o compilarla con soporte a SSL. Para verificar esto accedemos a MySQL con un cliente y ejecutamos la siguiente consulta “show variables like ‘%ssl%’;”. Si las variables have_openssl y have_ssl tienen como valor DISABLED significa que está soportado pero no activo. Si por el contrario encontramos el valor NO, significa que la compilación de MySQL no soporta SSL. Si aparece el valor YES, significa que está correctamente configurado y el servidor permite conexión bajo este mecanismo.



Además, hay que ver las rutas de las variables ssl_ca, ssl_cert y ssl_key. Indican la ruta de la CA, del certificado del servidor y de la clave de éste.

En este punto vamos a utilizar OpenSSL para generar la CA, el certificado y la clave. Para ello ejecutamos las siguientes instrucciones:
  • openssl genrsa 2048 > ca-key.pem
  • openssl req –sha1 –new –x509 –nodes –days 3600 –key ca-key.pem > ca-cert.pem

Con esto tenemos creado el certificado y la clave privada de la CA. Nos pedirán que rellenemos varios datos como país, ciudad, dominio, email, etcétera. 
  • openssl req –sha1 –newkey rsa:2048 -days 730 -nodes -keyout server-key.pem > server-req.pem

Con esto generamos la clave privada para el servidor. A continuación, exportamos la clave privada del servidor a tipo RSA con la ejecución del siguiente comando:
  • openssl rsa -in server-key.pem -out server-key.pem
Por último, generamos un certificado de servidor utilizado el certificado de la CA.
  • openssl x509 -sha1 -req -in server-req.pem -days 730 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
Los ficheros cacert.pem, server-cert.pem y server-key.pem deben estar en la ruta /etc/mysql. Aunque esto puede ser configurado en el fichero de configuración de MySQL /etc/mysql/my.cnf. Editando dicho fichero y buscando a partir del campo “[mysqld]” debemos descomentar la parte de SSL y asegurarnos de que las variables tienen la configuración adecuada, tal y como puede verse en la siguiente imagen.


Ahora, reiniciamos el servicio de MySQL. Una vez el motor arranque y lea la configuración del fichero sabrá de dónde leer la información del certificado, la CA y la clave privada. Ahora, podremos conectarnos con un cliente MySQL  a través de SSL. Como ejemplo rápido utilizamos el propio mysql. La instrucción es la siguiente mysql –u [user] –p –ssl-ca=[ruta cacert]. Para comprobar que la conexión se ha realizado a través de SSL podemos consultar la variable Ssl_Cipher. 


Si abrimos Wireshark y aplicamos el filtro de MySQL para ver el tráfico observaremos que ya no vemos nada. Sin embargo si utilizamos un filtro “tcp.dstport == 3306” veremos que hay conexión con dicho puerto de la máquina 192.168.56.106. Las consultas están siendo cifradas, y por eso Wireshark no reconoce contenido MySQL. 


Punto 2. Configurando Wordpress para que utilice comunicación cifrada con SSL con MySQL

Ahora, hay que indicar en el fichero wp-config.php de Wordpress que éste debe entender los flags de MySQL para SSL. Para ello, añadimos al fichero la instrucción “define(‘MYSQL_CLIENT_FLAGS’, MYSQL_CLIENT_SSL);”, tal y como se puede ver en la imagen siguiente.


Ahora accedemos al sitio web de nuestro Wordpress y las consultas a MySQL irán por un canal cifrado, tal y como puede verse en la imagen. En este momento el NPM o Network Packet Manipulation ya no es válido, ya que no podemos detectar y manipular las cadenas de MySQL. Si probamos con Wireshark veremos que solo vemos la conexión al MySQL, pero nada de las consultas, si que veríamos la conexión al puerto 3306, pero todo cifrado. 

De esta forma estamos fortificando el intercambio de información entre el Wordpress y la base de datos MySQL. También se puede forzar a que usuarios concretos solo puedan hacer conexiones bajo SSL, lo cual es interesante para fortificar.