Azure AD

Sincronização de hash de senhas (PHS – Password Hash Sync) no AAD Connect

Pessoal, o Bruno Freitas | LinkedIn e eu fizemos um artigo para que vocês possam ter uma visão geral do sincronismo de hash de senhas usando o Azure AD Connect.

Vamos aproveitar esse espaço para desmistificarmos uma questão que ainda hoje gera muita informação incorreta e dúvidas. Mostraremos que esse é um método seguro e não há risco de envio de senhas em texto puro, é um pouco mais complexo que isso. Esse é o método recomendado para que você tenha acesso à funcionalidades avanças de proteção da identidade, como o monitoramento de senhas vazadas na internet (Azure Identity Protection). Este é um artigo técnico, por mais que tentemos simplificar, alguns termos técnicos serão usados.

Essa é, sem dúvidas, a maneira mais fácil e rápida para implementarmos um modelo de autenticação. Nesse modelo, os usuários podem usar o mesmo nome de usuário e senha que usam localmente, sem a necessidade de implantar nenhuma infraestrutura adicional.

O processo de hash, a princípio parece muito complexo, mas vamos explicar aqui para que fique claro que ele é um método confiável e seguro.

O serviço de domínio do Active Directory armazena as senhas na forma de uma representação de valor de hash da senha de usuário real. Um valor de hash é um resultado de uma função matemática unidirecional (o algoritmo de hash). Não há um método para reverter o resultado de uma função unidirecional para a versão de texto sem formatação de uma senha. 

Quando o Azure AD Connect inicia o processo de sincronização, ele extrai o hash da senha de usuário da instância do Active Directory local e um processamento de segurança adicional é aplicado ao hash da senha antes que ela seja sincronizada com o serviço de autenticação do Azure AD. As senhas são sincronizadas por usuário e em ordem cronológica. 

O fluxo da sincronização é bem parecido com a sincronização de um usuário, mas no caso das senhas, a janela de sincronismo é menor e a senha é replicada em até 2 minutos. Já os usuários, por padrão, são sincronizados em uma janela de 30 minutos. Para o processo da senha, não é possível alterar esse valor. Na primeira vez que você habilitar o recurso de sincronização de hash de senha, ele executará uma sincronização inicial dos hashes de todos os usuários no escopo. 

Vou exemplificar abaixo o processo de hashing e sincronização das senhas:

1. Como vimos, a cada 2 minutos, o agente de sincronização no servidor do AD Connect solicita os hashes de senha armazenados (o atributo unicodePwd) de um Controlador de Domínio. Essa solicitação é feita através do protocolo de replicação padrão MS-DRSR usado para sincronizar dados entre controladores de domínio do AD. A conta do serviço deve ter as permissões do AD “Replicar Alterações de Diretório e Replicar Todas as Alterações de Diretório” (Replicate Directory Changes and Replicate Directory Changes All AD permissions), as quais são concedidas por padrão durante a instalação, para obter os hashes de senha.

2. Antes de enviá-la, o controlador de domínio criptografa o hash de senha MD4 usando uma chave que é um hash MD5 da chave de sessão RPC e um valor adicional de “salt”. Podemos dizer que ele “salga” esse valor com um valor adicional para evitar que duas senhas idênticas produzam hashes idênticos.

Para que fique claro esse processo, vamos entrar mais a fundo nesse processo de “salt”. O salt é uma cadeia de caracteres aleatória e concatenada com uma senha. Imagine que eu crie a minha senha fraca, algo como, “minhasenha123”. Quando eu aplico o salt à essa senha, eu tenho algo como: PROCESSOALEATORIODESALTminhasenha123.

Depois disso, o resultado é enviado para o agente de sincronização de hash de senha por RPC. O controlador de domínio também passa o salt para o agente de sincronização usando o protocolo de replicação do controlador de domínio, para que o agente possa descriptografar o envelope.

3. Depois que o agente de sincronização de hash de senha tiver o envelope criptografado, ele usará MD5CryptoServiceProvider e o salt para gerar uma chave para descriptografar os dados recebidos de volta para seu formato original de MD4. O agente de sincronização de hash nunca tem acesso à senha de texto não criptografado. O uso que o agente de sincronização de hash de senha faz do MD5 é estritamente para compatibilidade de protocolo de replicação com o controlador de domínio, e é usado somente no local entre o controlador de domínio e o agente de sincronização de hash de senha.

4. O agente de sincronização de hash de senha expande o hash de senha binária de 16 bits para 64 bytes convertendo primeiro o hash em uma cadeia hexadecimal de 32 bytes, depois convertendo essa cadeia de caracteres de volta para o binário com a codificação UTF-16. 

5. O agente de sincronização de hash de senha adiciona um salt por usuário – que é composto por um salt de 10 bytes – ao binário de 64 bytes a fim de proteger ainda mais o hash original.

6. Em seguida, o agente de sincronização de hash de senha combina o hash MD4 e o salt por usuário e usa o resultado como entrada na função PBKDF2. São usadas 1000 iterações do algoritmo de hash com chave HMAC-SHA256

7. O agente de sincronização de hash de senha usa o hash de 32 bytes resultante, concatena tanto o Salt por usuário quanto o número de iterações SHA256 a ele (para uso pelo Azure AD) e, em seguida, transmite a cadeia de caracteres de Azure AD Connect para o Azure AD por TLS; Este hash é identificado internamente como OrgID Hash

8. Quando um usuário tenta entrar no Azure AD e insere sua senha, a senha é executada por meio do mesmo processo de MD4 + sal + PBKDF2 + HMAC-SHA256. Se o hash resultante corresponder ao hash armazenado no Azure AD, isso significa que o usuário digitou a senha correta e será autenticado.

Vejamos agora uma forma mais elucidativa sobre como um OrgID Hash chegaria ao Azure AD, utilizando o Powershell:

1. Usando o módulo DSInternals é possivel realizar as operações criptográficas citadas anteriormente; Você pode instalá-lo usando o Install-Module DSInternals

2. Após a instalação, criar uma variável para armazenar a senha que será convertida, como na figura abaixo:

 3. Agora, a senha armazenada na variável criada na etapa 2 será transformada no NT Hash (MD4 Hash), que é armazenado no atributo unicodePwd:

4. É possivel conferir o hash que foi gerado executando somente a variável criada anteriormente ($hash):

5. Agora, o NT Hash criado anteriormente será transformado no OrgId Hash (Função PBKDF2 – 1000 Interações de HMAC-SHA256):

 Resultado da conversão:

É possível observar então a string aproximada que é enviada ao Azure AD pelo AAD Connect.

6. O Valor “8110b5f1fc10895298a7” disponível na string do OrgID Hash é o Salt gerado randomicamente, e é possível fazer uma checagem contra a senha gerada na etapa 2, para conferir se o hash gerado será o mesmo:

Hash gerado anteriormente :

(“d4b03d3daaa784d4f9140ff4c79fa9ef11b02acc597f3e824e8807cd840d2c94”)

Conversão da senha gerada na etapa 2 com o Salt gerado na etapa 5:

Resultado:

Obrigado! Esperamos ter ajudado no esclarecimento. Qualquer dúvida nos mande uma mensagem.

Tiago Souza

Tiago Souza

Security Technical Specialist