Le vote électronique, suite technique…

Il y a 15 jours je vous ai révélé la présence d‘une injection SQL sur le site de vote par internet destiné à élire les représentants des Français établis hors de France. Selon mes sources, aujourd’hui à 15h, se tient un plan média d’urgence au quai d’Orsay pour vanter les mérites de ce système… Ou pas ?

NB: cet article est très technique, faute de temps j’ai préféré livrer les conclusions sans les vulgariser. Je prendrai ce temps dans le week-end pour en faire une version plus… digeste…

J’ai regardé quelques peu le code java de l’applet servant à voter ainsi que l’environnement dans lequel il se trouve (le site en lui-même). De plus j’ai reçu deux emails de gentils anonymes ([email protected] et [email protected] merci :)) – voici quelques conclusions :

Sur l’environnement

Il est théoriquement impossible de passer l’étape de vérification de la configuration technique si vous avez fait le choix de travailler avec des logiciels open-source (donc pas Java lui-même mais un portage libre tout aussi sécurisé, si ce n’est plus). Théoriquement donc puisqu’il suffit de connaitre l’adresse de la page du vote pour bypasser cette sécurité (genre ici ;)) et toutes les autres vérifications sur la configuration matérielle (vote depuis un smartphone inclu).

Si on se penche un peu plus en détail sur le code de ladite page on constate d’ailleurs qu’il est possible de pré-remplir certaines variables (réinjectées dans des champs ensuite) de l’applet lui-même depuis l’url de la page appelante (la vraie, passée en iframe pas celle que vous avez dans votre navigateur) :

https://scrutin.diplomatie.gouv.fr/portail/client_welcome.html?siteLanguage=&electionId=&electionEventId=&institutionId=&pin=&j_username=toto&password=

Cette possibilité s’étend aussi au mot de passe (pin ici) et à un mystérieux « password » que je n’ai pas réussi à faire réagir…

Sur le système de recouvrement de mot de passe il est possible assez simplement de provoquer des « internal error » sans que je ne sois trop sûr de savoir à quel point elles sont gérées ou pas et ce qu’elles provoquent comme dégats exacts dans les logs ou autres parties du système :

https://mdp-scrutin.diplomatie.gouv.fr/portail/defis.html?wicket:interface=:d:challengeForm::IFormSubmitListener::

Sur ces deux systèmes il est possible de passer par du https (connexion chiffrée) ou pas. Il est donc possible de voter en utilisant par exemple un wifi ouvert du burger king du coin (c’est pour les Français établis à l’étranger on a dit… chanceux !) et qu’un utilisateur du même réseau, malveillant celui-là, surveille ce qu’il se passe sur le réseau… en clair…

Sur l’applet lui-même

On constate assez vite que le code n’a pas été le moins du monde obfusqué, ce qui rend la décompilation des binaires java un jeu d’enfant… Auquel je me suis livré brièvement (découvrant des copyright 2004 à certains endroits, des codes qu’un stagiaire n’oserait pas pondre à d’autres, …) et auquel deux anonymes ont donné un peu plus de temps avant de me soumettre leurs trouvailles.

[email protected] said :

Quelques commentaires sur l’applet de vote:
-le mot de passe est hashé avec du SHA256 et un salt hardcodé. Pas terrible, mais ça ne change rien, on est côté client. S’il y a du SSL, ça diminue le problème. (le code pourrait éventuellement supporter de l’authentification par certificat client dans des smartcards).

-le fichier ./com/scytl/pnyx/client/communication/ application/message/SecureMessageHelper.java contient un gros paquet de code chargé de l’envoi du vote (dénommé Ballot dans le code). Une clef AES est générée aléatoirement et utilisée pour chiffrer la structure de donnée envoyée. Cette clef est elle-même chiffrée avec une clef publique. J’ai l’impression que la clef publique est téléchargée à la volée. Les données peuvent donc être déchiffrées côté serveur. Impossible de savoir s’ils ont une gestion des clefs correcte.

