Medusa, Pässe und Scheißcode - warum die Passnummern aller Teilnehmer an Internet-Abstimmungen im Internet landeten

Nach dem Ende der Internet-Abstimmung, die überraschend gut endete, hatten ich und viele Menschen lange Zeit das Gefühl, dass in Russland etwas einfach nicht so gut laufen könnte. Jetzt können Sie sich entspannen - die Realität hat uns nicht enttäuscht und wir haben einen doppelten Wahnsinn gesehen: sowohl in Bezug auf die Architektur der Lösung als auch in Bezug auf die Kryptographie.



Übrigens schließt das Ministerium für Telekommunikation und Massenkommunikation nach wie vor JEDE Möglichkeit aus, dass Passdaten von Wählern verloren gehen.



In der Zwischenzeit sieht die Verteilung der Passserien folgendermaßen aus:



Bild



Lassen Sie uns die Ereignisse reproduzieren und versuchen zu verstehen, wie all dies hätte vermieden werden können



Was ist passiert?



Am 9. Juli erscheint Meduzas Material. Die Behörden haben tatsächlich die persönlichen Daten aller Internet-Wähler veröffentlicht, in denen sie über das Archiv degvoter.zip berichtet haben.



Wie finde ich das Archiv degvoter.zip?



Ich fand es so. Eine sorgfältige Suche in Yandex führte mich zu der Seite:

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



Dort wurde der Text "Https checkvoter.gosuslugi.ru degvoter.zip" gefunden. Die Datierung war zu dieser Zeit der 7.7.2020 (vor der Veröffentlichung von Medusa!). Jetzt ist dieser Text bereits an den Anfang der Seite "verschoben" worden und die Datierung hat sich geändert.



Das Archiv selbst wurde von der Website des Staatsdienstes entfernt, aber eine Kopie davon wurde in web.archive.org aufbewahrt, von wo es von allen an der Studie interessierten Personen, einschließlich mir, heruntergeladen wurde. Um zu verstehen, warum dies passiert ist, empfehle ich, auf die primäre Quelle zu verweisen - die robots.txt- Datei auf der State Service-Website.



Was ist in degvoter.exe?



Das Degvoter-Programm selbst ist in C # geschrieben und eine WinForms-Anwendung, die auf das Knie geschrieben wurde und mit einer SQLite-Datenbank arbeitet. Die Dateien im Archiv sind vom 30.06.2020, 22:17 Uhr (30. Juni 2020) datiert. Es ist ersichtlich, dass der Antrag so schnell wie möglich geschrieben wurde, da es zu diesem Zeitpunkt bereits am 1. Juli um 7:17 Uhr in Kamtschatka war und die dort um 8:00 Uhr eröffneten Grundstücke darauf hindeuten, dass die Frist näher als je zuvor war (es ist gut, dass sie elektronisch abgestimmt haben) nur Moskau und Nischni Nowgorod).



Passüberprüfungscode: Die



Bild



Anwendung ist sowohl aus architektonischer als auch aus kryptografischer Sicht der schlechteste Scheißcode. Und deshalb:



Beschreibung der Architekturfehler und des Prinzips des Angriffs auf die Wiederherstellung von Passkennungen



Das Programm enthielt eine lokale Datenbank, in der sich eine Pass-Tabelle mit zwei Feldern num befand und verwendet wurde. Wobei num SHA256 war (<series> + <number>).



Sehr oft macht ein Programmierer ohne relevante Erfahrung, der sich Kryptographieproblemen nähert, eine Reihe ähnlicher Fehler. Einer dieser Fehler ist die Verwendung einer Hash-Funktion ohne jegliches Aufhängen. Die Passkennung besteht aus einer 4-stelligen Reihe und einer 6-stelligen Nummer [xxxx xxxxxx]. Jene. Wir haben 10 ^ 10 Optionen. Die Telefonnummer besteht übrigens auch aus 10 Ziffern [+7 (xxx) xxx-xx-xx]. In der modernen digitalen Welt sind dies keine so großen Zahlen. Ein GB ist also mehr als 10 ^ 9 Bytes, d.h. 100 GB reichen aus, um alle Optionen aufzuzeichnen. Es ist wahrscheinlich, dass Sie sie irgendwie banal machen können. Ich habe gemessen, dass ein moderner Intel Core i5-Prozessor im Single-Thread-Modus alle sha256-Hashes für eine Serie eines Passes in 5 Sekunden (000000-999999) durchläuft. Und dies ist bei der Standard-Implementierung von sha256 ohne zusätzliche Optimierungen der Fall. Jene.Eine vollständige Suche des gesamten Speicherplatzes auf einem normalen Computer dauert weniger als einen Tag. Wenn wir berücksichtigen, dass die Suche in mehreren Threads durchgeführt werden kann, wird ein durchschnittlicher Prozessor eine solche Aufgabe in wenigen Stunden erledigen. Dies ist eine Demonstration der Tatsache, dass der Entwickler des Systems die Prinzipien der Verwendung von Hash-Funktionen nicht versteht. Aber selbst die korrekte Verwendung von Hash-Funktionen mit einer solchen Architektur schützt Passdaten nicht vor der Offenlegung, wenn der Gegner über unbegrenzte Ressourcen verfügt. Schließlich kann eine Person, die Zugriff auf die Datenbank erhalten hat, in kürzester Zeit Passkennungen erhalten, weil Ein Reisepass muss innerhalb einer begrenzten Zeit überprüft werden. Die ganze Frage bezieht sich nur auf Ressourcen (obwohl, wenn Hashing hier einfach in ein paar Millionen Runden angewendet würde, selbst eine so kontroverse architektonische Entscheidung wie die Verteilung der Datenbank zusammen mit der Anwendung seitdem nicht zu einem so lauten Effekt geführt hättewürde es Ihnen ermöglichen, sich zumindest vor Journalisten zu schützen). Medusa hat nur die Inkompetenz der Menschen demonstriert, die diesen Teil des Systems entworfen haben.



