Durante a Segunda Guerra Mundial, perguntaram a Abraham Wald onde se deveria colocar blindagem nos aviões bombardeiros. O instinto dos militares era estudar os aviões que regressavam e reforçar as zonas onde os buracos de bala se concentravam. Wald sugeriu que se fizesse o contrário. Os aviões que tinha à sua frente já tinham sobrevivido a impactos nesses pontos. Era precisamente por isso que os podia estudar. Os aviões que sofreram impactos no motor ou na cabina de pilotagem nunca regressaram para serem estudados.
A engenharia de deteção tem o mesmo ponto cego, e é fácil não o perceber porque os planos que sobrevivem parecem dar uma imagem completa, se nunca nos questionarmos sobre o que não está à nossa frente. Todas as regras que definimos e todos os padrões que classificamos como «conhecidamente maliciosos» provêm de pacotes de atacantes que chegaram até nós, o que significa que foram detetados. Estamos a estudar os buracos de bala nos aviões que regressaram e a considerar isso como o quadro completo do que existe lá fora. Os criminologistas têm um nome para a versão deste fenómeno com que lidam: a «figura oculta do crime». Trata-se do espaço entre os incidentes que são detetados e os incidentes que realmente ocorrem. Todas as estatísticas criminais baseiam-se nos criminosos que foram apanhados. Quem estuda esta matéria sabe disso e tem esse fator em conta.
A implicação para a elaboração de regras é incómoda, mas importante. As regras ao nível da cadeia de caracteres só conseguem detetar atacantes que reutilizaram artefactos que já vimos. Por definição, não conseguem detetar um atacante suficientemente sofisticado para nunca ter aparecido nos nossos dados de rastreio, da mesma forma que, por mais que se analisem os aviões que regressaram, nunca se saberá onde os aviões que não regressaram foram atingidos. As regras ao nível comportamental são a nossa única hipótese real contra o desconhecido. O atacante ainda tem de extrair os dados, ainda tem de executar o código, ainda tem de «ligar para casa». O que faz está limitado. O nome que lhe dá, a forma como o ofusca e para onde o envia não estão.
Mas a identificação de comportamentos só ajuda se, para começar, soubermos como é suposto ser o comportamento normal. Wald conseguiu identificar os aviões desaparecidos porque já sabia como era um avião inteiro e sem danos. Foi isso que lhe permitiu comparar cada buraco de bala em cada avião que regressava com a forma completa esperada: asas, fuselagem, cauda, motor, cabina de pilotagem, tudo. Assim que teve esse mapa completo, o que se destacou não foi onde estavam os danos. Foi onde não estavam.
A engenharia de deteção não tem isso garantido. Se não tivermos uma visão clara e completa do que constitui o comportamento normal de um pacote, uma chamada de rede inesperada ou a criação de um processo desconhecido não são identificadas como uma falha em nada. Parecem apenas mais ruído num sistema que não está mapeado.
O verdadeiro custo de um conjunto de dados de comportamento incompleto vai além da falta de uma ou duas regras. É o facto de perdermos a capacidade de sequer reconhecer a forma do que está em falta. Um atacante que nunca aparece nas nossas deteções baseadas em cadeias de caracteres tem, ainda assim, de agir, e essa ação só é visível como anómala se tivermos definido a linha de base da qual se desvia. Sem essa linha de base, os pacotes invisíveis permanecem invisíveis por uma segunda razão, para além da primeira. Não só evitaram deixar uma assinatura, como também estão a operar num espaço que nunca nos preocupámos em descrever, pelo que nada neles parece errado, a menos que analisemos as capacidades e os comportamentos dos pacotes.
As regras de cadeias de caracteres e IOC de baixo custo representam uma utilização racional dos recursos. As estratégias utilizadas na esmagadora maioria dos pacotes maliciosos são pouco sofisticadas e reutilizadas, com a mesma carga útil copiada para toda uma onda de pacotes. Uma regra de cadeia de caracteres descartável deteta toda essa onda praticamente sem custos, deixa de ser válida assim que o atacante altera a estratégia e é reescrita com a mesma facilidade. O facto de as regras de cadeias de caracteres de baixo custo «morrerem cedo» significa que o nível de baixo custo está a cumprir exatamente a função para a qual foi concebido. Exigir uma linha de base comportamental dispendiosa para ameaças que uma regra de cadeia de caracteres criada em cinco minutos já bloqueia seria um uso ineficiente do tempo.
A resposta é um conjunto de regras que abrange toda a pirâmide. As regras de nível inferior, mais económicas, lidam com o volume elevado. As regras de nível superior, mais dispendiosas, são os únicos meios de que dispomos para alcançar os poucos atacantes sofisticados que se escondem na «figura na escuridão». Níveis diferentes, funções diferentes, e a escolha do nível a utilizar depende inteiramente do tipo de atacante que se pretende capturar. É exatamente isso que a pirâmide adaptada que se segue ilustra.
Uma pirâmide adaptada
A pirâmide da dor de David Bianco [1] oferece-nos uma forma de analisar esta questão em camadas, em vez de tratarmos a deteção como uma categoria única e unidimensional, aqui adaptada ao contexto da cadeia de abastecimento de pacotes. Podemos classificar os tipos de indicadores de acordo com o custo que implica para um atacante alterá-los, desde o trivial até ao quase impossível. Isto abrange desde ocorrências fortuitas, como valores hash, até comportamentos manifestamente deliberados, como técnicas e estratégias.
Todos os níveis, exceto o mais alto, são escolhidos pelo atacante. Um domínio, um esquema de codificação, até mesmo uma ferramenta: tudo isso é uma decisão, e as decisões são revistas no momento em que deixam de funcionar para o atacante. É isso que faz com que o nível mais alto da pirâmide seja o local ideal para criar regras duradouras, e é também, precisamente, o local mais difícil para as escrever, uma vez que as deteções ao nível técnico e estratégico precisam de uma base de referência sólida para funcionar, caso contrário não funcionam de todo.
O que levanta a questão óbvia de onde vem essa referência, porque a pirâmide não nos fornece essa informação. Classificar os indicadores de acordo com o custo que implica a sua alteração indica-nos onde se encontram as regras duradouras, mas não como identificar um desvio em primeiro lugar. A forma mais prática de construir esse panorama é deixar de procurar uma linha de base universal (que não existe) e, em vez disso, mapear o comportamento normal por tipo de pacote. Uma ferramenta de compilação, um utilitário de linha de comandos, um framework web e um pequeno utilitário de função pura são tipos diferentes de software com capacidades diferentes.
Uma ferramenta de compilação que cria processos filhos e acede ao sistema de ficheiros durante a instalação está a comportar-se como esperado, enquanto um auxiliar de formatação de cadeias de caracteres que faz o mesmo não o faz. As capacidades e ações do pacote determinam o comportamento aceitável, e as mesmas categorias de pacotes tendem a comportar-se de forma semelhante no npm, no PyPI e no NuGet, pelo que o perfil é suficientemente estável para ser reutilizado. Se conseguirmos que esse mapa fique suficientemente completo, uma ação desconhecida deixa de ser interpretada como ruído e passa a ser vista como uma lacuna na forma esperada, o que é precisamente o objetivo. Trata-se de uma grande quantidade de trabalho, e o mapa será sempre parcial, mas é esse trabalho que torna o topo da pirâmide, de todo, alcançável.
Mapeamento da forma
Cada pacote que o Aikido Security recebe é analisado estaticamente e executado numa sandbox que regista o que realmente fez. Essa parte é comum. O que mudou foi que um indicador passa agora a ter uma estrutura que vai além do simples facto de ter sido acionado. Cada um descreve o que o código correspondente é capaz de fazer e que tipo de evidência representa, pelo que um sinal que, por si só, tenha pouco significado pode ser avaliado em relação aos outros à sua volta.
Isso permite que uma regra de deteção descreva uma forma em vez de uma cadeia de caracteres. Código que é executado durante a instalação, acedendo a credenciais que não tem motivos para utilizar, enviando algo para o exterior, num pacote cuja função declarada não explica nada disso. Não há domínio numa regra como essa, nem hash, nem nome de pacote. Não há nada nela que um atacante possa explorar.
A 4 de agosto de 2026, detetámos uma versão recém-publicada do Keyv, que se apresentava como o mesmo utilitário de chave-valor popular e fiável que já foi descarregado 600 milhões de vezes do NPM. Desta vez, porém, aquando da instalação, executava um ficheiro JavaScript fortemente ofuscado, que, por sua vez, descarregava o Bun (um executor de JavaScript alternativo ao Node.js) e, por fim, executava outro ficheiro JavaScript ofuscado. Essas ferramentas e técnicas comportamentais foram suficientes para que o nosso sistema o detetasse. Se estivéssemos apenas a utilizar indicadores nomeados, teríamos deixado escapar este pacote. Mas, como procuramos o inesperado, conseguimos detetar estes pacotes que, de outra forma, cairiam nesse espaço obscuro.
O nosso sistema concluiu corretamente o seguinte, apesar de não conseguir ter uma visão completa devido à forte ofuscação: «A combinação de execução oculta durante a instalação, recuperação remota de binários, preparação da carga útil e lançamento é suficiente para um veredicto de malware com elevado grau de confiança, mesmo que o comportamento final da carga útil e qualquer objetivo de roubo de dados não tenham sido totalmente descodificados».
Atualmente, e tem sido, no mínimo, difícil descodificar e compreender malware ofuscado, especialmente do ponto de vista da análise estática. Afinal, é por isso que os atacantes o colocam aí. O que podemos provar, em vez disso, é que o comportamento dos pacotes maliciosos é suficiente para identificarmos os números ocultos.
Ainda existe uma pequena silhueta escura. O Wald também nunca viu os aviões abatidos. O que lhe permitiu perceber onde tinham sido atingidos foi conhecer a forma de um avião inteiro suficientemente bem para reparar onde o padrão se quebrava. A nossa versão dessa forma é uma referência do comportamento normal de um pacote, mantida atualizada em vez de ser baseada em suposições, e cada pacote que analisamos contribui para a sua evolução. Os atacantes que ainda não apanhámos continuam limitados pelo que o código tem de fazer para roubar algo. Cada uma dessas limitações é um buraco cuja localização já conhecemos num avião que não regressou.
Veja o que estamos a detetar no Aikido Intel. Detetamos malware em poucos minutos. Ligue o seu repositório ao Aikido para analisar continuamente as dependências da sua aplicação, à procura de pacotes maliciosos.
Referências
[1] Bianco, D. J. (2013). A Pirâmide da Dor. Detecção e Resposta Empresarial. http://detect-respond.blogspot.com/2013/03/the-pyramid-of-pain.html (revisto a 17 de janeiro de 2014, com a adição do nível dos valores hash).