-le vote envoyé a un identifiant, un « BallotId » généré aléatoirement. Ce n’est pas un GUID (identifiant unique), mais aléatoire. Il pourrait donc y avoir des
conflits, voire même l’écrasement d’un autre vote 😀

-le vote contient le login (et le certificat de l’utilisateur si présent). La confidentialité du vote n’est donc pas assurée. De plus, rien n’empêche un administrateur de forger un vote. A tester: modifier l’applet pour qu’elle envoie le vote avec un autre username 😀

En résumé, ça pourrait être presque sécurisé pour une application normale, mais c’est largement insuffisant pour du vote électronique. Les systèmes de vote électronique évolués utilisent généralement du chiffrement homomorphique, garantissent l’anonymat du vote et génèrent un résultat vérifiable par tous les
votants.

Un beau fail, quoi 🙂

[email protected] said (j’ai enlevé les bouts de code ici – parties marquées /* … */):

Analyse succinte de l’applet de vote electronique
————————————————-

1. Utilisation du protocole HTTP

La classe HTTPPostTransport.class (com.scytl.pnyx.client.communication.transport) contient une routine d’envoi d’information:

public String sendMessage(Map<String, String> paramMap, URL paramURL) throws TransportException
/* … */

Cette routine vérifie si le protocole de l’URL est HTTP ou HTTPS, et autorise l’envoi des données via la méthode POST. Le fichier de properties contient aussi un commentaire intéressant:

## The kind of transport. Currently only HTTP POST
pnyx.transport=HTTP

La classe HTTPPostTransport est utilisée par l’applet pour effectuer l’envoi des informations. Le choix d’HTTP et d’HTTPS se fait à partir de l’URL d’origine, un votant accédant via le protocole HTTP cause l’utilisation du protocole HTTP par l’applet. Ce point a déjà été identifié auparavant.

2. Implémentation cryptographique

Il y a des salts qui trainent dans le code de l’applet:

/* … */

Et en plus de cela, on retrouve une méthode de génération de hash de username:

/* … */

Grosso-modo, le nom d’utilisateur transmis est:

username_transformed = hexencode(hash(<hash(salt)><username><pin><hash(salt)>))

On a une routine similaire pour la génération du pin « transformé »:

public synchronized String transformedPin(Map<String, String> paramMap)
/* … */

Cette fois-ci c’est le nom d’utilisateur qui sert de « marqueur »:

