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

https://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/adschema/adschema/a_userworkstations.asp

User Security Attributes

https://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/ad/ad/security_properties.asp