Implantes invisíveis no código-fonte

Especialistas da Universidade de Cambridge descreveram uma vulnerabilidade que afetam a maioria dos compiladores atuais.  Um novo método de ataque usa um recurso legítimo de ferramentas de desenvolvimento em que o código-fonte exibe uma coisa, mas compila algo completamente diferente.  Isso acontece por meio da magia dos caracteres de controle unicode.Caracteres de formatação de direcionalidade Unicode relevantes para ataques de reordenamento.

Caracteres de formatação de direcionalidade Unicode relevantes para ataques de reordenamento. Fonte.

Na maioria das vezes, os caracteres de controle não aparecem na tela com o resto do código (embora alguns editores os exibam), mas eles modificam o texto de alguma forma.  Esta tabela contém os códigos para o Algoritmo Unicode Bidirecional (bidi), por exemplo.

Como você provavelmente sabe, alguns idiomas são escritos da esquerda para a direita (por exemplo, inglês), outros da direita para a esquerda (por exemplo, árabe).  Quando o código contém apenas um idioma, não há problema, mas quando necessário – como uma linha contém palavras em inglês e em árabe – os códigos bidi especificam a direção do texto.

No trabalho dos autores, eles usaram esses códigos para, por exemplo, mover o terminador de comentário no código Python do meio de uma linha para o final.  Eles aplicaram um código RLI para mudar apenas alguns caracteres, deixando o resto inalterado.Exemplo de código Python vulnerável usando códigos bidi

Exemplo de código Python vulnerável usando códigos bidi. Fonte.

À direita está a versão que os programadores enxergam ao verificar o código-fonte;  a esquerda mostra como o código será executado.  A maioria dos compiladores ignora os caracteres de controle.  Qualquer pessoa que verificar o código pensará que a quinta linha é um comentário inofensivo, embora, na verdade, um extrato de retorno antecipado oculto dentro dele faça com que o programa ignore a operação que debita fundos de contas bancárias.  Em outras palavras, neste exemplo, o programa bancário simulado distribuirá dinheiro, mas não reduzirá o saldo da conta.

Por que é perigoso?

À primeira vista, a vulnerabilidade parece muito simples.  Quem iria inserir caracteres invisíveis, na esperança de enganar os auditores do código-fonte?  No entanto, o problema foi considerado sério o suficiente para justificar um identificador de vulnerabilidade (CVE-2021-42574).  Antes de publicar o artigo, os autores notificaram os desenvolvedores sobre os compiladores mais comuns, dando-lhes tempo para preparar os patches.

O relatório descreve os recursos básicos de ataque.  As duas estratégias de execução são ocultar um comando dentro dos comentários e ocultar algo em uma linha que, por exemplo, aparece na tela.  É possível, em teoria, obter o efeito oposto: criar um código que se parece com um comando, mas na verdade faz parte de um comentário e não será executado.  Métodos ainda mais criativos de explorar essa fraqueza estão fadados a existir.

Por exemplo, alguém poderia usar o truque para realizar um ataque supply chain sofisticado, por meio do qual um contratado fornece a uma empresa um código que parece correto, mas não funciona como o pretendido.  Então, depois que o produto final é lançado, uma parte externa pode usar a “funcionalidade alternativa” para atacar os clientes.

Quão perigoso isso é, de fato?

Pouco depois da publicação do artigo, o programador Russ Cox criticou o ataque do tipo Source Trojan.  Ele não ficou, para dizer o mínimo, impressionado.  Seus argumentos são os seguintes:

  • Não é um novo ataque;
  • Muitos editores de código usam realce de sintaxe para mostrar o código “invisível”;
  • Patches para compiladores não são necessários – verificar cuidadosamente o código para detectar qualquer bug acidental ou malicioso é suficiente.

Na verdade, o problema com caracteres de controle Unicode já existia, por exemplo, em 2017. Além disso, um problema semelhante com homóglifos – caracteres que parecem iguais, mas têm códigos diferentes – dificilmente é novo e também pode servir para passar código estranho em verificadores manuais  .

No entanto, a análise crítica de Cox não nega a existência do problema, mas condena os relatório excessivamente dramáticos – uma caracterização apropriada de, por exemplo, o bug apocalíptico “Source Trojan” do jornalista Brian Krebs ameaça a segurança de todo o código.

O problema é real, mas felizmente a solução é bastante simples.  Todos os patches já lançados ou esperados em breve bloquearão a compilação do código contendo tais caracteres.  (Veja, por exemplo, este aviso de segurança dos desenvolvedores do compilador Rust.) Se você usar suas próprias ferramentas de construção de software, recomendamos adicionar uma verificação semelhante para caracteres ocultos, que normalmente não deveriam estar presentes no código-fonte.

O perigo de ataques supply chain

Muitas empresas terceirizam tarefas de desenvolvimento para contratados ou usam módulos de código aberto prontos para uso em seus projetos.  Isso sempre abre a porta para ataques por meio da supply chain.  Os cibercriminosos podem comprometer um contratante ou incorporar código em um projeto de código aberto e inserir código malicioso na versão final do software.  As auditorias de código normalmente revelam tais backdoors, mas se não o fizerem, os usuários finais podem obter software de fontes confiáveis, mas ainda assim perderão seus dados.

O Trojan Source é um exemplo de ataque muito mais elegante.  Em vez de tentar contrabandear megabytes de código malicioso para um produto final, os invasores podem usar essa abordagem para introduzir um código difícil de detectar em uma parte crítica do software e explorá-lo nos próximos anos.

Como se proteger

Para se proteger contra ataques do tipo Trojan Source:

  • Atualize todos os compiladores de linguagem de programação que você usa (se um patch foi lançado para eles), e
  • Escreva seus próprios scripts que detectem uma gama limitada de caracteres de controle no código-fonte.

De forma mais ampla, a luta contra possíveis ataques supply chain requer auditorias manuais de código e uma variedade de testes automatizados.  Nunca é demais olhar para o seu próprio código de uma perspectiva do cibercriminoso, tentando localizar aquele erro simples que pode quebrar todo o mecanismo de segurança.  Se você não tiver recursos internos para esse tipo de análise, considere contratar especialistas externos.