Skip to content

branch/pypi-shai-hulud-vs-lorem-ipsum #302

@marcialwushu

Description

@marcialwushu

branch/pypi-shai-hulud-vs-lorem-ipsum

1. HEAD

Sabe aquele silêncio que se instala no open space por volta das 17h45 de uma sexta-feira? Não o silêncio de dever cumprido, mas aquele vácuo acústico que precede o estalo de um cabo de aço rompendo sob tensão. Eu estava lá, olhando fixamente para a tela do meu terminal, onde o cursor piscava com uma regularidade que parecia zombar da minha taquicardia. O café na minha caneca já tinha desenvolvido uma película cinzenta, uma microcamada geológica de poeira e desespero, atingindo aquela temperatura exata que não é nem bebida nem estado da matéria: apenas um fluido térmico para manter viva a ilusão de que o cérebro ainda processa alguma sintaxe válida.

O monitor ultra-wide, pago com a promessa de "aumento de produtividade", servia apenas para expor minha incompetência em alta definição. De um lado, trinta abas do Stack Overflow abertas, três delas com a mesma pergunta de 2014 cuja única resposta era um comentário de um usuário anônimo dizendo: "Deixa pra lá, já resolvi". Do outro lado, o chat do Slack, onde o bot do Jira despejava notificações automáticas como um metrônomo do apocalipse. Tarefa movida para Em Impedimento. Tarefa reaberta. Bug crítico atribuído a você.

Eu só queria fechar o notebook. Queria acreditar que o manifesto ágil é uma verdade universal e que o build de segunda-feira pertence ao homem de segunda-feira. Mas o ecossistema de software moderno, essa imensa e trêmula pilha de cartas de baralho besuntada com óleo de microserviços, tinha outros planos para o meu fim de semana. O universo do código não dorme; ele apenas compila em segundo plano, esperando o momento exato em que você relaxa os esfíncteres da atenção para estourar um estouro de pilha na memória que vai ecoar até a diretoria.

2. LOG: DO ESTADO DA ARTE AO ESTADO DE SÍTIO

Se você acha que a engenharia de software atual é sobre algoritmos elegantes e estruturas de dados refinadas, você provavelmente ainda está na faculdade ou vende cursos de "Aprenda a Programar em 6 Semanas" no Instagram. A realidade da trincheira é uma colcha de retalhos de decisões tomadas por comitês de pessoas que acham que "Cloud" é uma entidade mística que flutua no teto do datacenter. E nada resume melhor esse hospício digital do que o relatório de incidentes que caiu na minha mesa digital hoje.
Os atacantes finalmente entenderam que os desenvolvedores não leem código. Nós consumimos pacotes. Somos os fast-food do bit. Se está no PyPI, no npm ou no NuGet, nós apenas rodamos um pip install ou um npm install com a mesma fé cega de um devoto medieval engolindo água benta. Alguém lá na sede de Redmond piscou, um token de publicação foi para o ralo e, de repente, o SDK oficial do Python para o Microsoft DurableTask virou o vetor de distribuição de um framework de invasão em nuvem chamado rope.pyz. Três versões maliciosas (1.4.1, 1.4.2 e 1.4.3) foram lançadas no PyPI mais rápido do que o tempo que eu levo para decidir o que pedir no almoço.

O script malicioso tinha apenas 14 linhas de código. Catorze. Menos do que a nossa classe de configuração de CORS que ninguém mexe há três anos por medo de quebrar a autenticação. Bastava dar um import durabletask e o ecossistema entrava em parafuso. O treco foi desenhado para sugar segredos de AWS, Azure e GCP com a fome de um estagiário em dia de pizza grátis. Ele cria serviços falsos no systemd para garantir que vai sobreviver ao reboot da máquina e usa mecanismos de AWS SSM e Kubernetes para pular de um pod para o outro como se as nossas barreiras de VPC fossem cercas de palito de dente. A campanha foi batizada de TeamPCP Mini Shai-Hulud. O verme da areia do deserto de Duna agora vive no seu cluster de EKS, e ele não está atrás de especiaria; ele quer os seus tokens de IAM.

