Actualités :
14/05/2010 - Nouvelle fonctionnalité : devis en ligne !
30/04/2010 - Un exemple de Blind SQL Injection : Vulnérabilité Cacti
26/03/2010 - Forensics : un cas réel d'intrusion
22/02/2010 - Nos nouvelles offres : ToIP, VPN, Pont Hertzien et Forensic
29/01/2010 - Suivez nos Tweets
17/09/2009 - Debug VPN sous CheckPoint SecurePlatform
16/09/2009 - Activation des modules Apache sur Ubuntu 8.0.4 Server
04/09/2009 - Support du FTP passif sur un serveur protégé par iptables/netfilter
01/09/2009 - Linux Guru Wanted !
28/07/2009 - Désactiver la méthode TRACE sur Apache
20/07/2009 - Copier avec écrasement en mode non interactif
14/07/2009 - Connaitre la version de son Linux
28/03/2009 - NIST lance le concours pour SHA-3
17/01/2008 - Newsletter Janvier 2008
07/01/2008 - Monter un environnement PXE en 5 minutes
05/01/2008 - Google fabrique son propre switch 10Gb
15/12/2007 - wfuzz, un fuzzer HTTP
15/11/2007 - Newsletter Novembre 07
23/10/2007 - Un audit sécurité wifi
25/06/2007 - Visioconférences IP au travers de firewalls
12/06/2007 - Monter un serveur FTP sécurisé
10/05/2007 - Methodes AntiSpam
19/04/2007 - Proxy SNMP
13/03/2007 - NBAR, une fonctionnalité méconnue
04/03/2007 - Déchiffrer une session SSL : méthodes et limitations
24/02/2007 - LoadBalancer : Algorithmes de répartition
22/02/2007 - Rebond sur un PIX : évolutions au fil des versions
19/02/2007 - Apple se moque de la sécurité de Vista
25/01/2007 - Mesure réseau sous Linux
20/01/2007 - Load-Balancers : Introduction

 

 

 

Vous pouvez également retouver d'autres articles sur notre blog ou sur Twitter .

 

04/03/2007 - Déchiffrer une session SSL : méthodes et limitations

Tout le monde connait l'analyseur réseau Ethereal et son successeur Wireshark. Une des nouveautés de la version 0.99.5 est le déchiffrement de flux SSL dans certaines conditions.

 

Cette fonctionnalité est très intéressante car elle permet enfin de pouvoir analyser le trafic SSL à l'aide d'un sniffer que ce soit sur un serveur ( la plupart du temps HTTPS mais également LDAPS, POPS, SFTP, etc.. ) en production ou bien sur un port de recopie d'un flux (grâce à la fonction de mirroring d'un switch ou bien encore l'usage d'un tap physique).

 

Au niveau du client, il existe d'autres possiblités en utilisant des proxy (tels que l'excellent outil WebScarab de l'OWASP) on bien du tunneling SSL (avec stunnel par exemple).

 

Pour être tout à fait exhaustif, l'outil ssldump permettait déjà d'obtenir ce genre d'information, mais en shell. Son intégration à WireShark permet ainsi de suivre aisément et graphiquement les segments TCP, acknowledgements, retransmissions, etc..

 

Pour mettre en pratique cette fonctionnalité nous allons déchiffrer le flux HTTPs d'un serveur de test. Tout d'abord créeons le matériel crypto :

 

Nous générons un bi-clé RSA  de 1024 bits :

 

# openssl genrsa -out server.key 1024

Generating RSA private key, 1024 bit long modulus

.......++++++ .++++++

e is 65537 (0x10001)

 

Notez la valeur de "e" : pour rappel, on a "ed= 1 mod (p-1)(q-1)" avec p et q grands nombre premiers choisis aléatoirement .

La valeur "pq" est la clef publique et "d" la clef privée. Bien que théoriquement libre, la valeur de "e" choisie par la plupart des implémentations est 3 , 5, 17 ou bien 65537.

 

# openssl rsa -in server.key -out server.pem

 

Nous créeons maintenant le CSR (Certficate Signing request) :

 

# openssl req -new -key server.key -out server.csr

You are about to be asked [..]

Country Name (2 letter code) [GB]:FR

State or Province Name (full name) [Berkshire]:Paris

Locality Name (eg, city) [Newbury]:75008

Organization Name (eg, company) [My Company Ltd]:RandCo

Organizational Unit Name (eg, section) []:IT

Common Name []:test.randco.fr

Email Address []:

 

 

Comme nous sommes dans un environnement de test, nous autosignons ce CSR pour obtenir le certificat :

 

