Por cierto, el Ministerio de Telecomunicaciones y Comunicaciones Masivas todavía excluye CUALQUIER posibilidad de fuga de datos de pasaportes de los votantes.
Mientras tanto, la distribución de series de pasaportes se ve así:
reproduzcamos los eventos e intentemos entender cómo se pudo haber evitado todo esto.
¿Que pasó?
El 9 de julio aparece el material de Meduza. Las autoridades hicieron públicos los datos personales de todos los votantes de Internet, donde informaron sobre el archivo degvoter.zip.
¿Cómo puedo encontrar el archivo degvoter.zip?
Lo encontré así. Una búsqueda cuidadosa a través de Yandex me llevó a la página:
vudu7.vuduwiki.duckdns.org/mk.ru/https_check.ege.edu.ru.html
El texto "Https checkvoter.gosuslugi.ru degvoter.zip" se encontró allí. La cita en ese momento era el 7.7.2020 (¡antes de la publicación de Medusa!). Ahora este texto ya se ha "movido" a la parte superior de la página y la cita ha cambiado.
El archivo en sí se eliminó del sitio del servicio estatal, pero se conservó una copia en web.archive.org, desde donde fue descargado por todas las personas interesadas en el estudio, incluido yo mismo. Para entender por qué sucedió esto, recomiendo consultar la fuente principal: el archivo robots.txt en el sitio web del Servicio Estatal.
¿Qué hay dentro de degvoter.exe?
El programa degvoter en sí está escrito en C # y es una aplicación WinForms escrita en la rodilla que funciona con una base de datos sqlite. Los archivos en el archivo tienen fecha 2020-06-30 22:17 (30 de junio de 2020). Se puede ver que la solicitud se escribió en el menor tiempo posible, porque en ese momento ya eran las 7:17 del 1 de julio en Kamchatka, y el hecho de que las parcelas se abrieron allí a las 8:00 indica que la fecha límite estaba más cerca que nunca (es bueno que votaron electrónicamente solo Moscú y Nizhny Novgorod).
Código de verificación de pasaporte: la
aplicación, tanto desde el punto de vista arquitectónico como desde el punto de vista criptográfico, es el peor código de mierda. Y es por eso:
Descripción de los defectos de arquitectura y el principio del ataque a la recuperación de identificadores de pasaporte.
El programa incluía una base de datos local en la que había una tabla de pasaportes con dos campos num y utilizados. Donde num era SHA256 (<serie> + <number>).
Muy a menudo, cuando un programador sin experiencia relevante aborda problemas de criptografía, comete muchos errores del mismo tipo. Uno de esos errores es el uso de una función hash sin ningún tipo de bloqueo. El identificador de pasaporte consta de una serie de 4 dígitos y un número de 6 dígitos [xxxx xxxxxx]. Aquellos. Tenemos 10 ^ 10 opciones. El número de teléfono, por cierto, también consta de 10 dígitos [+7 (xxx) xxx-xx-xx]. En el mundo digital moderno, estos no son números tan grandes. Entonces, un GB es más de 10 ^ 9 bytes, es decir 100 GB es suficiente para registrar todas las opciones. Es probable que los pueda trillar. Medí que en modo de subproceso único, un procesador Intel Core i5 moderno itera sobre todos los hashes sha256 para una serie de pasaportes en 5 segundos (000000-999999). Y esto está en la implementación estándar de sha256 sin ningún ajuste adicional. Aquellos.Una búsqueda completa de todo el espacio en una computadora normal tomará menos de un día. Si tenemos en cuenta que la búsqueda puede llevarse a cabo en varios subprocesos, un procesador promedio se encargará de dicha tarea en unas pocas horas. Esta es una demostración del hecho de que el desarrollador del sistema no comprende los principios del uso de funciones hash. Pero incluso el uso correcto de las funciones hash con dicha arquitectura no salva los datos del pasaporte de la divulgación si el adversario tiene recursos ilimitados. Después de todo, una persona que ha obtenido acceso a la base de datos puede obtener identificadores de pasaporte en un tiempo limitado, porque un pasaporte debe ser verificado dentro de un tiempo finito. Toda la pregunta es solo sobre los recursos (aunque si simplemente aplicaran hashing en un par de millones de rondas, incluso una decisión arquitectónica tan controvertida como la distribución de la base de datos junto con la aplicación no conduciría a un efecto tan fuerte, ya quele permitiría protegerse al menos de los periodistas). Medusa acaba de demostrar la incompetencia de las personas que diseñaron esta parte del sistema.
Intentemos descubrir cómo hacerlo mucho mejor, por un lado, y por otro lado, también mantenernos dentro de una noche de desarrollo.
Arquitectura en la rodilla
Supongamos que no tenemos tiempo y necesitamos escribir una solución durante la noche.
El requisito obvio es que la base de datos con hash de pasaporte debe estar en el servidor y debe ser una aplicación cliente-servidor. La pregunta surge de inmediato, ¿qué hacer si Internet se rompe repentinamente en el sitio? Para estos fines, debe crear una versión de Android de la aplicación cliente, que también debe descargarse para los miembros del PEC. En lugares donde no hay Internet o comunicación celular, la gente no votó en esta votación.
El hash en la base de datos no debe calcularse directamente a partir de la identificación del pasaporte. Esto se hace para que los hashes en la base de datos no puedan ser de fuerza bruta utilizando las tablas existentes para la fuerza bruta. Primero, debe usar una función de hash fuerte. La pregunta principal es CÓMO debe usarse. Aquí hay muchas implementaciones posibles, pero en esencia todo se reduce al uso de un algoritmo en el que habrá tres parámetros: el tipo de función hash, el número de iteraciones y los valores que deben usarse para mezclar en el hash (será común para todos los hash). El requisito final es que se debe usar una función hash fuerte dentro de cada iteración, y la velocidad de cálculo hash debe ser de varias unidades por segundo. Incluso tomando el control de la base de datos del servidor, un atacante en este caso tomaría una cantidad significativa de tiempo para recuperar todos los datos.
Cada una de las aplicaciones del cliente será solo un campo de entrada + un cliente Http que envía una solicitud al servidor.
El servidor funciona solo a través de HTTPS y solo durante la votación y tiene un límite de 1 RPS por IP. Usamos Redis como delimitador RPS, donde escribimos la dirección IP y TTL como clave en un segundo. Si hay un valor, la solicitud de IP no está permitida, no hay valor, la solicitud de IP está permitida. Esto permitirá evitar la fuerza bruta desde el exterior.
Escrita de esta manera, nuestra solución, literalmente hecha de mierda y palos, será un orden de magnitud más seguro que el degvoter actual. Al mismo tiempo, la diferencia en el tiempo de escritura es pequeña y el proceso de escritura del código en sí puede ser paralelo para 3 personas (servidor, cliente-win, cliente-android).
Veamos posibles escenarios de fuga.
Tenemos los siguientes puntos donde puede obtener información sobre el sistema.
- Código fuente del servidor
- Archivos de fondo compilados
- DB del servidor
- Aplicaciones cliente
Las aplicaciones del cliente en este caso no llevan ninguna información, mientras que el número máximo de personas tiene acceso a ellas, y aquí es donde está la probabilidad máxima de fugas (lo que sucedió).
Para recuperar información, deberá acceder a la información desde los puntos (1,2) o (1,3). Si solo hay una base, entonces sin un método de hash conocido, será imposible recuperar algo.
conclusiones
- Cada vez que necesite trabajar con datos personales de alguna forma, involucre a un arquitecto
- Cada vez que necesite trabajar con datos personales de alguna forma: involucre a un desarrollador con experiencia / educación en el campo de la criptografía o la seguridad de la información
Estas dos reglas simples ayudarán a evitar la vergüenza que vimos en el ejemplo con la aplicación degvoter (recuerde que un desarrollador común puede no comprender los matices del uso de funciones hash).
La utilidad para demostrar la posibilidad de recuperar datos personales DegvoterDecoder se encuentra en el repositorio dedicado al análisis de datos de votación. ... Por defecto, está configurado para 8 hilos. Si ya ha descargado el archivo degvoter.zip y programa en C #, puede averiguar fácilmente cómo funciona.
github.com/AlexeiScherbakov/Voting2020