É hora de repensar a segurança do OpenBSD

O OpenBSD está posicionado como um sistema operacional seguro. No entanto, nos últimos meses, foram encontradas várias vulnerabilidades no sistema. Claro, não há nada de extraordinário nisso. Embora algumas vulnerabilidades sejam bastante incomuns. Você pode até dizer crítico. Os desenvolvedores do OpenBSD têm várias diretrizes sobre como garantir a segurança. Aqui estão dois deles:

  • evitar erros;
  • minimizar o risco de erros.

Nem todo mundo concorda que esses princípios são suficientes para construir sistemas seguros. Parece-me que faz sentido estudar se a abordagem do OpenBSD funciona ou se está inicialmente condenada.

Para ilustração, não selecionei tudo, mas apenas alguns bugs interessantes que acidentalmente coincidem com o tópico da nossa conversa.

autenticação libc


As funções de autenticação executam auxiliares sem verificação de argv. Relatório . Patch .

Este é um erro surpreendentemente simples, mas provavelmente não parecia muito óbvio durante a revisão do código. Parece-me, em parte, o motivo de alguma confusão é quem é responsável pela verificação dos dados de entrada. Você pode chamar cada um dos três componentes envolvidos: um programa, uma biblioteca ou login_passwd - e é razoável supor que alguém esteja verificando. No final, acho que a biblioteca foi considerada culpada, porque foi para ela que um patch apareceu, mas pessoalmente, à primeira vista, seu código não parece estar claramente errado.

Uma parte mais interessante da história é que, mesmo com o erro da libc mencionado, a função login_passwdEu não ficaria vulnerável dessa maneira se não fosse por outro bug. Em 2001, o login_passwd foi reescrito para dar suporte ao kerberos, e talvez tenha sido quando eles introduziram qual é a verdadeira causa do erro. Uma oferta de autenticação do tipo solicitação-resposta (como no sistema s / key) retorna um estado autenticado, não um silêncio. Muitos anos depois, o código kerberos foi excluído, mas parte do código para suportá-lo permaneceu, assim como o erro introduzido.

Se o código do kerberos fosse completamente limpo, o bug de autenticação ainda permaneceria (havia outros problemas relacionados à análise de argv), mas seu efeito certamente diminuiria bastante.

Não é fácil analisar corretamente o argv em um contexto de segurança. Muitas dicas e abordagens lógicas não funcionam aqui. Vou apenas observar que esta vulnerabilidade apareceu apósoutra discussão sobre o problema com nomes de arquivos no Unix / Linux / POSIX , embora o sinal de menos inicial (hífen) não se refira realmente ao nome do arquivo.

ld.so


Variáveis ​​de ambiente incorretas não foram removidas do código ld.so. Relatório . Patch .

Algo como um erro de memória. Mas não. O bug aqui é vincular o sucesso de uma operação - dividindo a variável de ambiente - para excluir essa variável. Muito confiante.

Obviamente, os proponentes de vários sistemas de digitação garantirão que processarão essas operações na ordem correta, mas não o fato de que isso ajudará. O código C não travou devido à falta de tratamento de erros ou porque o erro de alocação de memória permaneceu invisível.

ftp


O ftp segue os redirecionamentos para arquivos locais. Relatório . Patch .

O bug de redirecionamento de FTP do NetBSD tem sido um exemplo típico de funções não controladas . E aqui novamente o mesmo erro (felizmente, com pequenas consequências)! Gente, bem, sente-se em casa. Não adicione recursos extras aos seus programas.

smtpd de


O smtpd não pode verificar alguns endereços de remetente. Relatório . Patch . Comentário .

Penso que tudo foi dito no comentário de Gilles, mas lembrarei o pano de fundo. Era uma vez, todo o correio era armazenado localmente para cada usuário em / var / mailem arquivos mbox. Isso não é muito legal, porque há uma chance de danos se o mua excluir o email enquanto o mda entregar um novo (sem mencionar outros problemas, como distorcer o campo De). Portanto, o arquivo mbox precisa estar bloqueado. Mas o bloqueio em um sistema de arquivos de rede não funciona de maneira confiável. Então, em vez de bloquear, usamos arquivos de bloqueio. No entanto, você precisa chegar a um acordo sobre um protocolo de bloqueio específico, porque o usuário possui os arquivos mbox e a própria raiz possui o diretório. Portanto, para modificar o arquivo mbox, você precisa executar a função auxiliar setuid todas as vezes. Bem, este é o primeiro problema. Outra relíquia dos velhos tempos são as configurações de mda, que podem ser usadas não apenas como um programa, mas como um pipeline de shell. As pessoas prescrevem algo comospam-assassin | mail.mdae você não pode simplesmente passar adiante execve().