# openssl x509 -req -in server.csr -signkey server.key -out server.crt

Signature ok

subject=/C=FR/ST=Paris/L=75008/O=RandCo/OU=IT/CN=test.randco.fr

Getting Private key

 

Nous obtenons ainsi une clé privée server.key et un certificat server.crt. Configurons ensuite Apache : nous ajoutons dans httpd.conf (au niveau du virtual host écoutant sur le port 443) ceci :

 

DocumentRoot /usr/local/apache2/htdocs

ServerName test.randco.fr SSLEngine on

SSLCertificateFile /usr/local/apache2/etc/ssl.crt/server.crt

SSLCertificateKeyFile /usr/local/apache2/etc/ssl.key/server.pem

 

Cependant SSL n'est pas supporté par la version du binaire httpd actuel :

 

# httpd -l | egrep -i "(ssl|so)"

mod_so.c

#

 

Etant donné que nous utilisons Apache2, nous devons donc juste le recompiler en activant l'option --enable-ssl (contrairement à Apache 1.3 pour lequel le module mod_ssl est distribué à part) :

 

# ./configure --enable-ssl

# make

# make install

# httpd -l | egrep -i "(ssl|so)"

mod_ssl.c

mod_so.c

# apachectl -k restart

 

Une fois que le flux HTTPs aura été capturé par Wireshark, regardons comment configurer le déchiffrement dans Wireshark :

dans le menu Edit > Preferences > Protocols > SSL , remplir les champs comme suit :

  • RSA keys list : les champs séparés par une virgule sont l'adresse IP du server, port TCP, protocole applicatif sous-jacent , chemin vers la clé privée
  • SSL debug file : chemin vers l'indispensable fichier de debug

SSL capture with Etthereal

 

En appliquant un "SSL follow", on peut suivre la session et récuperer le contenu de la session en clair :

 

 

