Como auditamos Mail.ru Corporate Mail - nosso novo serviço para grandes empresas





Os dados corporativos costumam ser um segredo comercial. Vazá-los pode causar um golpe à reputação, perdas financeiras ou até mesmo à falência. Portanto, os requisitos de segurança para um produto B2B devem ser muito altos. Criando um novo produto - Corporate Mail Mail.ru - demos atenção especial à questão de sua segurança.



Corporate Mail Mail.ru é uma versão local do conhecido correio B2C Mail.ru. Comparado a ele, ele contém uma série de modificações para trabalhar em um novo ambiente - o circuito do cliente.



Para deixar nossos clientes confiantes na segurança, decidimos fazer uma auditoria em uma empresa terceirizada e corrigir todas as deficiências que encontramos antes de oferecer o produto ao mercado. Para isso, recorreram a uma das empresas mais conceituadas na área de segurança da informação - Segurança Digital.



Os resultados da auditoria estão sob o corte.



Execução remota de código em uWSGI



Existem diferentes estruturas para a construção de aplicativos da web Python. Normalmente, o Python Web Server Gateway Interface (WSGI) é usado para a comunicação entre o aplicativo da web e o servidor da web. Além disso, o uso de WSGI permite implementar componentes de middleware.



Para padronizar a comunicação entre uma aplicação web Python e um servidor web como Apache ou Nginx, o PEP 0333 foi desenvolvido, seguido pelo PEP 3333, que descreve a interface WSGI. Não vamos nos alongar sobre como funciona o WSGI, mas falaremos sobre um servidor popular que suporta a interface WSGI - uWSGI.







O servidor uWSGI pode funcionar tanto no modo de servidor web normal como no "modo WSGI", trocando dados com outro servidor web, como o Nginx. Ao mesmo tempo, o Nginx usa o protocolo binário de mesmo nomeuwsgi , que é interessante para os cibercriminosos devido à sua rica funcionalidade. Ao analisar os "internos" da solução, foi encontrado um servidor uWSGI, ao qual todos os componentes internos do produto tinham acesso.



O problema era que o protocolo uwsgi pode usar as chamadas variáveis ​​mágicas que permitem configurar dinamicamente o servidor uWSGI. Entre essas variáveis, há UWSGI_FILEuma que permite carregar um novo aplicativo dinâmico se você especificar o caminho para o arquivo na variável. Como se viu, uWSGI-servidor pode lidar com diferentes circuitos, desta forma, por exemplo section, fd, callou mais interessante - exec. Assim, você pode passar a variável como um valorexec://<cmmand>para executar um comando bash arbitrário. Um exploit foi escrito para analisar este problema e está disponível no github .





Um exemplo de consulta que executa um comando.