Enquanto isso, em outra sala desse mesmo prédio em chamas que chamamos de internet, o pessoal de finanças estava abrindo e-mails de phishing achando que estavam baixando planilhas de bônus trimestral. O que eles ganharam foi uma aula prática de esteganografia. Os caras estão pegando executáveis de malware, quebrando em strings Base64 e injetando dentro de imagens hospedadas em repositórios públicos como o archive.org. A imagem parece um wallpaper inócuo de gatinho ou uma paisagem corporativa genérica de pessoas sorrindo enquanto seguram tablets. Ela tem menos de um megabyte, os metadados estão limpos, o antivírus olha para ela e pensa: "Belo JPEG, assinado e carimbado".

Mas quando o usuário clica no anexo, um JavaScript Dropper acorda, puxa a imagem, extrai o código escondido entre os pixels e injeta uma DLL em DotNET direto na memória de processos legítimos do Windows (o famoso process hollowing, ou "evisceração de processo" para os íntimos). Ferramentas tradicionais de EDR ficam procurando arquivos suspeitos no disco enquanto o Remcos RAT, o Agent Tesla e o XWorm estão rodando um open bar dentro da memória RAM, coletando cada digitação, cada senha guardada no Chrome e cada piada interna do canal de fofoca da empresa.

E para fechar a trinca do bingo do apocalipse, descobrem que instaladores do Microsoft Teams foram trojanizados em uma campanha ironicamente chamada de Lorem Ipsum. Os atacantes envenenaram o SEO do Google para colocar sites falsos no topo da busca. O dev apressado, precisando entrar numa call de alinhamento atrasada, digita "Download Teams", clica no primeiro link e baixa um instalador que vem com um certificado digital ID válido, mas assinado por Deus sabe quem. Por baixo do instalador do Teams, roda um script em PowerShell que faz o sideloading de uma DLL e começa a conversar com uma infraestrutura de Comando e Controle (C2) que usa perfis falsos num site chamado letsdiskuss.com para ler instruções codificadas em imagens JFIF. É o estado da arte do desvio de tráfego. O tráfego do malware se mistura com a navegação normal da rede de tal forma que diferenciar o tráfego do hacker do tráfego de um analista de marketing assistindo a vídeos de react no YouTube vira uma tarefa de adivinhação mística.

3. REFACTOR

Olhando para esse cenário, eu percebo que a nossa indústria atingiu o ápice da sua maturidade irônica. Nós gastamos bilhões de dólares em firewalls de última geração, contratamos consultorias de segurança que cobram o preço de um rim por hora para rodar scripts de varredura automatizados que geram PDFs de 400 páginas com gráficos coloridos que ninguém lê, e no final do dia, a segurança do nosso ambiente corporativo foi de arrasto porque o pacote do Python que gerenciava as filas do nosso background job resolveu exfiltrar as chaves de root da AWS para um servidor em Frankfurt.

A engenharia de software moderna transformou-se no ato de mover lixo eletrônico de um lado para o outro. Nós não escrevemos código; nós apenas colamos encanamentos. Conectamos uma API que não controlamos a um banco de dados que não entendemos, usando uma biblioteca mantida por um sujeito chamado "DeV_mAsTeR_99" que fez o último commit em 2021 e cujo e-mail de contato é um domínio expirado. Se o DeV_mAsTeR_99 decidir deletar o repositório porque brigou com a namorada ou se a conta dele for hackeada por um grupo de script kiddies da Europa Oriental, metade dos sistemas de pagamento da América Latina entra em modo de negação de serviço.

A verdade nua e crua, destilada no álcool isopropílico das nossas frustrações noturnas, é que o modelo de dependências do ecossistema de código aberto faliu espiritualmente. Nós criamos uma pirâmide de Ponzi de abstrações. Para imprimir um "Olá Mundo" formatado na tela, o framework moderno baixa 450 megabytes de dependências que incluem três parsers de JSON diferentes, uma biblioteca para verificar se um número é ímpar e dezessete pacotes de polyfills para navegadores que deixaram de existir quando o Orkut ainda era relevante.

[Seu Código (3 linhas)]
       │
       ▼