Versuchen wir herauszufinden, wie man es einerseits viel besser macht und andererseits auch innerhalb einer Entwicklungsnacht bleibt.



Architektur am Knie



Angenommen, wir haben überhaupt keine Zeit und müssen nachts eine Lösung schreiben.

Die offensichtliche Anforderung besteht darin, dass sich die Datenbank mit Passport-Hashes auf dem Server und eine Client-Server-Anwendung befinden muss. Es stellt sich sofort die Frage, was zu tun ist, wenn das Internet auf der Website plötzlich ausfällt. Zu diesem Zweck müssen Sie eine Android-Version der Client-Anwendung erstellen, die auch zum Herunterladen an PEC-Mitglieder bereitgestellt werden muss. An Orten, an denen es kein Internet oder keine Mobilfunkkommunikation gibt, haben die Menschen bei dieser Abstimmung nicht abgestimmt.



Der Hash in der Datenbank sollte nicht direkt aus der Pass-ID berechnet werden. Dies geschieht, damit die Hashes in der Datenbank nicht unter Verwendung vorhandener Tabellen für Brute Force Brute-Force-fähig sind. Zunächst müssen Sie eine Strong-Hash-Funktion verwenden. Die Hauptfrage ist, wie es verwendet werden soll. Hier gibt es viele mögliche Implementierungen, aber im Wesentlichen läuft alles auf die Verwendung eines Algorithmus hinaus, bei dem es drei Parameter gibt: den Typ der Hash-Funktion, die Anzahl der Iterationen und die Werte, die zum Mischen in den Hash verwendet werden müssen (dies ist für alle Hashes gleich). Die letzte Anforderung besteht darin, dass innerhalb jeder Iteration eine starke Hash-Funktion verwendet werden muss und die Hash-Berechnungsgeschwindigkeit mehrere Einheiten pro Sekunde betragen muss. Selbst wenn ein Angreifer die Datenbank vom Server übernimmt, würde er in diesem Fall viel Zeit benötigen, um alle Daten wiederherzustellen.



Jede der Clientanwendungen ist nur ein Eingabefeld + ein HTTP-Client, der eine Anforderung an den Server sendet.



Der Server arbeitet nur über HTTPS und nur während der Abstimmung und hat ein Limit von 1 RPS pro IP. Wir verwenden Redis als RPS-Trennzeichen, wobei wir die IP-Adresse und TTL als Schlüssel in einer Sekunde schreiben. Wenn es einen Wert gibt - die Anforderung von IP ist nicht zulässig, gibt es keinen Wert - ist die Anforderung von IP zulässig. Dies ermöglicht es, rohe Gewalt von außen zu vermeiden.



Auf diese Weise geschrieben, wird unsere Lösung, die buchstäblich aus Scheiße und Stöcken besteht, eine Größenordnung sicherer sein als der derzeitige Degvoter. Gleichzeitig ist der Unterschied in der Schreibzeit gering und der Prozess des Schreibens des Codes selbst kann für 3 Personen (Server, Win-Client, Android-Client) parallelisiert werden.



Schauen wir uns mögliche Leckszenarien an.



Wir haben die folgenden Punkte, an denen Sie Informationen über das System erhalten können



  1. Server-Quellcode
  2. Kompilierte Backend-Dateien
  3. Server-DB
  4. Client-Anwendungen


Client-Anwendungen enthalten in diesem Fall keine Informationen, während die maximale Anzahl von Personen Zugriff auf sie hat, und hier ist die maximale Wahrscheinlichkeit von Lecks (was passiert ist).



Um Informationen wiederherzustellen, müssen Sie über die Punkte (1,2) oder (1,3) auf Informationen zugreifen. Wenn es nur eine Basis gibt, ist es ohne eine bekannte Hashing-Methode unmöglich, etwas wiederherzustellen.



Schlussfolgerungen



  1. Wenn Sie in irgendeiner Form mit personenbezogenen Daten arbeiten müssen, wenden Sie sich an einen Architekten
  2. Jedes Mal, wenn Sie in irgendeiner Form mit personenbezogenen Daten arbeiten müssen, sollten Sie einen Entwickler mit Erfahrung / Ausbildung auf dem Gebiet der Kryptographie oder Informationssicherheit einbeziehen


Diese beiden einfachen Regeln helfen dabei, die Schande zu vermeiden, die wir im Beispiel mit der Degvoter-Anwendung gesehen haben (Denken Sie daran, dass ein gewöhnlicher Entwickler die Nuancen der Verwendung von Hash-Funktionen möglicherweise nicht versteht).



Das Dienstprogramm zum Demonstrieren der Möglichkeit der Wiederherstellung personenbezogener Daten DegvoterDecoder befindet sich im Repository, das der Analyse von Abstimmungsdaten gewidmet ist ... Standardmäßig ist es für 8 Threads konfiguriert. Wenn Sie das Archiv degvoter.zip bereits heruntergeladen haben und in C # programmieren, können Sie leicht herausfinden, wie es funktioniert.



github.com/AlexeiScherbakov/Voting2020



All Articles