Méduse, passeports et code de merde - pourquoi les numéros de passeport de tous les participants au vote par Internet se sont retrouvés sur Internet

Après la fin du vote par Internet, qui s'est étonnamment bien terminé, pendant longtemps, beaucoup de gens et moi-même avons eu le sentiment qu'en Russie, quelque chose ne pouvait tout simplement pas se passer si bien. Maintenant, vous pouvez vous détendre - la réalité n'a pas déçu et nous avons vu une double folie: à la fois en termes d'architecture de la solution, et en termes de cryptographie.



À propos, le ministère des Télécoms et des Communications de masse exclut toujours TOUTE possibilité de fuite des données de passeport des électeurs



Pendant ce temps, la distribution de séries de passeports ressemble à ceci:



image



reproduisons les événements et essayons de comprendre comment tout cela aurait pu être évité



Qu'est-il arrivé?



Le 9 juillet, le matériel de Meduza apparaît et les autorités ont rendu publiques les données personnelles de tous les électeurs sur Internet, où elles ont parlé des archives degvoter.zip.



Comment puis-je trouver l'archive degvoter.zip?



Je l'ai trouvé comme ça. Une recherche minutieuse dans Yandex m'a conduit à la page:

vudu7.vuduwiki.duckdns.org/mk.ru/https_check.ege.edu.ru.html



Le texte "Https checkvoter.gosuslugi.ru degvoter.zip" y a été trouvé. La datation à cette époque était le 7.7.2020 (avant la publication de Medusa!), Maintenant ce texte a déjà "déplacé" vers le haut de la page et la datation a changé.



L'archive elle-même a été supprimée du site du service public, mais une copie de celle-ci a été conservée dans web.archive.org, d'où elle a été téléchargée par toutes les personnes intéressées par l'étude, y compris moi-même. Pour comprendre pourquoi cela s'est produit, je vous recommande de vous référer à la source principale - le fichier robots.txt sur le site Web State Service.



Que contient degvoter.exe?



Le programme degvoter lui-même est écrit en C # et est une application WinForms écrite sur le genou qui fonctionne avec une base de données sqlite. Les fichiers de l'archive sont datés du 2020-06-30 22:17 (30 juin 2020). On voit que la candidature a été rédigée dans les plus brefs délais, car à ce moment-là il était déjà 7h17 le 1er juillet au Kamtchatka, et le fait que les parcelles y soient ouvertes à 8h00 indique que la date limite était plus proche que jamais (c'est bien qu'ils aient voté électroniquement seulement Moscou et Nizhny Novgorod).



Code de vérification du passeport: L'



image



application, à la fois d'un point de vue architectural et d'un point de vue cryptographique, est le pire code de merde. Et c'est pourquoi:



Description des failles d'architecture et du principe de l'attaque sur la récupération des identifiants de passeport



Le programme comprenait une base de données locale dans laquelle il y avait une table des passeports avec deux champs num et utilisés. Où num était SHA256 (<série> + <numéro>).



Très souvent, lorsqu'un programmeur sans expérience pertinente aborde les problèmes de cryptographie, il fait un tas d'erreurs du même type. L'une de ces erreurs est l'utilisation d'une fonction de hachage sans aucune sorte de blocage. L'identifiant du passeport se compose d'une série de 4 chiffres et d'un numéro de 6 chiffres [xxxx xxxxxx]. Ceux. nous avons 10 ^ 10 options. Le numéro de téléphone se compose également de 10 chiffres [+7 (xxx) xxx-xx-xx]. À l'échelle du monde numérique moderne, il ne s'agit pas d'un si grand nombre. Donc, un Go représente plus de 10 ^ 9 octets, c'est-à-dire 100 Go suffisent pour enregistrer toutes les options. Il est probable que vous puissiez en quelque sorte les banaliser. J'ai mesuré qu'en mode monothread, un processeur Intel Core i5 moderne itère sur tous les hachages sha256 pour une série d'un passeport en 5 secondes (000000-999999). Et c'est sur l'implémentation standard de sha256 sans aucune modification supplémentaire. Ceux.une recherche complète de tout l'espace sur un ordinateur ordinaire prendra moins d'une journée. Si nous prenons en compte le fait que la recherche peut être effectuée dans plusieurs threads, un processeur moyen fera face à une telle tâche en quelques heures. Ceci est une démonstration du fait que le développeur du système ne comprend pas les principes d'utilisation des fonctions de hachage. Mais même l'utilisation correcte des fonctions de hachage avec une telle architecture n'empêche pas la divulgation des données de passeport si l'adversaire dispose de ressources illimitées. Après tout, une personne qui a eu accès à la base de données peut obtenir des identifiants de passeport dans un temps limité, car un passeport doit être vérifié dans un délai déterminé. Toute la question ne concerne que les ressources (bien que si le hachage avait été simplement appliqué ici en quelques millions de tours, même une décision architecturale aussi controversée que la distribution de la base de données avec l'application n'aurait pas conduit à un effet aussi fort, carvous permettrait de vous protéger au moins des journalistes). Medusa vient de démontrer l'incompétence des personnes qui ont conçu cette partie du système.