Existem muitas dificuldades enraizadas no passado. E, infelizmente, esse código problemático não pode ser simplesmente substituído. O e-mail é usado há muito tempo, e sistemas e fluxos de trabalho muito complexos são criados com base nisso, por isso é muito difícil simplesmente cortar um pedaço de código e colar um novo. Apesar dos vários níveis de segregação de privilégios, um processo pai no nível raiz ainda depende muito de seus processos filhos menos privilegiados. Ele executará os comandos e argumentos que receberá.

Evitar isso parece tão simples quanto mudar para o formato de armazenamento maildir, mas requer várias alterações em muitos lugares. Correio mua padrãonão entende esse formato. Quanto a mim, a mbox sobreviveu por muito tempo, mas ainda serve a muitas pessoas, e o procedimento de atualização pode não ser completamente transparente e não funcionar automaticamente.

leitura smtpd


A leitura fora do escopo no smtpd pode ser usada para executar comandos. Relatório . Patch .

Este é realmente um problema de segurança de memória. Ao enviar algumas barras de status engraçadas, o servidor smtp remoto pode injetar comandos na fila smtpd para execução. Quando um email é enfileirado para entrega, o smtpd adiciona algumas informações de destino ao cabeçalho para saber qual comando executar (veja acima). Esse ataque é semelhante ao "contrabando" de solicitações http . Se você pode gerar uma "merda" com comandos inesperados no cabeçalho, o smtpd os executará quando você tentar entregar novamente.

Como acima, um dos problemas é que as partes mais sensíveis do smtpd estão muito próximas da superfície de ataque. Parece-me que o verdadeiro problema é que o smtpd armazena seus próprios metadados nos dados de email. Por esse motivo, torna-se possível um ataque de análise fora de sincronização. Se a resposta citada do servidor fosse armazenada completamente separada do arquivo com as instruções de entrega, a leitura fora das bordas não causaria muitos danos.

Essa vulnerabilidade me parece indicativa, porque aqui vemos o perigo de misturar dados com diferentes níveis de confiança. Este perigo nunca foi discutido. E ela definitivamente é.

achados


Obviamente, a conclusão ficou clara desde o início, mas falaremos sobre isso de qualquer maneira.

Acho que alguns desses erros ajudam a demonstrar como princípios como remover interfaces obsoletas e reduzir a complexidade do código são vitais para a segurança . Na maioria das vezes, a falha ocorreu devido ao fato de que esses princípios não foram seguidos até o fim e não porque os próprios princípios são estragados ou insustentáveis. Algumas coisas estão desaparecendo, mas não concordo que os desenvolvedores precisem de algum tipo de vigilância sobre-humana. É fácil dar conselhos inúteis, como cuidado, não cometa erros e git gud [expressão de jogador de gíria significa 'ficar bom' ', ou seja, “melhore, melhore logo” - aprox. trans.]. Mas acho que o OpenBSD tem problemas mais sérios.

Até o OpenBSD pode arriscar a segurança por praticidade utilitária. É por isso que alguns projetos desatualizados não são alterados há muito tempo. Portanto, talvez a lição seja que princípios eficazes sempre sejam seguidos, e não apenas quando for conveniente. Embora muitas vezes seja difícil fazer a escolha certa.

As três vulnerabilidades mais sérias, auth e duas smtpd, são mais ou menos adequadas para exploração somente devido a problemas de arquitetura que vão além do escopo do bug original. Eles deveriam ter permanecido apenas falhas menores que demonstram que em um sistema bem protegido não é necessário buscar o código perfeito, ou seja, erros menores são permitidos - e não afetam a segurança. Infelizmente, pode ser difícil identificar falhas de design de forma abstrata. E todas as partes do sistema parecem protegidas individualmente, mas, se combinadas, podem aparecer fraquezas.

A separação de privilégios é um componente essencial da segurança do OpenBSD e é baseada na comunicação entre processos. Faz sentido examinar de perto os problemas que podem surgir com processos danificados. Navegadores protegidos estão cada vez mais reforçando a proteção e dificultando ataques. Em particular, o smtpd deve ser protegido contra corrupção de memória nas tarefas de rede. Mas a facilidade com que ele é capaz de controlar o processo dos pais é alarmante.

Apenas um erro pode ser evitado usando uma linguagem mais segura. Sim, provavelmente, existe algum tipo de idioma do programa que, em alguns casos, pode ajudar se você o seguir com perseverança religiosa. Mas ainda não tenho certeza de que, por padrão, todo programador codifique corretamente todos os invariantes correspondentes.

Escrever um servidor de correio é um negócio complicado. Especialmente se os quadros herdados estiverem apertando você.




All Articles