A propósito, o Ministério das Telecomunicações e Comunicações de Massa ainda exclui QUALQUER possibilidade de vazamento de dados de passaporte dos eleitores.
Enquanto isso, a distribuição de séries de passaportes fica assim:
Vamos reproduzir os eventos e tentar entender como tudo isso poderia ter sido evitado.
O que aconteceu?
No dia 9 de julho, o material de Meduza aparece, e as autoridades tornaram públicos os dados pessoais de todos os eleitores da Internet, onde contaram sobre o arquivo degvoter.zip.
Como posso encontrar o arquivo degvoter.zip?
Eu achei assim. Uma pesquisa cuidadosa no Yandex me levou à página:
vudu7.vuduwiki.duckdns.org/mk.ru/https_check.ege.edu.ru.html
O texto "Https checkvoter.gosuslugi.ru degvoter.zip" foi encontrado lá. O namoro na época era 7.7.2020 (antes da publicação da Medusa!). Agora, este texto já foi "movido" para o topo da página e o namoro foi alterado.
O arquivo foi removido do site do serviço estatal, mas uma cópia dele foi preservada em web.archive.org, de onde foi baixado por todas as pessoas interessadas no estudo, inclusive eu. Para entender por que isso aconteceu, recomendo consultar a fonte principal - o arquivo robots.txt no site do Serviço de Estado.
O que há dentro do degvoter.exe?
O próprio programa degvoter é escrito em C # e é um aplicativo WinForms escrito no joelho que funciona com um banco de dados sqlite. Os arquivos no arquivo são datados de 30/06 2020 - 22:17 (30 de junho de 2020). Pode-se observar que o pedido foi escrito no menor tempo possível, porque naquele momento já era 7h17 de 1º de julho em Kamchatka, e o fato de as parcelas terem sido abertas às 8h indica que o prazo estava mais próximo do que nunca (é bom que eles tenham votado eletronicamente) apenas Moscou e Níjni Novgorod).
Código de verificação de passaporte: o
aplicativo, tanto do ponto de vista arquitetural quanto do ponto de vista criptográfico, é o pior código de merda. E é por isso:
Descrição das falhas de arquitetura e o princípio do ataque à recuperação de identificadores de passaporte
O programa incluiu um banco de dados local no qual havia uma tabela de passaportes com dois campos num e usados. Onde num era SHA256 (<série> + <número>).
Muitas vezes, quando um programador sem experiência relevante aborda problemas de criptografia, ele comete muitos erros do mesmo tipo. Um desses erros é o uso de uma função hash sem nenhum tipo de interrupção. O identificador de passaporte consiste em uma série de 4 dígitos e um número de 6 dígitos [xxxx xxxxxx]. Essa. temos 10 ^ 10 opções. O número de telefone, a propósito, também consiste em 10 dígitos [+7 (xxx) xxx-xx-xx]. Na escala do mundo digital moderno, esses não são números tão grandes. Portanto, um GB tem mais de 10 ^ 9 bytes, ou seja, 100 GB é suficiente para gravar todas as opções. É provável que você possa entendê-las. Eu medi que, no modo single-thread, um processador Intel Core i5 moderno repete todos os hashes sha256 para uma série de passaportes em 5 segundos (000000-999999). E isso está na implementação padrão do sha256, sem ajustes adicionais. Essa.uma pesquisa completa de todo o espaço em um computador comum levará menos de um dia. Se levarmos em conta que a pesquisa pode ser realizada em vários segmentos, um processador médio lidará com essa tarefa em poucas horas. Isso é uma demonstração do fato de que o desenvolvedor do sistema não entende os princípios do uso de funções de hash. Mas mesmo o uso correto de funções de hash com essa arquitetura não salva os dados do passaporte da divulgação se o adversário tiver recursos ilimitados. Afinal, uma pessoa que obteve acesso ao banco de dados pode obter identificadores de passaporte em um tempo finito, porque um passaporte deve ser verificado dentro de um tempo finito. A questão toda é apenas sobre os recursos (embora, se eles simplesmente aplicassem o hash em alguns milhões de rodadas, mesmo uma decisão arquitetônica tão controversa como a distribuição do banco de dados e o aplicativo não levaria a um efeito tão alto, poispermitiria que você se protegesse pelo menos dos jornalistas). A Medusa acabou de demonstrar a incompetência das pessoas que projetaram essa parte do sistema.
Vamos tentar descobrir como torná-lo muito melhor, por um lado, e por outro lado, também manter dentro de uma noite de desenvolvimento.
Arquitetura no joelho
Suponha que não temos tempo e precisamos escrever uma solução durante a noite.
O requisito óbvio é que o banco de dados com hashes de passaporte esteja no servidor e seja um aplicativo cliente-servidor. Surge imediatamente a pergunta: o que fazer se a Internet quebrar repentinamente no site? Para esses fins, você precisa criar uma versão Android do aplicativo cliente, que também deve ser fornecida para fazer o download para os membros do PEC. Em locais onde não há Internet ou comunicação celular, as pessoas não votaram neste voto.
O hash no banco de dados não deve ser calculado diretamente a partir do ID do passaporte. Isso é feito para que os hashes no banco de dados não possam ser de força bruta usando as tabelas existentes para força bruta. Primeiro, você precisa usar uma função hash forte. A principal questão é como deve ser usado. Existem muitas implementações possíveis aqui, mas, na verdade, tudo se resume ao uso de um algoritmo no qual haverá três parâmetros: o tipo da função hash, o número de iterações e o (s) valor (es) que devem ser usados para se misturar ao hash (será comum para todos os hashes). O requisito final é que uma função hash forte deve ser usada em cada iteração e a velocidade de computação do hash deve ser várias unidades por segundo. Mesmo assumindo o banco de dados do servidor, nesse caso, um invasor levaria um tempo significativo para recuperar todos os dados.
Cada um dos aplicativos clientes será apenas um campo de entrada + um cliente Http que envia uma solicitação ao servidor.
O servidor funciona apenas por HTTPS e apenas durante a votação e tem um limite de 1 RPS por IP. Usamos Redis como delimitador RPS, onde escrevemos o endereço IP e TTL como chave em um segundo. Se houver um valor - a solicitação do IP não é permitida, não há valor - a solicitação do IP será permitida. Isso tornará possível evitar a força bruta do lado de fora.
Escrita dessa maneira, nossa solução, literalmente feita de merda e paus, será uma ordem de magnitude mais segura do que o degvoter atual. Ao mesmo tempo, a diferença no tempo de gravação é pequena e o processo de escrever o código em si pode ser paralelo para 3 pessoas (servidor, cliente vencedor, cliente Android).
Vejamos os possíveis cenários de vazamento.
Temos os seguintes pontos onde você pode obter informações sobre o sistema
- Código fonte do servidor
- Arquivos de back-end compilados
- DB do servidor
- Aplicativos cliente
Os aplicativos clientes, nesse caso, não carregam nenhuma informação, enquanto o número máximo de pessoas tem acesso a eles, e é aí que a probabilidade máxima de vazamentos é (o que aconteceu).
Para recuperar informações, você precisará acessar as informações dos pontos (1,2) ou (1,3). Se houver apenas uma base, sem um método de hash conhecido, será impossível recuperar alguma coisa.
conclusões
- Toda vez que você precisar trabalhar com dados pessoais de alguma forma - envolva um arquiteto
- Toda vez que você precisar trabalhar com dados pessoais de alguma forma - envolva um desenvolvedor com experiência / educação no campo de criptografia ou segurança da informação
Essas duas regras simples ajudarão a evitar a vergonha que vimos no exemplo com o aplicativo degvoter (lembre-se de que um desenvolvedor comum pode não entender as nuances do uso de funções hash).
O utilitário para demonstrar a possibilidade de recuperar dados pessoais O DegvoterDecoder está localizado no repositório dedicado à análise dos dados de votação. ... Por padrão, ele está configurado para 8 threads. Se você já baixou o arquivo degvoter.zip e programa em C #, pode facilmente descobrir como ele funciona.
github.com/AlexeiScherbakov/Voting2020