Esta vulnerabilidade só pode ser explorada se o invasor:



  • Já está na rede interna do produto, por exemplo, um dos componentes foi comprometido. Isso pode permitir que ele sequestre um novo componente, obtenha acesso a novos dados e continue o ataque.
  • Possui SSRF com a capacidade de enviar dados arbitrários sobre TCP (por exemplo, usando gopher://). Nesse cenário, um invasor pode obter acesso ao interior do produto.


É importante notar que as implementações de interfaces CGI para outras linguagens de programação ou frameworks também podem ser vulneráveis, por exemplo, um exploit do mesmo repositório para FastCGI. Isso não quer dizer que seja uma vulnerabilidade no sentido usual, mas sim um recurso dos servidores CGI, portanto, você precisa limitar o acesso a esses servidores o máximo possível.



Ignorando a proteção CSRF



Com a introdução de vários mecanismos de segurança nos navegadores, os ataques do lado do cliente na web moderna estão desaparecendo gradualmente. Isso também se aplica ao CSRF: os navegadores já implementaram o suporte para o cookie SameSite, embora se configurado incorretamente, ainda possa haver lacunas. Além disso, muitas estruturas populares permitem que os desenvolvedores configurem facilmente a proteção contra CSRF, mas alguns bugs ou vulnerabilidades não críticas podem se transformar em um potencial de ataque de CSRF. Esses erros foram encontrados no aplicativo de calendário incluído em nosso produto.



O aplicativo possui uma API que permite realizar ações sobre os eventos e calendários do usuário, como por exemplo: editar, visualizar ou deletar. Para fazer referência ao objeto, o parâmetro UID é passado no caminho da URL, que é responsável pelo ID do calendário ou evento. Se parece com isso:



example.com/api/calendar/{UID}/action?
example.com/api/event/{UID}/action?






Por padrão, o UID é gerado aleatoriamente e não pode ser influenciado pelo usuário. Já no aplicativo, foram encontrados dois locais nos quais o usuário pode alterar o UID.



A primeira é importar arquivos no formato ICS (um formato especial para calendários e eventos), eles possuem um campo UID especial que o usuário controla ao importar. Neste caso, após a importação dos eventos, seus UIDs permanecerão os mesmos que foram transferidos no arquivo. Além disso, este parâmetro não tem filtragem. Assim, o usuário pode criar um evento com um UID arbitrário.



O segundo é a capacidade de alterar o calendário UID ao editá-lo. Isso pode ser feito interceptando a solicitação para editar o calendário e simplesmente alterando o campo UID. Não houve filtragem aqui também.



Outra característica importante: esta API implementa proteção CSRF, para isso, um parâmetro especial é passado nos parâmetros GET, que desempenha o papel de chave para a API e de token CSRF. Ele é adicionado via JavaScript a todas as solicitações de API. É uma má prática passar tokens CSRF em parâmetros GET; neste caso, os tokens podem vazar através do referenciador, logs do aplicativo ou histórico do navegador.



Juntando tudo. Um invasor pode controlar UIDs de objeto em um aplicativo e compartilhar o acesso a eventos e calendários com outros usuários. Nesse caso, os usuários verão o mesmo UID e, quando começarem a trabalhar com tal objeto, as solicitações serão executadas com o UID controlado pelo invasor. Usando isso, um invasor pode fazer um objeto com um UID como este:



../../../AnyPathTo?anyparam=value&


Agora, quando o usuário realizar uma ação no objeto, uma solicitação será gerada:



example.com/api/event/../../../AnyPathTo?anyparam=value&/action


Em seguida, um token também será adicionado a ele, desempenhando o papel de um token CSRF:



example.com/api/event/../../../AnyPathTo?anyparam=value&/action&token=abcdef


E por fim, fazendo a solicitação, o navegador normaliza a sequência " ../", assim a solicitação será enviada para



example.com/AnyPathTo?anyparam=value&/action&token=abcdef


Agora, um invasor pode forçar um usuário a enviar uma solicitação ao aplicativo por um caminho arbitrário com parâmetros arbitrários e com o token CSRF correto. Resta entender quais métodos de solicitação podemos executar.



Acabou por ser simples: ao editar, envia-se PUT, ao eliminar, DELETE, ao visualizar, GET (o POST é utilizado para criar e não podemos obrigar a vítima a utilizá-lo). Ao usar DELETE, um invasor pode forçar o navegador do usuário a executar uma solicitação para excluir um objeto do usuário. Um bônus separado para um invasor é que, quando um usuário edita um objeto, uma solicitação PUT é enviada com o corpo da solicitação. Ao editar um calendário, o corpo da solicitação conterá JSON, que contém todos os parâmetros do calendário atual. Ou seja, o invasor que criou o calendário “malicioso” controla esses parâmetros. Se um invasor conseguir redirecionar uma solicitação de edição do calendário “malicioso” para o calendário privado do usuário, todas as propriedades do calendário “malicioso” serão aplicadas às propriedades do calendário do usuário da vítima.Isso pode substituir o acesso ao calendário porque é uma das propriedades do calendário especificadas em JSON.







Capacidade de ataque MITM



A penetração de um intruso na rede interna da empresa é uma situação perigosa com graves consequências. Portanto, durante a auditoria do produto, uma de nossas tarefas era encontrar falhas na arquitetura do sistema que pudessem ajudar um invasor a se mover pelo domínio ou melhorar ataques externos.



Um dos principais recursos do produto é a integração com o Active Directory. Ele é implementado para autenticação via LDAP e coleta de mensagens do servidor Exchange, neste exemplo vamos nos concentrar no ActiveSync. Para um invasor, esse é um alvo muito interessante porque contas de usuário e senhas são passadas entre o produto e o Active Directory durante a conexão. Ao obter acesso às conexões, um invasor poderá sequestrar contas e estará um passo mais perto de comprometer o domínio.



Em soluções internas e nos servidores de empresas, muitas vezes há um problema com o uso incorreto do TLS ou sua ausência, embora não seja difícil implementar o TLS para um serviço. Isso geralmente é uma consequência do fato de que a rede interna da empresa é considerada mais segura e os administradores da empresa não perdem tempo criando a infraestrutura de PKI correta e emitindo certificados para todos os servidores.



O ataque mais comum dentro de redes corporativas é MITM. Esse tipo de ataque geralmente permite o acesso dentro do Active Directory de uma empresa. Ao mesmo tempo, nem sempre é possível para um invasor atacar a interação servidor a servidor dentro da rede da empresa; na maioria das vezes, durante os testes de penetração, ele ou seu modelo cai em um segmento de rede de usuário em que não há servidor Exchange ou controlador de domínio. Além disso, em nosso caso, o produto não usa protocolos de resolução de nomes de transmissão, como NBNS, LLMNR, mDNS, portanto, a falsificação desses protocolos não permitirá que o MITM seja implementado. Assim, para um MITM bem-sucedido entre a solução e outros servidores, é necessário que o invasor tenha acesso à rede onde um desses componentes está instalado. Às vezes, é possível atingir esse objetivo - há roteadores ou servidores vulneráveis,que, em última análise, permitem que você acesse uma rede específica



Em nosso caso, durante a análise, descobriu-se que a integração com o Active Directory é vulnerável a ataques MITM.



Quando o usuário insere um nome de usuário e uma senha, o sistema envia duas solicitações LDAP ao controlador de domínio. A primeira solicitação retorna uma lista de endereços de e-mail e, se o login do usuário estiver presente nesta lista, a segunda solicitação é enviada, que é Autenticação LDAP Simples. Os dados são transmitidos em texto não criptografado sem usar SSL / TLS, ou melhor, LDAPS (LDAP sobre SSL) não é usado. Isso permite que um invasor, mesmo no caso de um ataque passivo MITM, obtenha contas de usuário que estão atualmente autorizadas no produto.







O segundo problema: ao se conectar a um servidor Exchange usando o protocolo ActiveSync para coletar mensagens de entrada, o sistema não autenticou o certificado TLS do servidor. Nesse caso, um invasor poderia implementar um ataque MITM ativo; ao receber uma conexão, ele poderia fornecer um certificado autoassinado, estabelecer uma conexão e fazer proxy dos dados para o servidor Exchange; então, o MITM ficará invisível e um invasor poderá obter as credenciais do usuário, que são transmitidas no protocolo ActiveSync.







Ao explorar essas vulnerabilidades, um invasor pode teoricamente obter contas de usuário e usá-las para atacar o domínio do Active Directory. Separadamente, deve-se destacar que o uso correto do TLS é uma tarefa necessária para uma empresa que implementa uma solução.



Resultado



Estamos constantemente enfrentando ataques de hackers e ganhamos sólida experiência em como combatê-los. Acreditamos que os produtos que colocamos no perímetro do cliente devem ser o mais seguros possível, inclusive com base nos resultados de verificações independentes. Corporate Mail Mail.ru é um desses produtos.



Fomos confrontados com uma tarefa trabalhosa: transferir uma grande base de código com muitos microsserviços para a infraestrutura do cliente, para que o correio funcionasse sozinho na maior parte do tempo, sem falhas e intervenções do administrador.



Pedimos aos auditores que prestassem a maior atenção à alteração da autorização (o Correio Corporativo utiliza o AD do cliente) e à API de correio principal - o código-fonte destes componentes foi analisado em detalhe. Como resultado, as deficiências encontradas foram principalmente relacionadas à topologia de rede alterada e modificações específicas para a solução local.



Para o restante dos componentes (calendário, Mail.ru para interface de administração de negócios), um modelo de caixa cinza foi usado: os auditores interagiam com o serviço com os privilégios de usuários comuns, mas podiam se conectar ao contêiner com o aplicativo em execução, possuíam parcialmente o código-fonte da API e podiam esclarecer os detalhes com os desenvolvedores.



A auditoria foi muito útil para nós. Encontramos uma série de deficiências em alguns dos componentes, que prontamente corrigimos para colocar um produto seguro no mercado. Ao mesmo tempo, estávamos convencidos do alto nível de proteção da maioria dos outros componentes. Planejamos realizar tais auditorias regularmente - queremos que nosso produto esteja sempre no topo das soluções domésticas mais seguras, não apenas em nossa opinião, mas também na opinião de auditores independentes.



A segurança do Correio Corporativo é a combinação da segurança do próprio produto com a infraestrutura do cliente. Ou seja, a responsabilidade pela segurança dos dados corporativos é nossa, do desenvolvedor e do próprio cliente. Além disso, formulamos recomendações sobre práticas comprovadas para proteger a infraestrutura de falhas e sempre aconselhar os clientes durante a instalação de nosso produto.



All Articles