El protocolo SSL (y su sucesor,
TLS),
es el principal encargado de que las comunicaciones en Internet sean
seguras, proporcionando múltiples opciones de cifrado y autenticación.
El cifrado es obligatorio, mientras que la autenticación no, aunque
normalmente se autentica al menos el servidor, para evitar ataques de
tipo
Man-in-the-Middle. Obviamente, es un protocolo imprescindible en cuanto la información transmitida es mínimamente sensible.
No obstante, también complica el análisis de las comunicaciones por
parte de los responsables de seguridad, ya que no es posible hacer un
filtrado basado en el contenido del tráfico, al estar cifrado. De hecho,
no es raro encapsular tráfico dentro de SSL para evadir el control de
proxies o firewalls. Este
análisis puede también ser necesario para
análisis de incidentes, o para conocer en detalle qué información
estamos mandando a webs o aplicaciones que utilizan este protocolo.
En esta entrada veremos dos alternativas distintas para analizar
tráfico SSL, explicando los principios que hacen posible el descifrado
de los datos. Pero antes de nada, destacar que interceptar
tráfico SSL
ajeno, sin consentimiento o autorización explícita, no es legal.
Negociación de claves
Dentro de las suites de cifrado que ofrece SSL, encontramos
criptosistemas destinados a la negociación de claves, al cifrado de
información y a su autenticación. Por ejemplo, para los algoritmos
definidos en el
RFC 5246:
- TLS_RSA_WITH_AES_128_CBC_SHA: Utiliza RSA para intercambio de claves, cifra con AES-128 en modo CBC y utiliza SHA1 en la autenticación HMAC.
- TLS_DH_anon_WITH_AES_256_CBC_SHA: Utiliza Diffie-Hellman anónimo (sin autenticar) para intercambio de claves, AES-256 en modo CBC para cifrado, y SHA1 para la autenticación HMAC.
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: Utiliza Diffie-Hellman efímero con DSS (derivado de DSA) para autenticar el intercambio de claves, AES-256 en modo CBC para cifrado y autenticación HMAC con SHA-256.
En lo concerniente a esta entrada, para entender cómo funciona la
intercepción del
tráfico, nos interesa la primera parte (la verde), ya
que es la encargada de la generación de las claves criptográficas. Para
saber qué esquema utiliza un sitio web concreto, se puede utilizar por
ejemplo la web de
Qualys SSL Labs o, para los que sean más de consola, un script como el descrito en este
post de superuser.com. Chrome también lo muestra, al pinchar en el candado que indica que SSL está activo, y acceder a la pestaña "Conexión".
Resumiendo, en SSL cliente y servidor negocian un
premaster secret común, del que derivan el
master secret,
que a su vez usan para crear las claves criptográficas para
autenticación y cifrado. Con los diferentes mecanismos de negociación de
clave, lo que se hace es variar la forma en que se obtiene dicho
premaster secret.
Descifrando SSL directamente con el premaster secret
Evidentemente, si nos hacemos con el
premaster secret, podemos
realizar todos los cálculos necesarios para derivar las claves finales
igual que hacen cliente y servidor. Esta opción es la que menos
esfuerzo requiere, ya que los propios navegadores permiten
volcar el premaster secret a un fichero. Posteriormente, en Wireshark, desde
"Edit > Preferences > Protocols > SSL" se puede indicar dónde se encuentran estos ficheros.
La principal ventaja de este método es, evidentemente, su sencillez. La
principal desventaja (de cara al análisis de incidentes), es que sólo
sirve para analizar nuestro propio tráfico, aunque si lo que queremos
es estudiar el tráfico de una aplicación concreta, esto tampoco es
problema. Esto podría solventarse concatenando todos los ficheros de log
obtenidos de los navegadores de las distintas máquinas, ya que
Wireshark va explorando una a una las entradas de dicho fichero hasta
encontrar una que permite descifrar el
tráfico. No obstante, esto reduce
la sencillez y dificulta la escalabilidad.
Descifrando SSL con un proxy MitM
En esta alternativa no se tiene acceso directo al
premaster secret y básicamente, actuamos como un atacante activo, a modo de
Man-in-the-Middle. Hay varios proxies que permiten realizar la intercepción necesaria para el posterior descifrado. Por ejemplo,
Burp Proxy,
mitmproxy o
Squid con
SSL Bump. Posteriormente, con Wireshark, se puede especificar la clave privada utilizada por el proxy para negociar el
premaster secret.
Evidentemente, hay que configurar los navegadores (o las máquinas)
para que enruten el
tráfico a través del proxy. Pero aparte de esto,
¿cuál es la teoría detrás de la práctica?
Cuando el método de intercambio de claves utilizado es RSA, el cliente calcula el
premaster secret
y lo envía cifrado con la clave pública (RSA) del servidor. En este
caso, al cambiar el certificado del servidor original por el de nuestro
proxy, podremos utilizar la clave privada asociada para descifrar el
premaster secret.
Si se utiliza Diffie-Hellman, el modo de proceder será modificar el tráfico, utilizando unos valores (
z,
Z =
gz) propios en lugar de los valores (
a,
A =
ga) y (
b,
B =
gb) que generan cliente y servidor durante el
algoritmo,
tal y como se muestra en el siguiente esquema (imagen original de
Wikipedia), donde Alice sería el cliente, Bob el servidor y Mallory
nuestro proxy.
En caso de utilizarse la variante no autenticada de Diffie-Hellman (
DH_anon),
con eso será suficiente. Si, como se hace normalmente, sí se autentica
el intercambio, el proxy tendrá que cambiar el certificado que envía
el servidor. En los esquemas definidos como DH, el valor B enviado por
el servidor es fijo (contenido en el certificado del servidor);
mientras que en los definidos como DHE (la E viene de
efímero),
este valor se genera aleatoriamente en cada negociación y es firmado
por el servidor (con la clave privada asociada a su certificado). Por
tanto, la intercepción variará también dependiendo de si el algoritmo es
DH o DHE. No obstante, de todo esto se encarga el proxy, ya que
negocia sesiones SSL de forma independiente con cliente y servidor.
En cualquier caso, dejando de lado la teoría, una vez esté en marcha el
proxy, nosotros sólo tendremos que introducir en Wireshark la clave
adecuada. Esto se puede hacer desde "
Edit > Preferences > Protocols > SSL > RSA keys list > Edit",
podemos indicar dónde están las claves RSA utilizadas durante la
negociación (por lo tanto, para esta variante, Wireshark permite el
descifrado cuando SSL intercambia claves usando RSA).
En este caso, salvo que instalemos en los navegadores la CA que hemos
utilizado para firmar los certificados, se generarán alertas en los
navegadores (por no confiar en la CA o gracias a técnicas como el
certificate pinning).
En cualquier caso, como lo que queremos es descifrar nuestro propio
tráfico, no hay problema con esto: simplemente ignoramos las
advertencias del navegador, y continuamos.
La ventaja de esta opción es que permite ampliar el análisis a
múltiples máquinas (todas las que pasen por el proxy), lo cual puede ser
útil en incidentes en los que no se sabe qué máquinas pueden estar
afectadas, aunque el setup puede ser algo más complicado.
Ejemplos
La siguiente captura muestra una conexión a https://www.inteco.es (la
dirección IP 195.53.165.3) interceptada con Squid, desplegado como
proxy local en la misma máquina que el cliente. Como se puede observar,
Wireshark descifra automáticamente el tráfico SSL entre cliente y
proxy. También se ve cómo se hacen dos negociaciones SSL: los mensajes
290, 340 y 347 corresponden a la negociación entre el servidor de
INTECO y el proxy, mientras que los mensajes 322, 324, 326 y 328
pertenecen a la negociación entre cliente y proxy.
La intercepción se observa también por el hecho de que el certificado
mostrado por el navegador (izquierda) no es el original (derecha):
Fuente:
INTECO