Sua aplicação está pronta para um ambiente seguro – PARTE II
Por Yuri Diógenes
1. Introdução
Em Maio deste ano eu havia escrito o que foi a parte um deste arquivo, porém nem imaginava de fato que haveria uma parte 2, mas o dia a dia vem me mostrado duas coisas:
· Primeiro que muitas empresas já se preocupam de fato com a segurança da informação e investem nisso – o que é ótimo;
· Segundo que muitas empresas tem aplicações antigas que ainda não estão prontas para trabalhar em um ambiente seguro – o que é fato;
A dias atrás trabalhei em um outro caso onde o vilão parecia ser o sistema operacional, porém após vários testes podemos concluir que não era, mas até chegar a essa conclusão muita coisa aconteceu.
Vamos entender o cenário:
· O cliente tem uma aplicação que faz uso do protocolo LDAP para fazer consultas no Active Directory;
· O usuário ao se conectar no AD usando LDAP ele passa suas credenciais via linha de comando;
· No passado este usuário da aplicação podia usá-la sem maiores problemas e fazer suas consultas no AD também sem problemas;
Problema: Após a empresa implementar algumas políticas de segurança o usuário passou a não conseguir mais utilizar esta aplicação de forma alguma.
2. Obtendo Dados
Primeiramente foi necessário um trabalho de investigação para saber o que tinha mudado no aspecto de segurança, para minha sorte o cliente ainda estava no início da implementação o que facilitou meu trabalho pois não tive que trilhar muito para achar uma pista fundamental.
Uma das políticas que foi implementada foi a de que os usuários só poderiam efetuar logon na rede a partir de algumas estações de trabalho, uma política simples mas eficaz e antiga (temos isso desde o NT 3.51) mas funcional. Lembra desta política? Fica nas propriedades do usuário como mostra abaixo:
Neste momento você deve estar pensando: fácil, basta colocar a estação a qual o usuário está efetuando o logon e pronto. Bem, não foi bem assim, apesar de que isso também me veio em mente, porém mesmo adicionando a estação a qual o usuário poderia efetuar o logon, continuávamos recebendo o erro de acesso negado.
Foi aí que resolvemos fazer um teste rodando localmente (no Domain Controller) e também tivemos problemas, então colocamos o Domain Controller na lista de computadores autorizados para aquele usuário logar e funcionou.
Depois disso testamos com outras coisas e sempre que o Domain Controller estava na lista de computadores a qual o usuário poderia logar a aplicação que usava LDAP conseguia fazer a autenticação. Intrigante não?
3. Fazendo o “Narrow Down” do problema...
Neste momento houve um certo “stress” por parte do cliente pois a princípio ele achava que era um furo da política de segurança que só deixava o usuário logar caso o DC estivesse na lista. Isso foi algo que não me convenceu também, porém como estávamos lidando com uma aplicação de terceiros e não tínhamos conhecimento de como ela funcionava por de trás dos panos então resolvemos usar uma ferramenta nossa para fazer o teste, foi aí que usamos o LDP.EXE. Quando estamos conectando via LDP temos a opção de passar as credencias do usuário que está efetuando o logon, conforme mostra a figura abaixo:
Então tiramos o DC da lista de computadores que o usuário estava permitido de efetuar o logon, deixamos apenas a estação local a qual ele estava logado. Resultado: funcionou sem problemas.
4. E por que isso?
Agora que já sabemos que com o nosso LDAP funciona resta saber por que, afinal temos não só que resolver mas também provar o porque e defender nossa tese. Para isso nada melhor que o velho e bom Network Monitor, lembre-se: tudo que passa pela placa de rede do computador a qual você está investigando é capturado pelo netmon, então a melhor forma de saber o que realmente está acontecendo é olhar os pacotes, claro pode levar tempo e pode ser algo que não é tão claro para alguns, porém eu recomendo você começar a se familiarizar bem com isso.
Vamos então ao teste número 1:
· Uso do LDP.EXE para se conectar ao AD via LDAP:
1. Cliente faz uma requisição na porta TCP 389:
192.1.16.15 192.7.11.12 TCP 4507 > ldap [SYN]
2. Servidor concorda com a conexão
192.7.11.12 192.1.16.15 TCP ldap > 4507 [SYN, ACK]
3. O MS LDP (no lado do cliente) envia então o “Bind Request” onde passa as credencias e neste caso usa o método NTLM de autenticação:
192.1.16.15 192.7.11.12 LDAP MsgId=13
Bind Request, DN=(null), NTLMSSP_AUTH, User: DOMAINNAME \TestUser
Lightweight Directory Access Protocol
LDAP Message, Bind Request
Message Id: 13
Message Type: Bind Request (0x00)
Message Length: 225
Response In: 3175
Version: 3
DN: (null)
Auth Type: SASL (0x03)
Mechanism: GSS-SPNEGO
GSS-API Generic Security Service Application Program Interface
NTLMSSP
NTLMSSP identifier: NTLMSSP
NTLM Message Type: NTLMSSP_AUTH (0x00000003)
Lan Manager Response:
F1DC6D4CFFCD04F900000000000000000000000000000000
Length: 24
Maxlen: 24
Offset: 134
NTLM Response: F2988187EC1C67496EDF4F46313F401E08F688325DC541A8
Length: 24
Maxlen: 24
Offset: 158
Domain name: DOMAINNAME
Length: 18
Maxlen: 18
Offset: 72
User name: TestUser
Length: 32
Maxlen: 32
Offset: 90
Host name: COMPUTADOR1
Length: 12
Maxlen: 12
Offset: 122
Session Key: 33724B7018EADC94650FCAAB1F6741EF
Length: 16
Maxlen: 16
Offset: 182
Flags: 0xe2888215
4. O servidor envia uma mensagem de autenticação com sucesso:
192.7.11.12 192.1.16.15 LDAP MsgId=13 Bind Result
Lightweight Directory Access Protocol
LDAP Message, Bind Result
Message Id: 13
Message Type: Bind Result (0x01)
Message Length: 9
Response To: 3174
Time: 0.001953000 seconds
Result Code: success (0x00) <---------------------- SUCCESSO
Matched DN: (null)
Error Message: (null)
Bem, com isso sabemos exatamente como nossa aplicação está se comportando durante a autenticação, ou seja, está usando NTLM.
Vamos então ao teste número 2:
· Uso da aplicação de terceiros para se conectar ao AD via LDAP:
1. O cliente faz uma requisição de acesso na porta TCP por 389 (dispensarei a visualização dos pacotes pois não há mudança de comportamento)
2. O servidor concorda com a requisição;
3. O cliente então envia o “Bind Request” e agora vem a diferença:
192.1.16.15 192.7.11.12 LDAP MsgId=1 Bind Request, DN=CN=TestUser,OU=Test,DC=domainname,DC=local
Lightweight Directory Access Protocol
LDAP Message, Bind Request
Message Id: 1
Message Type: Bind Request (0x00)
Message Length: 83
Response In: 998
Version: 3
DN: DN=CN=TestUser,OU=Test,DC=domainname,DC=local
Auth Type: Simple (0x00) <-------------------- Método Simples de Autenticação
Password: 12345678
4. O servidor então envia o resultado abaixo:
192.7.11.12 192.1.16.15 LDAP MsgId=1 Bind Result, invalidCredentials
Lightweight Directory Access Protocol
LDAP Message, Bind Result
Message Id: 1
Message Type: Bind Result (0x01)
Message Length: 94
Response To: 997
Time: 0.001954000 seconds
Result Code: invalidCredentials (0x31) <-------------- ERRO
Matched DN: (null)
Error Message: 80090308: LdapErr: DSID-0C090334, comment:
AcceptSecurityContext error, data 531, vece
Agora que temos o cenário que funciona e o que não funciona já podemos dizer que:
· Consulta LDAP via LDP.EXE está usando o método de autenticação NTLM;
· Consulta LDAP via aplicação de terceiro está usando autenticação simples;
O protocolo LDAP implementado pela Microsoft poderá ter os seguintes métodos de autenticação:
Método de Autenticação |
Descrição |
LDAP_AUTH_SIMPLE |
Autenticação simples com texto limpo. |
LDAP_AUTH_NTLM |
Autenticação NT Lan Manager |
LDAP_AUTH_DPA |
Autenticação distribuída, usada pelo MMS (Microsoft Membership System) |
LDAP_AUTH_NEGOTIATE |
Generic security services (GSS) |
LDAP_AUTH_SSPI |
Método antigo o qual está incluso por compatibilidade retroativa. |
Fonte da Tabela: White Paper Understanding LDAP
Agora vem a pergunta: o que tem haver o método de autenticação do usuário com a política de segurança que define que estações o usuário pode logar?
Vejamos então como todo o processo ocorre:
1. A aplicação de terceiro envia uma consulta LDAP para o AD usando o método de autenticação simples (LDAP_AUTH_SIMPLE). Este tipo de método envia uma string que contém apenas o nome do usuário e senha;
2. Quando o DC recebe este pedido de autenticação do cliente o DC então verifica as credenciais do usuário assim como as propriedades da conexão para checar se o computador a qual o usuário está locado está na lista dos computadores autorizados para aquele usuário;
3. Como a aplicação envia uma requisição simples de autenticação LDAP o nome do computador não vai junto do pacote então o DC usa o nome NetBIOS dele mesmo para fazer a autenticação.
4. O DC então verifica se o nome NetBIOS dele mesmo está contido ou não na lista dos computadores (atributo userWorkstations) autorizados e neste caso como não está então retorna um “Access Denied”.
Agora fica fácil entender o por que de que quando colocávamos o nome do DC na lista a autenticação funcionava. O problema não ocorre com NTLM pois o nome do computador vai junto do pacote, conforme mostra a captura de rede apresentada anteriormente. Vamos rever os campos contidos no pacote LDAP usando NTLM:
NTLM Response: F2988187EC1C67496EDF4F46313F401E08F688325DC541A8
Length: 24
Maxlen: 24
Offset: 158
Domain name: DOMAINNAME
Length: 18
Maxlen: 18
Offset: 72
User name: TestUser
Length: 32
Maxlen: 32
Offset: 90
Host name: COMPUTADOR1
Length: 12
Maxlen: 12
Offset: 122
Session Key: 33724B7018EADC94650FCAAB1F6741EF
Length: 16
Maxlen: 16
Offset: 182
Flags: 0xe2888215
5. Conclusão
Ambiente seguro é algo de extrema importância nos dias de hoje, porém tão importante quanto isso é um ambiente de validação das políticas de segurança, principalmente quando estamos saindo de um ambiente onde existem aplicações antigas que não se preocupam com o aspecto de segurança. A implementação de novas políticas trazem benefícios ao negócio mas também podem ser tornar uma dor de cabeça caso não seja bem planejado.
6. Referências
Understanding LDAP
https://www.microsoft.com/windows2000/techinfo/howitworks/activedirectory/ldap.asp
User-Workstations Attribute
User Security Attributes
Comments
- Anonymous
September 24, 2006
The comment has been removed - Anonymous
September 28, 2006
The comment has been removed