Essayons de comprendre comment l'améliorer d'une part, et d'autre part, restons également dans une nuit de développement.



Architecture sur le genou



Supposons que nous n'ayons pas le temps du tout et que nous ayons besoin d'écrire une solution pendant la nuit.

L'exigence évidente est que la base de données avec les hachages de passeport doit être sur le serveur et ce doit être une application client-serveur. La question se pose immédiatement, que faire si Internet tombe soudainement en panne sur le site? À ces fins, vous devez créer une version Android de l'application cliente, qui doit également être fournie à télécharger aux membres PEC. Dans les endroits où il n'y a ni Internet ni communication cellulaire, les gens n'ont pas voté lors de ce vote.



Le hachage dans la base de données ne doit pas être calculé directement à partir de l'ID de passeport. Ceci est fait pour que les hachages dans la base de données ne puissent pas être de force brute en utilisant des tables existantes pour la force brute. Tout d'abord, vous devez utiliser une fonction de hachage fort. La question principale est de savoir comment il doit être utilisé. Il existe de nombreuses implémentations possibles ici, mais en substance, tout se résume à l'utilisation d'un algorithme dans lequel il y aura trois paramètres: le type de la fonction de hachage, le nombre d'itérations et la ou les valeurs qui doivent être utilisées pour se mélanger dans le hachage (ce sera commun pour tous les hachages). La dernière exigence est qu'une fonction de hachage forte doit être utilisée dans chaque itération, et la vitesse de calcul de hachage doit être de plusieurs unités par seconde. Même en prenant le contrôle de la base de données du serveur, un attaquant dans ce cas prendrait un temps considérable pour récupérer toutes les données.



Chacune des applications clientes sera juste un champ de saisie + un client Http qui envoie une requête au serveur.



Le serveur fonctionne uniquement sur HTTPS et uniquement pendant le vote et a une limite de 1 RPS par IP. Nous utilisons Redis comme délimiteur RPS, où nous écrivons l'adresse IP et TTL comme clé en une seconde. S'il y a une valeur - la demande d'IP n'est pas autorisée, il n'y a pas de valeur - la demande d'IP est autorisée. Cela permettra d'éviter la force brute de l'extérieur.



Écrit de cette façon, notre solution, littéralement faite de merde et de bâtons, sera d'un ordre de grandeur plus sûr que le dégvoter actuel. Dans le même temps, la différence de temps d'écriture est faible et le processus d'écriture du code lui-même peut être parallélisé pour 3 personnes (serveur, win-client, android-client).



Regardons les scénarios de fuite possibles.



Nous avons les points suivants où vous pouvez obtenir des informations sur le système



  1. Code source du serveur
  2. Fichiers backend compilés
  3. DB de serveur
  4. Applications client


Les applications clientes dans ce cas ne portent aucune information, alors que le nombre maximum de personnes y a accès, et c'est là que se situe la probabilité maximale de fuites (ce qui s'est produit).



Afin de récupérer des informations, vous devrez accéder aux informations à partir des points (1,2) ou (1,3). S'il n'y a qu'une base, alors sans méthode de hachage connue, il sera impossible de récupérer quelque chose.



conclusions



  1. Chaque fois que vous avez besoin de travailler avec des données personnelles sous une forme ou une autre - impliquez un architecte
  2. Chaque fois que vous avez besoin de travailler avec des données personnelles sous une forme ou une autre - impliquez un développeur ayant de l'expérience / une formation dans le domaine de la cryptographie ou de la sécurité de l'information


Ces deux règles simples permettront d'éviter la honte que nous avons vue dans l'exemple avec l'application degvoter, (Rappelez-vous qu'un développeur ordinaire peut ne pas comprendre les nuances de l'utilisation des fonctions de hachage)



L'utilitaire de démonstration de la possibilité de récupérer des données personnelles DegvoterDecoder est situé dans le référentiel dédié à l'analyse des données de vote ... Par défaut, il est configuré pour 8 threads. Si vous avez déjà téléchargé l'archive degvoter.zip et que vous programmez en C #, vous pouvez facilement comprendre comment cela fonctionne.



github.com/AlexeiScherbakov/Voting2020



All Articles