pin_transformed = hash(<username_transformed><username><pin>)
pin_transformed2 = base64(hash(<username_transformed><username><pin><username_transformed>)
makeSecretKey(pin_transformed, pin_transformed2)

La routine de génération de clef est basée sur  le dernier hash calculé, généré à partir du nom d’utilisateur et du mot de passe, ainsi que le salt. Le salt est connu du client, donc peut être récupéré. Seul le mot de passe reste inconnu.

La clef ainsi générée sert à chiffrer l’ensemble des communications.

Si on couple ça au protocole HTTP, il est tout à fait possible d’intercepter une séquence d’authentification, et de bruteforcer le mot de passe (6
cars alpha minuscules).
De fait le secret du vote peut être compromis.

Je passe le fait que le salt n’est pas généré de manière aléatoire …

3. Conclusion rapide

Je n’ai pas pris le temps de regarder en détail l’intégralité du code, cette conclusion est donc quelque peu rapide et contient peut-être des erreurs, mais amha ces quelques éléments démontrent déjà que d’une part le démontre qu’il est possible d’intercepter les données du vote, et potentiellement de casser un mot de passe si on dispose de l’identifiant, et ainsi de pouvoir générer une clef permettant le déchiffrement des données. D’autre part, l’implémentation des routines crypto laisse entrevoir un possible amateurisme (il n’y a qu’à voir l’enchevetrement des appels aux fonctions de hachage imbriquées), mais cela reste à confirmer.

N’hésitez pas à contribuer ci-dessous (je désactive le log d’IP des commentaires le temps des législatives internet) ou via le formulaire de contact (même chose, il ne log pas les IP).

Vous pouvez aussi, si vous avez voté et avez rencontré des difficultés en témoigner sur le site dédié mis en place par le Parti Pirate.

Et pour vous renseigner sur le sujet : Hardkor ou Bastamag.

14 réflexions sur « Le vote électronique, suite technique… »

  1. Ploum
  2. Geal

    J’ai l’impression que Scytl n’a pas très bien compris le principe de l’isoloir. Ni du bulletin secret. Mais franchement, on aurait pu attendre d’eux un peu plus de boulot pour développer un truc propre…

  3. Ploufplouf

    Pour les mots de passe, je suis surpris du « 6 caractères ». Pour les deux que j’ai sous la main, c’est 10 (mais bien de l’apha-numérique minuscule).

    À noter aussi que faire de l’homme du milieu en SSL ne génère qu’un petit warning, et ne bloque en rien le vote.

  4. Ping : La plateforme de vote par internet pour les législatives serait bourrée de failles de sécurité | Geekattitude

  5. leomar

    Pour sortir du coté technique… je suis un français vivant à l’étranger. Pour voter, j’ai donc donné mon adresse mail a l’ambassade de france.

    Celle-ci c’est empressé de la distribuer a qui la voulais. Je suis depuis spammé par tout les candidats et parti politiques… y compris par des partis n’étant pas français, mais qui me disent soutenir tel ou tel candidats

    Les mails sont parfois envoyés par des sociétés privées (comme le dernier « spam », envoyé par un site anglais, mais basé en suisse, et donc l’adresse officiel de contact du whois est l’adresse gmail du proprio, et qui est hébergé sur un serveur mutu ovh *_*)

    Pis bon, s’ils veulent falsifier le vote… il leur suffit d’utiliser le mot de passe, vue que le mot de passe pour voter a été transmis directement par mail, et en clair

  6. Ploum

    leomar > je trouve normal que chaque candidat puisse envoyer un (et un seul) mail. D’ailleurs, c’est à l’état de le faire (le candidat envoyant son mail).

    Que les bases de données d’adresse circulent, ça c’est très inquiétant: si tu me donnes 1/2 journée, je te fais un beau site de phishing, j’envoie un email à tous disant que, pour des raisons de sécurités, la nouvelle adresse de vote est xxxx. Et voilà. J’ai récupéré tous les votes.

  7. sil

    Les hacktivistes feraient quelque chose d’utile s’ils pirataient le système de sorte à rendre le scrutin nul.

  8. sil

    @ploum

    Ceci dit, rien que faire un site de phishing sans trafiquer les les votes pourrait permettre d’invalider le scrutin, si la presse relaie l’information.

    En effet, si des électeurs sont trompés par le site de phishing, alors ils ne voteront pas sur le site officiel. Il y a donc atteinte au droit de vote et à la sincérité du scrutin. Un juge pourrait donc décider que le scrutin est nul.

  9. sil

    Voilà comment pourrait se passer l’attaque :
    – on crée le site de phishing,
    – on envoie un mail aux votants du style « Bonjour, nous vous rappelons que vous avez jusqu’au 29 juin pour voter à l’adresse suivant [lien vers le site de phishing],
    – on récupère les login et identités,
    – on envoie un message à la presse du style « Nous avons hameçonné les personnes suivantes [liste des personnes] qui n’ont donc pas voté sur le site officiel ».

    Et voilà comment invalider une élection CQFD.

  10. Ping : Vote électronique nique nique | SCTeam

  11. Ping : Le système de vote éléctronique des législatives françaises vulnérable ? | UnderNews

  12. Ping : Elections législatives des Français de l'étranger #EXTcirco07

  13. Ping : Le vote électronique est-il fiable ? | TECH ME OUT

Les commentaires sont fermés.