Camuflaje en la capa de cifrado: domain fronting

En la entrada de hoy hablaremos sobre una técnica relativamente vieja (aunque programas como Signal la han empezado a utilizar hace relativamente poco) y que siempre me ha parecido un hack muy “astuto”: el domain fronting.

Por ejemplo, tomemos la dirección IP del frontal que nos sirve www.google.es:

$ host www.google.es
www.google.es has address 216.58.210.227

Vamos a fijarnos en el campo Common Name (CN) del certificado TLS que nos devuelve el servidor:

$ echo | openssl s_client -CApath /usr/lib/ssl -connect 216.58.210.227:443 | openssl x509 -subject 
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
DONE
subject= /C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
-----BEGIN CERTIFICATE-----
MIIgWjCCH0KgAwIBAgIIHcanliJsJ+UwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
[...]

Vemos que no es www.google.es. Este certificado está autenticando un nombre que no está presente en su CN.

Si utilizamos el subcomando x509 para obtener más información sobre el certificado, nos toparemos con la explicación:

$ echo | openssl s_client -CApath /usr/lib/ssl -connect 216.58.210.227:443 | openssl x509 -text
[...]
        X509v3 extensions:
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Alternative Name: 
                DNS:google.com, DNS:*.2mdn.net, DNS:*.android.com, DNS:*.appengine.google.com,
                DNS:*.au.doubleclick.net, DNS:*.cc-dt.com, DNS:*.cloud.google.com,
                DNS:*.de.doubleclick.net, DNS:*.doubleclick.com
[...]

El servidor HTTPS está utilizando la extensión Subject Alternative Name (SAN), que hace posible servir más de un sitio web por HTTPS sobre la misma dirección IP utilizando un solo certificado X.509.

Además, en la parte del cliente HTTPS, podemos utilizar otra extensión más reciente (en este caso del protocolo TLS, no del estándar X.509) llamada Server Name Indication (SNI) para “pedir” cualquiera de los virtual host disponibles en la misma dirección IP.
Podemos indicarle al subcomando s_client (modificador -servername) que utilice esta extensión para pedir uno de los otros nombres disponibles; por ejemplo, mail.google.com:

$ echo | openssl s_client -CApath /usr/lib/ssl \
  -connect 216.58.210.227:443 -servername mail.google.com | openssl x509 -subject 
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = mail.google.com
verify return:1
DONE
subject= /C=US/ST=California/L=Mountain View/O=Google Inc/CN=mail.google.com
-----BEGIN CERTIFICATE-----
MIID1jCCAr6gAwIBAgIIGOTyaAwrvk4wDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
[...]

Si observamos una captura de la anterior interacción con Wireshark, veremos claramente el campo con la extensión SNI. El cliente le ha indicado al servidor (en el mensaje ClientHello del handshake de TLS) que “quiere” el virtual host del servicio GMail:

De hecho, en el caso de Google (cosa que ocurre también con muchas otras redes CDN o servidores frontales, de ahí el nombre de la técnica: domain fronting), no es necesario ni siquiera utilizar la extensión SNI de TLS, sino que basta con apuntar contra la misma IP, pero especificando una cabecera HTTP Host con el virtual host deseado:

$ wget -q -S --max-redirect=1 --header 'Host: mail.google.com' www.google.es
  HTTP/1.1 301 Moved Permanently
  Location: /mail/
  Content-Type: text/html; charset=UTF-8
[...]

Por lo tanto, como resultado del comando anterior, alguien monitorizando la red sólo “vería” una petición a www.google.es: el tráfico de las interacciones con mail.google.com quedaría dentro, “camuflado” en la capa TLS, a no ser que “rompamos” dicha capa con generación dinámica de certificados desde una raíz de certificación presente en las estaciones de trabajo (incluso en este último caso, cosas como certificate pinning le pondrían las cosas difíciles a quien trate de hacer el MitM).

Pero, en el fondo, ¿qué ventaja aporta esto? Está claro, Google utiliza los mismos frontales para todo. ¿Qué interés puede tener el camuflar el tráfico hacia/desde GMail como tráfico “genérico” de búsquedas en Google? Pues si montamos el servidor de mando y control o exfiltración a través de GMail, ya podría ser una ventaja, pero la cosa va más allá: las aplicaciones de Google App Engine (GAE, dominios *.appspot.com, entre otros), también se sirven con estos frontales.

Por lo tanto, en este caso concreto, ya no es que podamos desplegar nuestro C&C basándolo en el servicio web de GMail, es que lo podemos desplegar directamente como una app de GAE en miservidorc2.appspot.com, y la monitorización de red ni siquiera vería las resoluciones DNS de ese nombre (sólo vería DNS asociado con www.google.es y tráfico TLS supuestamente de búsquedas).

Y lo que es mejor: para “chaparnos la paraeta”, o bien Google detecta de algún modo que tenemos un C&C ilegítimo en miservidorc2.appspot.com, o bien el equipo de vigilancia de red tiene que “romper” HTTPS (o filtrar todo el tráfico HTTPS en general, o no permitir accesos por HTTPS a Google, ni ninguno de sus frontales, en particular). Esto no va a sentar bien a ninguna organización del mundo: ¿no se pueden buscar cosas en Google?
Mal vamos… ;-) Y por eso esta técnica es tan potente: eliminar los frontales supone eliminar muchos servicios útiles y es una acción que tiene asociado un elevado daño colateral. Por esta razón es una técnica muy empleada para saltarse filtros de contenidos, DPI, etc. La utilizan herramientas como Lantern, Psiphon, como se ha mencionado Signal, y algunos pluggable transports para Tor, como Meek.

Sin buscar demasiado :-) podemos encontrarnos diversos “artilugios” que se monta la gente por ahí… Por ejemplo, aquí tenemos un “reflector” de Twitter:

$ wget -qO- https://3benben.appspot.com
    <html>
        <head>
        <title>GAE Twitter API Proxy</title>
        <link href='https://appengine.google.com/favicon.ico' rel='shortcut icon' type='image/x-icon' />
        <style>body { padding: 20px 40px; font-family: Verdana, Helvetica, Sans-Serif; font-size: medium; }</style>
        </head>
        <body><h2>GTAP v0.4.2 is running!</h2></p>
        <p><a href='/oauth/session'><img src='/static/sign-in-with-twitter.png' border='0'></a> <== Need Fuck GFW First!! 
        or <a href='/oauth/change'>change your key here</a></p>
        <p>This is a simple solution on Google App Engine which can proxy the HTTP request to twitter's official REST API url.</p>
        <p><font color='red'><b>Don't forget the "/" at the end of your api proxy address!!!.</b></font></p>
    </body></html>

Con él, podemos visitar la cuenta de SecurityArtWork :-) sin tan siquiera tocar Twitter directamente (obviamente, el reflector se “queda” con todas nuestras peticiones; mucho ojo):

$ wget -O- --header='Host: 3benben.appspot.com' \
    https://www.google.es/securityartwork |
    fgrep description | head -1
[...]
  <meta name="description"
  content="The latest Tweets from Security Art Work (@Securityartwork).
  Information Security Blog 
#infosec #cybersecurity #hacking
  #intelligence
S2Grupo Company @s2grupo · s2grupo.es.
  España, Mexico, Colombia">
[...]

Esto podría funcionar desde países o redes donde se haya bloqueado el acceso a Twitter, pero en los que por la razón que sea no haya sido posible bloquear el acceso a los frontales HTTPS de Google ;-)

Hay muchas más redes CDN que pueden (ab)usarse de este modo; por ejemplo, Meek permite utilizar un reflector hospedado en Amazon CloudFront que redirige a un bridge de Tor:

$ wget -qO- https://a0.awsstatic.com/ --header 'Host: d2zfqthxsdq309.cloudfront.net'
I’m just a happy little web server.

De este modo, sería posible utilizar la red Tor, y “desde fuera” lo único que se “vería” son accesos HTTPS al frontal a0.awsstatic.com, utilizado para muchísimas otras cosas.
Y lo mismo con la CDN de Microsoft Azure:

$ wget -qO- https://ajax.aspnetcdn.com/ --header 'Host: az786092.vo.msecnd.net'
I’m just a happy little web server.

Del mismo modo que podíamos hospedar nuestro servidor de C2/exfiltración en Google App Engine, los dos anteriores ejemplos muestran que lo mismo podemos hacer si contratamos un VPS de forma anónima en CloudFront o Azure. Podemos utilizar esta técnica para enmascarar cualquier tipo de tráfico, que “por fuera” parecerá un acceso habitual al frontal correspondiente.

Por lo tanto, mucho ojo con contactos con CDN y frontales: no siempre son lo que parecen :-) Desde el desconocimiento de quien escribe (¡cualquier información es bienvenida!), no se ha publicado información de ningún APT que utilice esta técnica concreta, pero mucho me extrañaría que no se tratara de una práctica habitual para evadir controles egress (sí que hay documentados varios casos en los que se han utilizado servicios como Google Docs, Google Drive, Google Apps Script, etc. para C&C, pero hasta donde hemos visto de momento no utilizaban domain fronting, es decir, no ocultaban el acceso a dominios como docs.google.com, lo cuál sería un paso más allá).

Por supuesto, se trata de una técnica relativamente fácil de detectar utilizando análisis de tráfico (aunque el dominio que veamos sea el del frontal, el tráfico es el de “dentro”, y eso debe provocar la correspondiente firma en los paquetes, sus tamaños y timings, que será más o menos difícil de identificar) y de anomalías (como caso sencillo, si aunque se utilice domain fronting no se asegura que el fingerprint del cliente TLS sea el habitual, se detectará fácilmente), pero eso ya es otra historia… ;-)

¡Un saludo y hasta el próximo post! @pmarinram

Material interesante

Comments

  1. Ramón Onrubia says:

    Excelente post Pablo. Demuestra que una vez más, cualquier funcionalidad añadida a una tecnología – en este caso la posibilidad de hacer virtual hosts por https con distinto fqdn sociado al mismo CN y certificado SSL/TLS – provocan la aparición de nuevos vectores de ataques.

  2. Muchas gracias por tu comentario, Ramón. Me alegro de que te haya gustado el post. ¡Un saludo!