[Framework da Moda (250 dependências)]
       │
       ▼
[Biblioteca de Utilidades Abandonada pelo Autor]
       │
       ▼
[Malware Oculto com 3 Camadas de Criptografia XOR] ◄── O Shai-Hulud mora aqui.

O caso do CrystalX RAT é uma obra de arte do masoquismo técnico. Os caras escreveram um agente de acesso remoto em Go. Para passar pelos nossos sistemas de análise comportamental, eles enfiaram o executável dentro de três camadas de compressão e criptografia: um XOR posicional, depois uma camada de ChaCha20 e finalmente uma compressão DEFLATE bruta. É o equivalente digital a pegar uma ogiva nuclear, embrulhar em plástico bolha, colocar dentro de uma caixa de Sedex, enfiar essa caixa dentro de um container de lixo e despachar com um selo que diz "Frágil - Amostras de Tecido para Pesquisa". Quando o arquivo entra na máquina da vítima, ele se descompacta na memória, desativa o Windows Defender usando APIs nativas que o próprio sistema operacional expõe para diagnóstico e limpa os logs de eventos para não deixar rastros. Ele não pede licença; ele assume a gerência do estabelecimento enquanto você está discutindo na Planning se a pontuação daquela story deve ser 3 ou 5 pontos de Fibonacci.
O que me fascina (e me assusta na mesma proporção) é que o nível de engenharia por trás desses ataques é imensamente superior ao nível de engenharia do software que eles estão atacando. O atacante estuda a fundo as entranhas da API do Windows, entende como o scheduler de tarefas gerencia os consumidores WMI e manipula o tráfego HTTP de forma que ele pareça uma conversa legítima entre o seu navegador e uma CDN. Enquanto isso, o time de desenvolvimento interno está há duas semanas tentando centralizar uma div na página de login ou discutindo se o padrão arquitetural correto para um microsserviço de envio de e-mail deveria ser limpo ou hexagonal.
Nós somos patos sentados em cima de uma montanha de dinamite, jogando confete uns nos outros. O pipeline de CI/CD, que deveria ser o nosso templo sagrado de automação e validação de qualidade, virou o cano de esgoto por onde o malware entra direto no coração da infraestrutura. O desenvolvedor assina o código com sua chave SSH, o GitHub Actions roda o build, os testes unitários (aqueles três que passam sempre porque estão com o retorno mockado) dão sinal verde, o container Docker é gerado e o deploy acontece automaticamente na AWS. Tudo limpo, automatizado e moderno. A única diferença é que agora o contêiner de produção tem um processo escondido que faz varredura de portas na rede interna e envia os dados para uma VPS na Alemanha. Mas o dashboard do Datadog está verde, então o tech lead pode dormir em paz.

4. COMPILING...

Sento na cadeira de plástico da cozinha da empresa, aquela que tem uma das pernas visivelmente mais curta e balança toda vez que você respira mais forte. O micro-ondas ao fundo emite um zumbido de transformador cansado enquanto tenta aquecer o que sobrou da lasanha de ontem de alguém. Penso nos caras que desenharam o protocolo TCP/IP nos anos 70. Eles tinham visões de cientistas compartilhando dados acadêmicos entre universidades, uma utopia de cooperação intelectual e avanço da humanidade. Se contassem para eles que cinquenta anos depois a infraestrutura global da internet estaria sendo usada para passar chaves de criptografia dentro de imagens de papel de parede hospedadas no uploaddeimagens.com.br para que um grupo criminoso possa chantagear um hospital nos Estados Unidos, eles provavelmente teriam queimado os cabos e ido pescar.

A complexidade virou a nossa religião e a nossa punição. Nós criamos sistemas tão intrincados que nenhum ser humano sozinho é capaz de entender o fluxo completo de uma requisição do momento em que o usuário clica no botão até o dado tocar o disco magnético no servidor. Passamos por camadas de balanceadores de carga, gateways de API, proxies reversos, malhas de serviço, sidecars, orquestradores de containers, drivers de banco de dados e sistemas de cache em memória. Cada uma dessas camadas é um ecossistema próprio, com suas próprias vulnerabilidades, suas próprias dependências desatualizadas e suas próprias decisões de design questionáveis tomadas em uma madrugada de 2018.