Pour tester à votre tour, voici la clé privée et le fichier de capture de la session HTTPS réalisée avec IE6. Les limitations de ssldump et de la méthode demeurent cependant :

  • AES n'est supporté que dans la version CVS de ssldump (donc non intégrée à Wireshark)

 

  • tous les flux chiffrés avec des Cipher Suite mettant en oeuvre un échange de clé du type Diffie-Helmann Ephemere (DHE) (en opposition avec RSA et Diffie Hellman statique - DH) restent évidemment indéchiffrables ( ceci en est d'ailleurs le but : cet algorithme reste toutefois sensibles aux attaques Man in the Middle. C'est la méthode choisie par Webscarab ou d'autres proxy tels que Spike Proxy ou Burp Proxy. Evidement, ce genre de manipulation provoque une alerte SSL au niveau du client : "certificat invalide"  !).

    La capture précédente était réalisée avec MS IE 6 (à jour de patches), le Cipher Suite négocié était TLS_RSA_WITH_RC4_128_MD5. Si on utilise d'autres outils (notamment Open Source tels que Firefox ou lwp-request, basé sur Perl) des Cipher Suite beaucoup plus forts seront négociés automatiquement :

 

# lwp-request -des https://localhost

200 OK

Connection: close

Server: Apache/2.0.53 (Unix) mod_ssl/2.0.53 OpenSSL/0.9.7a PHP/4.3.10 mod_perl/2 .0.1 Perl/v5.8.6

Content-Length: 2271

Content-Type: text/plain

Client-Peer: 127.0.0.1:443

Client-Response-Num: 1

Client-SSL-Cert-Issuer: /C=FR/ST=Paris/L=75008/O=RandCo/OU=IT/CN=test.randco.fr

Client-SSL-Cert-Subject: /C=FR/ST=Paris/L=75008/O=RandCo/OU=IT/CN=test.randco.fr

Client-SSL-Cipher: DHE-RSA-AES256-SHA

Client-SSL-Warning: Peer certificate not verified

 

Ce qui donne avec ssldump (version CVS) et le fichier de capture obtenu via :

 

# tcpdump -n tcp port 443 -i lo -w https2.cap -s 16436 &

 

(remarquez la taille des paquets à capturer inhabituellement grande : le MTU de l'interface de loopback est de 16436 octets !) :

 

# ./ssldump -r https2.cap -k server.key

New TCP connection

#1: 127.0.0.1(52260) <-> 127.0.0.1(443) 1 1 0.0004 (0.0004)

C>S SSLv2 compatible client hello Version 3.1 cipher suites

TLS_DHE_RSA_WITH_AES_256_CBC_SHA

TLS_DHE_DSS_WITH_AES_256_CBC_SHA

TLS_RSA_WITH_AES_256_CBC_SHA

TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA

TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA

TLS_RSA_WITH_3DES_EDE_CBC_SHA SSL2_CK_3DES

TLS_DHE_RSA_WITH_AES_128_CBC_SHA

TLS_DHE_DSS_WITH_AES_128_CBC_SHA

TLS_RSA_WITH_AES_128_CBC_SHA SSL2_CK_RC2

TLS_DHE_DSS_WITH_RC4_128_SHA TLS_RSA_WITH_RC4_128_SHA

TLS_RSA_WITH_RC4_128_MD5 SSL2_CK_RC4 SSL2_CK_RC464

TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA

TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA

TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5

TLS_DHE_RSA_WITH_DES_CBC_SHA

TLS_DHE_DSS_WITH_DES_CBC_SHA

TLS_RSA_WITH_DES_CBC_SHA SSL2_CK_DES

TLS_DHE_DSS_WITH_RC2_56_CBC_SHA

TLS_RSA_EXPORT1024_WITH_RC4_56_SHA

TLS_RSA_EXPORT1024_WITH_RC4_56_MD5

TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA

TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA

TLS_RSA_EXPORT_WITH_DES40_CBC_SHA

TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5

SSL2_CK_RC2_EXPORT40

TLS_RSA_EXPORT_WITH_RC4_40_MD5

SSL2_CK_RC4_EXPORT40 1 2 0.0205 (0.0201)

S>C Handshake ServerHello Version 3.1 session_id[0]= cipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA

 

Ce qui veut donc dire TLS (SSL v3.1) avec échange de clés Diffie Hellman Ephemere  , algorithme de chiffrement par bloc AES  256 bits et hashage par SHA 

 

compressionMethod NULL 1 3 0.0205 (0.0000)

S>C Handshake Certificate 1 4 0.0205 (0.0000)

S>C Handshake ServerKeyExchange 1 5 0.0205 (0.0000)

S>C Handshake ServerHelloDone 1 6 0.0531 (0.0325)

C>S Handshake ClientKeyExchange

DiffieHellmanClientPublicValue[128]= 7d 96 7e c0 16 ff 1b 63 26 4d 5a 1a b6 0e 16 62 e9 8d dd d6 a0 45 07 d2 51 50 61 d9 26 14 3b 3f bd 77 c5 66 ba 99 26 7e dc 52 c5 1c f2 72 2c dc 24 17 1e 58 a8 45 0d 46 3e 42 da 45 ad 1a c2 e2 87 c3 b8 3b 0f cc 12 c6 6b 98 db 25 7f da 37 8d f7 02 06 95 64 54 94 ec 57 eb 82 e3 76 ab 80 2d a6 da a2 d8 b3 51 a8 29 65 9c 35 fb 81 91 6f 91 e7 ab a9 75 f4 55 b1 30 09 97 13 29 fb a0 a6 a4 1 7 0.0531 (0.0000)

C>S ChangeCipherSpec 1 8 0.0531 (0.0000)

C>S Handshake 1 9 0.0697 (0.0165)

S>C ChangeCipherSpec 1 10 0.0697 (0.0000)

S>C Handshake 1 11 0.0700 (0.0003)

C>S application_data 1 12 0.0700 (0.0000)

C>S application_data 1 13 0.0703 (0.0003)

S>C application_data 1 14 0.0705 (0.0001)

S>C application_data 1 0.0716 (0.0011)

C>S TCP FIN 1 15 0.0717 (0.0001)

S>C Alert

 

Pour rappel, la valeur publique de l'échange Diffie Helman est "A = g^a mod p" avec un générateur "g" et un nombre premier "p" fixés suivant le groupe DH sélectionné. (dans le cas présent DHE - Diffie Hellman en mode éphémère - cette valeur publique est signée à l'aide du certificat serveur afin de se prémunir des attaques Man in the Middle)

Le nombre aléatoire "a" est seul connu de l'extremité qui publie A. Grâce à la théorie du logarithme discret, on sait qu' il est impossible (lire : long) connaissant "A","p" et "g" de déterminer "a".

Or "a" ( ou plus exactement "A^b mod p = B^a mod p") est utilisé pour construire la clé de session qui chiffrera le flux avec l'algorithme de chiffrement sélectionné (stream cipher RC4 ou bien block cipher AES dans les cas de ce présent article).

 

Ceci explique que ssldump ne puisse obtenir la clé de session uniquement en observant le traffic et en connaissant la clef privée RSA si ce genre de Cipher Suite est utilisé.

 

Le contenu de cet article est abordé en profondeur lors notre formation "Réseaux Privés Virtuels" .