Cuando al que te ataca sólo le interesa obtener resultados sin entender nada, se lo llama "script kiddie". Es una subcategoría despreciada por los hackers, tanto white hat como black hat ("buenos" y "malos")[1].
Gracias a JP (http://scvsoft.com/) y a Walter Villalba de OWASP (www.linkedin.com/in/waltvillalba) por las correcciones y sugerencias.
Se qué estamos todos apurados y que sólo nos interesa arreglar el problema sin entender nada, pero yo no soy nadie para juzgar, así que primero voy a dar las recetas y luego podés elegir dejar de leer.
Si sos un usuario final, el ataque pudo haber obtenido tus contraseñas en algunos sitios como:
- tumblr
- google (incluyendo gmail)
- yahoo (incluyendo yahoo mail)
- dropbox
- minecraft
- netflix
Al final de la entrada hay un link a una lista. Quizás sea menos trabajo simplemente cambiar todas las contraseñas, algo que de todos modos es una buena práctica hacer periódicamente.
Si sos webmaster, desarrollador, TI, podés seguir el siguiente procedimiento:
- hay encriptación, ya sea web, sip, vpn o lo que sea que use TLS?
- la provee openssl?
- con version 1.0.1 o 1.0.2-beta?
- tiene activado heartbeat?
- ejecutar algún script de comprobación web o cli
- actualizar openssl
- Si el paso 5 dió positivo, hay que renovar los certificados, que deben estar basados en un nuevo par de claves asimétricas
- reiniciar los servidores que utilizan openssl
Si no tenés ganas de pensar, comenzá directo en 5) . Si evaluás que lo vas a corregir inmediatemente, podés usar las herramientas web. Si realmente no tenés ganas de pensar, elegí según tu distro y reiniciá a la windows:
- apt-get update && apt-get upgrade ; # debian y derivados (ubuntu, mint)
- yum update ; # red hat y derivados (fedora, centos)
- zypper update ; # suse
Si compilaste por tu cuenta es que tenés ganas de pensar y no necesitás que te diga que tenés que obtener la versión actualizada de OpenSSL, recompilar lo que haga falta y reiniciar lo que haga falta. A menos que hayas compilado con heartbeat desactivado.
¿Por qué prefiero las herramientas cli? Mera desconfianza, aunque estoy casi seguro de que confiar sería seguro, ¿cómo podés saber que tu consulta no es utilizada para armar una base de datos de sitios vulnerables?
Con mayor profundidad...
He intentado hacer bloques con títulos que reflejen la complejidad y a quién está dirigido.Descripción de la vulnerabilidad
OpenSSL es una librería criptográfica muy utilizada para encriptar las comunicaciones. Encriptar las comunicaciones significa hacerles un proceso mediante el cual los que no participan no pueden entenderlas. Esto no quita que quienes esten afuera no puedan saber quienes se comunican (anonimato) ni que no puedan hacer un análisis de tráfico.
Estar dentro de la comunicación significa tener la clave con la cual se encripta y desencripta la comunicación. Esta clave es distinta de la que se usa para que uno se autentique, la que la persona escribe. Hay otra clave más que tiene que ver con el establecimiento de la comunicación y que es muy especial, pues son dos claves, una pública y otra privada. Como la clave pública es pública ya la tenemos, nos interesaría obtener la privada. Con ella, podríamos obtener la clave con la que se encripta y desencripta la comunicación (que es distinta para cada comunicación) y de ahí la clave de la autenticación del usuario, por ejemplo al home banking. Esto no se limita a la comunicación actual si no a cualquiera que pueda haber sido capturada en el pasado.
La clave privada tambien es interesante pues nos permite meternos en el medio o incluso hacernos pasar por un sitio de modo indetectable.
Apache y Nginx son servidores web que usan OpenSSL pero no hay que excluir cualquier otro servicio como mysql, postgres, postfix, imap, pop3 que pueda estar usando criptografía en las comunicaciones.
Heartbeat[2] es una extensión a los protocolos TLS y DTLS para mantener una conexión y evitar tener que estar reconectando. La idea es que establecer una conexión segura implica bastante trabajo e intercambio de mensajes para los participantes. Con esta extensión se puede mantener abierta la comunicación sin que haya tráfico permantente.
En los mensajes de Heartbeat, hay una parte que tiene longitud variable y la vulnerabilidad de OpenSSL en las versiones afectadas consiste en no controlar que la longitud declarada corresponda con la real. Esto permite producir un error en la librería y obtener un volcado de partes de la memoria de trabajo. En ese volcado pueden haber partes de los mensajes con cookies de sesión o la clave de encriptación, ambas con valor efímero, pares user/password o lo mejorcito que son las claves privadas utilizadas por la aplicación.
Hay una ilustración bien gráfica en http://xkcd.com/1354/ (gracias Gloria B.)
Ahora, ya estás en condiciones de entender Heartbeat -> HeartBleed
El alcance como usuario final
Como usuario final nos interesa saber si nuestras credenciales han sido comprometidas. Eso es una ruleta y hay alguna probabilidad si tras haberse uno autenticado ha habido un ataque.
Menos ruleta es que si hubo un ataque mientras uno estuvo comunicándose, nuestros mensajes pudieron haber sido vistos. Pero a la vez es menos riesgoso, pues es muy difícil rearmar una comunicación probablemente incompleta.
Si la clave privada ha sido comprometida y el atacante tiene la capacidad de ver todo el tráfico, listo, perdiste tus claves y toda la privacidad con respecto a esa aplicación o servicio. Si no tiene esa capacidad pero te está atacando a tí, puede hacerte MITM, pero, ¿quién se tomaría tanto trabajo en atacarte?
Con respecto a las listas que hay de servicios vulnerables, es importante tener en cuenta que la vulnerabilidad existe desde hace dos años y que puede haber evidencia de explotación desde noviembre del 2013[3], asi que las listas representan el estado en un momento determinado, algunos de los sitios que ahora figuran ok pudieron haber estado vulnerables en algún momento.
ACTUALIZACIÓN: a las seis horas que pasaron desde que publiqué esto, ya apareció algo nuevo[4].
Un caso extremo es yahoo y lo sé por que me fijé si era vulnerable y me dió que sí, a la media hora quise corroborar y ya estaba corregido. Lo cual no significa que hayan corregido los certificados. Para comprobarlo hay que pedirle al browser ver los detalles del certificado.
El alcance como proveedor, web master, desarrollador
Como proveedor, en fulldisclosure hay un muy buen consejo: "As a general rule of thumb for this vulnerability, any binary/service dynamically linked to libssl.so should be considered compromised"[5], que yo lo extendería a compilado estático y a cualquier script que haya usado la versión vulnerable.
Para saber qué openssl hay, lo mejor es preguntarle:
$> openssl version
Para saber quienes usan openssl enRed Hat/SuSE y derivados (Fedora, Centos), tendría que haber algo sencillito pero no lo pude hallar, así que hice esto:
rpm -qa | while read package ; do
rpm -q $package --requires | grep ssl > /dev/null
if [ $? -eq 0 ]; then
echo == $package ==
rpm -q $package --requires | grep ssl
echo
fi
done
(puede ser que esté mal, lo hice en un SuSE y ahora no tengo donde probarlo, quizás el grep sea openssl o libssl en lugar de ssl)
Con respecto a Debian y derivados (Ubuntu, Mint), es parecido pero peor y no lo he podido hacer andar. Si alguien tiene la gentileza de enviarlo, lo pondré. Se parece a:
# NO FUNCIONA
dpkg --get-selections | \
sed -e "s/[ \t]\+/ /g" | \
cut -d" " -f 1 | while read package; do
apt-cache showpkg $package | grep ssl > /dev/null
if [ $? -eq 0 ]; then
echo == $package ==
apt-cache showpkg $package | grep ssl
echo
fi
done
#NO FUNCIONA
Un problema que ocurre es que el ataque a nivel aplicación es indetectable. No aparece en el log de la aplicación. Podría aparecer en logs de firewalls, pero no sé cual es la retención habitual.
Consecuencias para proveedores, web masters, desarroladores.
Si la vulnerabilidad fue introducida a propósito, el que lo hizo dice que no[6], o fue descubierta al poco tiempo, hay que renovar todos los certificados de cualquier sitio que haya sido vulnerable. Esto es algo que se irá determinando en los próximos días a medida que se exploren los logs.
Alguien podría decirme (y lo ha hecho) que las agencias gubernamentales seguramente tengan copias de todos las claves privadas importantes y ¿qué le podría decir? Es desalentador, pero sigamos jugando como si no fuera así.
Hay un aspecto que sólo he leido mencionado superficialmente al pasar en un solo lugar y aún no le han prestado suficiente atención por que todo el mundo está corriendo detrás de los servidores, que es que la vulnerabilidad no es de los servidores, es de la librería. Esto implica que si el navegador o aplicación que uno usa se conecta a un sitio malicioso, este podría obtener volcados tambien. El verificador ssl de cliente que uso (aún) no verifica[7] o al menos nada dice.
Pero a medida que pasan las horas, hay nuevas noticias [8]
Aprendizaje para quienes saben programar
Como es costumbre, vamos a aprender algo de este desastre.
El objetivo del ejercicio es capturar un poco de tráfico de un sitio vulnerable y luego desencriptarlo.
Primero hay que hallar un sitio vulnerable y capturar un poco de tráfico, por ejemplo con wireshark. Se puede usar el siguiente filtro:
"tcp.port eq 443 and ip.dst eq XX.XX.XX.XX"
Luego, no a la vez pues si no capturaremos el tráfico del ataque que no nos interesa, ejecutar alguno de los scripts que circulan por ahí, por ejemplo hb-test.py, que no sólo te dice si el sitio es vulnerable sino que hace el ataque y el vuelco de memoria en formato hexdump, al que luego hay que convertir en binario. Tambien se puede utilizar un script que salve en formato binario directamente o modificar hb-test.py.
De un modo u otro, hay que detectar que suite criptográfica se usa, como por ejemplo donde dice SSL-Session: -> Cipher tras ejecutar
openssl s_client -connect domain:port
y elegir la herramienta apropiada para extraer la clave. La idea es que las claves presentan un cierto patrón detectable.
Con una menor ambición, con el comando strings y grep se pueden obtener claves de la aplicación.
Mi experiencia fue obtener ~30k muestras y usé estos scripts para obtener el binario a partir de la salida de hb-test.py
[hex2bin.sh]
for file in dumps/*; do
fn=$(basename $file .dump)
./hex2bin.py < $file > buffers/${fn}.hex
done
[hex2bin.py]
#!/usr/bin/python2
import fileinput
import sys
def translate(line):
line = line[6:54]
for i in xrange(0,48,3):
sys.stdout.write(line[i:i+2].decode('hex'))
state = "seeking"
for line in fileinput.input():
line = line.strip()
if state=="seeking" and line=="Received heartbeat response:":
state = "translating"
elif state == "translating":
if line == "" :
break
else:
translate(line)
Luego, ejecuté
for file in buffers/*; do aeskeyfind $file; done > aeskeys.txt 2>&1
y como no salió nada y tanto no sé:
for file in buffers/*; do rsakeyfind $file; done > rcakeys.txt 2>&1
Las búsquedas con string y grep tampoco fueron provechosas, pero era de esperar, ya que el sitio carece de autenticación.
Pude identificar que hay codeigniter, symfony, cosa que ya sabía pues mio es el sitio, quizás dos cookies de sesión, triste, quizás hagan falta más muestras o un sitio con otro tipo de tráfico.
ACTUALIZACIÓN: según un challenge que hubo[9], hacen falta muchas más muestras que las que tomé, así que es mejor hacerlo en una red local con un servidor dedicado y parece que tomar las muestras cerca de un reinicio mejora las probabilidades, si es que no es indispensable.
ACLARACIÓN: he sido lo más cuidadoso posible, pero este no es un tema que domine particularmente y pude haber cometido algún error. En caso de ser así, por favor no dudés en señalarlo.
Recursos online
Listas, estadísticas y anuncios
- http://mashable.com/2014/04/09/heartbleed-bug-websites-affected/
- http://googleonlinesecurity.blogspot.com.ar/2014/04/google-services-updated-to-address.html
- http://news.netcraft.com/archives/2014/04/08/half-a-million-wid ely-trusted-websites-vulnerable-to-heartbleed-bug.html
- https://github.com/musalbas/heartbleed-masstest/blob/master/top 10000.txt
Herramientas web
- http://possible.lv/tools/hb/
- https://github.com/FiloSottile/Heartbleed
- https://www.ssllabs.com/ssltest
- https://sslcheck.globalsign.com/en_US
- https://lastpass.com/heartbleed/
- http://www.hut3.net/blog/cns---networks-security/2014/04/14/bugs-in-heartbleed-detection-scripts-
- http://www.theguardian.com/technology/2014/apr/16/heartbleed-bug-detection-tools-flawed
Herramientas cli
- https://gist.github.com/takeshixx/10107280
- https://github.com/musalbas/heartbleed-masstest/blob/master/ssl test.py
Información general y análisis
- http://heartbleed.com/
- https://www.schneier.com/blog/archives/2014/04/heartbleed.html
- http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html
Referencias
- http://www.urbandictionary.com/define.php?term=script+kiddie
- https://tools.ietf.org/html/rfc6520 - Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension
- https://www.eff.org/deeplinks/2014/04/wild-heart-were-intelligence-agencies-using-heartbleed-november-2013
- http://www.bloomberg.com/news/2014-04-11/nsa-said-to-have-used-heartbleed-bug-exposing-consumers.html
- http://seclists.org/fulldisclosure/2014/Apr/139
- http://www.smh.com.au/it-pro/security-it/man-who-introduced-serious-heartbleed-security-flaw-denies-he-inserted-it-deliberately-20140410-zqta1.html
- https://www.howsmyssl.com/
- http://www.bloomberg.com/news/2014-04-11/millions-of-android-devices-vulnerable-to-heartbleed-bug.html
- http://blog.cloudflare.com/the-results-of-the-cloudflare-challenge
No hay comentarios:
Publicar un comentario