package main

import (
	"crypto/cipher"
	"os"
)

// CrystalX_POV: Quando o código do hacker é mais limpo que o seu monolito corporativo.
func EvadirDefesas(ambiente *Contexto) {
	if ambiente.DetectarSandbox() {
		// Limpa os logs de eventos antes que o analista sênior termine o segundo café.
		ExecutarComando("wevtutil.exe cl Setup")
		ExecutarComando("wevtutil.exe cl System")
		os.Exit(0)
	}
	InjetarProcessoLegitimo()
}

Nós tratamos a segurança como se fosse um checklist do Jira. "Adicionar autenticação de dois fatores no endpoint X". Pronto, tarefa movida para Done, o bug da vulnerabilidade está fechado no sistema de gerenciamento de projetos. Mas o fato de que a biblioteca que gera o token de dois fatores usa uma dependência que faz um request HTTP sem criptografia para um servidor na China para pegar o fuso horário atualizado... bem, isso não estava no escopo da sprint, então não é problema nosso. O foco é a entrega. O valor de negócio. O MVP que precisa ir para o ar antes do final do trimestre porque o bônus do gerente de produto depende disso.
O resultado é essa sensação constante de impostura técnica que todo programador com mais de cinco anos de experiência carrega no peito. Nós sabemos o quão frágil é o chão onde estamos pisando. Sabemos que o sistema que processa milhões de transações financeiras por dia é mantido de pé por três scripts em bash que rodam num cronjob de uma máquina virtual esquecida sob a mesa de alguém na TI clássica. E quando vemos relatórios sobre campanhas como a Eimeria, que usa cinco níveis de empacotamento desde arquivos RAR5 até ferramentas de RunPE escritas em AutoIt para atacar a indústria petrolífera, a gente percebe que a única razão pela qual a sociedade ainda funciona é porque os hackers também têm horário de almoço e precisam dormir.

5. EXIT STATUS 1

O terminal continua piscando. O aviso de CVE no meu terminal avisa que o pacote que estou usando tem uma vulnerabilidade crítica de execução remota de código com nota 9.6 no CVSS. Olho para o relógio: 23h42. Se eu atualizar a versão do pacote agora para corrigir a falha de segurança, o changelog diz que a nova versão removeu o suporte a métodos legados que a nossa aplicação inteira usa para se comunicar com o banco de dados de faturamento. Se eu atualizar, o sistema quebra na hora. Se eu não atualizar, um hacker na Rússia pode assumir o controle do servidor nas próximas duas semanas.

Abro o Jira. Crio uma nova tarefa: Avaliar impacto da atualização da dependência XPTO. Defino a prioridade como "Média". Jogo ela para o fundo do backlog da próxima sprint, logo abaixo de outras 142 tarefas de refatoração que estão lá desde a época em que o termo "DevOps" ainda era considerado um modismo de startup.

Fecho o notebook com aquela força suave que você usa para fechar o caixão de um conhecido distante. A luz azul da tela se apaga, deixando o quarto na penumbra confortável da ignorância temporária. Amanhã é sábado. Se a produção cair, o pager do PagerDuty vai tocar, o som de sirene de ataque aéreo vai ecoar pela casa e eu vou ter que fingir surpresa ao entrar na call de triagem de incidentes, dizendo: "Nossa, que estranho, na minha máquina funcionava perfeitamente".

No fundo, todos nós sabemos. O software não foi feito para durar; ele foi feito apenas para passar no teste de fumaça antes da apresentação para o cliente. Nós não somos engenheiros construindo pontes de concreto armado; somos crianças construindo castelos de areia na beira da praia enquanto a maré sobe, rezando para que a onda principal só chegue depois que o nosso turno terminar.

{
  "pullRequest": {
    "title": "Refactor/Existential-Dread",
    "status": "Declined",
    "reason": "Merge conflicts detected with real life. Code works on my machine, infrastructure is an illusion, security is a social construct. Do not review."
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions