Novas ferramentas, métodos antigos. Fazemos engenharia reversa e descobrimos a falha fatal do 1Password.Todo mundo adora gerenciadores de senhas. Eles são ótimos por muitas razões. Pessoalmente, tenho mais de 200 entradas no gerente. Com tantos dados confidenciais em um só lugar, é importante entender a extensão do dano se o seu registro estiver comprometido, seja malware, exploração ou apenas um computador sem vigilância por vários minutos.
O Washington Post publicou recentemente um artigo baseado em nosso
estudo . Este artigo ajuda a conscientizar as pessoas de que nem todos os gerenciadores de senhas são iguais.
Eu acreditava firmemente que um gerenciador de senhas bloqueadas estava bem protegido. Se alguém obtiver acesso ao meu computador, o máximo poderá contar com um monte de bytes aleatórios, pois as informações são apagadas da memória de forma confiável.
Isso é verdade para o 1Password 4 (observe que a versão mais recente é a sétima hoje). Antes de mudar para ele há alguns anos, verifiquei se realmente não havia senhas quando o gerente estava bloqueado. Portanto, em caso de comprometimento, o invasor precisará lidar com o armazenamento criptografado.
O cofre está trancado!Nesse estado, não há entradas de senha ou senha mestre. Muito razoável e correto, e o 1Password 4 passou neste teste. Ou não?
Para me livrar dos detalhes chatos, direi imediatamente: conseguimos restaurar a senha mestra de uma instância bloqueada no 1Password 4, como mostrado abaixo.
Desbloqueie o 1Password 4 e recupere sua senha mestraA animação mostra que 1Password 4 é primeiro desbloqueado da maneira normal e depois bloqueado. Depois disso, executamos nosso utilitário
multipass , que recupera a senha com êxito. O utilitário explora o processamento incorreto do campo de entrada da senha no 1Password 4 para restaurar o buffer de senha mestre ofuscado, desofuscá-lo, desbloquear automaticamente o 1Password 4 e, finalmente, exibir a senha mestre no console.
Detalhes chatos
A primeira etapa na avaliação de um gerenciador de senhas é verificar uma senha mestra limpa na memória. Isso é possível em qualquer editor hexadecimal capaz de interagir com o espaço na memória do processo. Por exemplo, o editor
HxD gratuito. Use-o para abrir o espaço de memória 1Password 4.
Caímos imediatamente na primeira área legível do espaço de memória 1Password 4.
Exemplo de representação de memória HxDNada de especial ainda. Mas você pode fazer uma pesquisa. Por exemplo, como é a situação se você digitar a senha na janela de desbloqueio 1Password 4, mas não clicar no botão "Desbloquear":
Cofre bloqueado 1Password 4 com a senha mestra inserida no campoCertamente a senha está em algum lugar na memória?
Abrimos o HxD, mas procurar uma linha com nossa senha mestre (“Z3Superpass #”) não produz resultados.
Parece que o 1Password de alguma forma criptografa ou ofusca o formulário quando ele é digitado. Se o procedimento funcionar corretamente, está tudo bem.
Mergulhando mais fundo
Para descobrir por que a senha mestra não pode ser encontrada na memória quando está claramente presente na caixa de diálogo de desbloqueio, você deve encontrar o código que interage com ela. Existem várias maneiras. Você pode acompanhar o processamento de eventos de teclado e mouse localizando 'GetMessage', 'PeekMessage', 'GetWindowText' ou outras APIs do Windows que normalmente lidam com a entrada do usuário. Então, encontramos o buffer no qual as teclas são gravadas e, através delas, passamos à rotina de criptografia / ofuscação. Mas esse é um processo longo e propenso a erros, especialmente com estruturas grandes que às vezes gerenciam a memória de maneira muito estranha; portanto, é necessário fazer muitas cópias e conversões para controlar o buffer.
Em vez disso, usamos nossa própria ferramenta Thread Imager, projetada para fazer engenharia reversa de protocolos proprietários “estranhos” no nível do aplicativo. Isso ajudará você a determinar onde a memória 1Password 4 interage com nossa senha mestra. A ferramenta "automaticamente" identifica áreas de código no 1Password 4 que interagem com uma senha ofuscada (ela simplesmente destaca as instruções que interagem com os dados de interesse para análise posterior). O resultado é algo como isto:
O Thread Imager localiza o código 1Password 4 que interage com uma senha mestre sem focoComo a senha mestre é armazenada na memória de forma ofuscada, a ferramenta deve mostrar primeiro onde ocorre a ofuscação.
Um fragmento do primeiro resultado mostra que a primeira aparência da senha mestre é acompanhada por uma transição de código do endereço 0x7707A75D para 0x701CFA10.
Uma entrada detalhada no Thread Imager destaca a transição de código de 0x7707A75D para 0x701CFA10, enquanto os registros EAX e ECX se referem ao buffer com a senha mestreExaminar este local 0x7707A75D no depurador (x64dbg) confirma nossa teoria. De fato, pela primeira vez, a sequência 'Z3superpass #' ocorre quando a função de decodificação 'RtlRunDecodeUnicodeString' da biblioteca ntdll.dll termina.

Após algumas análises, fica claro que essas duas funções são usadas para ofuscar a senha: 'RtlRunEncodeUnicodeString' e 'RtlRunDecodeUnicodeString'. Portanto, a senha mestra está oculta da cópia primitiva da memória, e é por isso que anteriormente não conseguimos encontrá-la no editor hexadecimal.
Se você estudar o buffer codificado no final da função RtlRunEncodeUnicodeString, a linha criptografada com a senha mestra ficará assim:
Senha Mestra CriptografadaApós RtlRunDecodeUnicodeString ', é decodificado:
Senha mestra descriptografadaCuriosamente, essa área é salva no mesmo endereço 0x00DFA790 e podemos literalmente observar sua alteração ao inserir uma senha na janela de desbloqueio do 1Password 4:
Vulnerabilidade
'RtlRunEncodeUnicodeString' e 'RtlRunDecodeUnicodeString' são funções simples que modificam uma sequência com uma operação XOR simples. Isso não é tão ruim: parece ser o método padrão para mascarar todos os controles de edição nativos do Windows com o conjunto de sinalizadores 'ES_PASSWORD'.
O problema é que, depois de desbloquear o 1Password 4, a senha mestre criptografada não é apagada da memória.
Pior, ele permanece na memória mesmo após o bloqueio da 1Password 4. Ou seja, temos um armazenamento de senhas bloqueadas, mas com uma senha mestre criptografada na memória.
E pior ainda, como interagimos com a caixa de diálogo de entrada de senha mestra, a mesma área de memória é reutilizada com o mesmo valor XOR, o que nos dá acesso fácil ao buffer codificado para criar uma exploração.
Desafio
Para criar uma exploração confiável para o 1Password 4, é necessário obter uma imagem mais clara de como a senha mestra é processada pelos fluxos de trabalho do programa. Usando as ferramentas mencionadas acima, construímos um diagrama de dados de saída (veja a figura abaixo).

Este diagrama facilita a compreensão de onde e quais bibliotecas estão envolvidas, a fim de identificar com segurança áreas da memória nas quais você pode recuperar a senha mestra.
Explorar
O que temos no momento? Temos um armazenamento bloqueado e, em algum lugar da memória, uma senha ofuscada é armazenada, porque o programa não limpou a memória corretamente.
Para recuperá-lo, você precisa chamar o procedimento no 1Password 4, que inicia o 'RtlRunEncodeUnicodeString' e 'RtlRunDecodeUnicodeString'. Assim, mostrará a localização do buffer de memória com a senha mestre codificada.
Área de memória com uma senha mestra ofuscadaSem esse buffer, seria necessário mergulhar no abismo de procedimentos internos, controles do Windows e mecanismos de gerenciamento de memória relacionados. Talvez essa análise facilite a localização de um buffer, mas não fomos por esse caminho.
Parece que a única maneira de chamar 'RtlRunEncodeUnicodeString' e 'RtlRunDecodeUnicodeString' é inserir a senha mestra no caractere na caixa de diálogo. Então, obtemos o buffer desejado. Mas não sabemos o tamanho da senha.
Resolvemos esse problema interceptando o código que acessa o primeiro caractere do nosso buffer, bloqueando uma tentativa de alteração. Essa rotina está no loop de mensagens de controle em comctl32, que lida com o controle de buffer dos elementos correspondentes. Chamar 'memmove' com deslocamento 0x70191731 substitui o buffer pelo caractere inserido:
(Efeito colateral: a linha destacada (amarela) atualiza toda a linha da senha)Agora finalmente conseguimos tudo o que precisamos para criar uma exploração. As etapas a seguir nos permitem extrair a senha mestra:
- Ligue 'memmove' para evitar a substituição do primeiro byte da senha principal.
- Ligue 'RtlRunEncodeUnicodeString' para obter a localização do buffer da senha principal ofuscada.
- Gancho 'RtlRunDecodeUnicodeString' para acessar o buffer ofuscado obtido na etapa anterior.
- Digitando um caractere no campo de entrada da senha e recusando a etapa 1 (salvando toda a senha mestre), redirecionando as etapas 2 para a etapa 3 para decodificar a senha mestre ofuscada.
Para executar todas essas ações, crie uma DLL com o código do manipulador para todos esses ganchos. A biblioteca é incorporada no processo 1Password 4, envia um caractere para a caixa de diálogo de senha mestre, iniciando as etapas memmove, RtlRunEncodeUnicodeString e RtlRunDecodeUnicodeString que podemos interceptar - e fazendo nossa mágica para recuperar a senha mestre ofuscada. A maior parte da mágica acontece no DetourRtlRunEncodeUnicodeString, este é o gancho da função 'RtlRunEncodeUnicodeString', mostrada abaixo:
O que nos leva ao resultado final: desbloquear o repositório bloqueado 1Password 4 de qualquer versão usando o procedimento de buggy usado pela API do Windows:

Sumário
Quando nos aprofundamos no interior do 1Password 4, esperávamos encontrar algum tipo de sistema de segurança complexo e esperávamos que todas as informações confidenciais fossem apagadas da memória, como acontece nos procedimentos do PBKDF2 e em outras áreas em que a senha mestra é usada. Entradas correspondentes também são limpas. No entanto, devido à supervisão, o campo de entrada da senha é considerado como um controle padrão da API do Windows com uma senha oculta, o que prejudica a segurança do 1Password 4.