- Segundo uma análise preliminar de engenharia reversa do backdoor do xz, esse comportamento não é um simples bypass de autenticação, mas se aproxima de execução remota de código (RCE)
- O ponto central é o fluxo em que a função
RSA_public_decryptinterceptada verifica a assinatura da chave de host do servidor com uma chaveEd448fixa - Se a verificação da assinatura for aprovada, o payload pode ser passado para
system()e executado - A análise é um resultado preliminar compartilhado com autorização, e a publicação no Bluesky inclui uma publicação citada ou conteúdo incorporado
- O backdoor é resumido como tendo gate e não sendo reproduzível, portanto deve ser visto de forma diferente de ataques que simplesmente reutilizam a mesma entrada
Fluxo de execução do backdoor do xz
- A análise preliminar de engenharia reversa compartilhada com autorização se concentra na função
RSA_public_decryptinterceptada- Verifica a assinatura da chave de host do servidor com uma chave
Ed448fixa - Após a verificação, passa o payload para
system()
- Verifica a assinatura da chave de host do servidor com uma chave
Classificação e restrições
- Esse comportamento é classificado não como bypass de autenticação, mas como execução remota de código (RCE)
- O backdoor é resumido como tendo características gated/unreplayable
- A publicação original no Bluesky inclui uma publicação citada ou outro conteúdo incorporado
1 comentários
Opiniões no Hacker News
Há resultados de engenharia reversa adicional sobre este caso. Eles incluem informações de remapeamento de símbolos extraídas da prefix trie que o backdoor usava para ocultar strings, e parece que ele também tentou se esconder da própria engenharia reversa/análise
https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9...
A lista completa das strings decodificadas está aqui
https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01
Da perspectiva de alguém que não conhece bem os internos do OpenSSL, o valor N parece ser obtido do campo
ndersa_sthttps://github.com/openssl/openssl/blob/56e63f570bd5a479439b...
Esse valor é um
BIGNUM, e parece ser um tipo de comprimento variávelhttps://github.com/openssl/openssl/blob/56e63f570bd5a479439b...
O backdoor extrai esse valor de um certificado recebido do atacante remoto, tenta descriptografá-lo com ChaCha20 e, se tiver sucesso, passa o resultado para
system().system()é quase um wrapper simples que executa uma linha de shell script com as permissões do usuário sob o qual o processo atual está rodandoSe eu entendi corretamente, isso é pior do que um bypass de chave pública. Num bypass de chave pública, em tese, o atacante obteria apenas os privilégios do usuário que está tentando fazer login, e em configurações de SSH reforçadas é bem provável que o login como root estivesse bloqueado
Mas isto é execução remota de código no próprio contexto do processo
sshd, então, se osshdestiver rodando como root, o payload também pode ser executado como root. Como execução remota de código amplamente disseminada, é realisticamente algo próximo do pior cenário possívelFico me perguntando qual seria a probabilidade de esse backdoor ser descoberto depois se ele não tivesse sido encontrado por causa do problema de desempenho. Entendi o problema de desempenho como um erro no código/defeito corrigível, e também é importante saber se havia ferramentas capazes de detectá-lo
Perguntas assim são muito relevantes para entender se esse é o primeiro backdoor desse tipo, ou apenas o primeiro que veio à tona
Um único pequeno erro pode derrubar tudo, e às vezes uma única frase já inicia uma reação em cadeia que revela um plano cuidadosamente elaborado
Investigações criminais funcionam assim todos os dias. O trabalho policial tem restrições de recursos, mas software é examinado diariamente por pessoas que analisam como hobby, por profissionais que continuam analisando quase como hobby e por profissionais que analisam por trabalho
No fim, é bem provável que isso fosse descoberto algum dia
O ataque ao XZ foi muito bem executado, quase uma obra-prima. Eu não me surpreenderia se uma agência estatal estivesse envolvida. Mas, ao mesmo tempo, ele teve uma sorte enorme. Se qualquer uma das coisas que agora aparecem como problemas tivesse sido descoberta, não só eu, mas muitos colegas teriam iniciado uma longa investigação
Uma conclusão possível é que, se xz/liblzma não fosse open source, seria impossível encontrar esse tipo de problema. Claro que o fato de ser open source também ajudou a tornar isso possível em primeiro lugar, mas basta imaginar se isso estivesse dentro do Windows ou do MacOS
Mas, se não fosse usado, não cumpriria seu objetivo. Quanto mais fosse usado, maior também seria a probabilidade de ser detectado depois. É comparável ao SolarWinds
Pessoalmente, a chamada a
system()foi meio descuidada, e acho que um scanner de funcionalidades em binários talvez pudesse ter encontrado esse caminhosshdacontece em uma etapa aceitável, o momento de linkedição, e, se esta análise estiver correta, também não era um backdoor de chave mestra, então não há rastros típicos de auditoria de login. Além disso, o fato de osshdiniciar outros processos pode ser algo naturalmente permitidoUma política SELinux muito rígida talvez conseguisse detectar o
sshdexecutando algo que não fosse um shell, mas um nível de hardening assim deve ser muito raroA questão de descobrir isso fora do alvo, de certo modo, já foi testada. Várias pessoas examinaram o payload com
valgrinde similares, mas não viram. Ele também é bem protegido para não ser descoberto em ambientes de depuração, porque a infraestrutura exposta abaixo do payload não é compatível com ferramentas como ASanMesmo que seja linkado, o código roda muito antes de
main(), então, mesmo vasculhando perto deliblzmacom um debugger, normalmente não se observaria a execuçãoCom
strace, seria possível ver todas as chamadas de sistema e a atividade do linker depois que o processo fosse criado. Mas, pelo que se entende até agora, o payload não faz chamadas de sistema nessa etapa para decidir se deve ser ativado; parece olhar coisas comoargveenviron[0] https://en.wikipedia.org/wiki/PWB/UNIX
[1] https://news.ycombinator.com/item?id=38020792
Parece haver uma string codificada dentro do payload binário
https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01...
Essa string funciona como um kill switch
https://piaille.fr/@zeno/112185928685603910
Se for mesmo isso, uma mitigação poderia ser a seguinte
-a. Caso contrário, você pode apagar o arquivo de ambiente. E, em geral, o correto é atualizar para uma versão sem o código malicioso e reiniciarAlguém consegue explicar brevemente o que exatamente o backdoor faz? Isso já se sabe? O backdoor em si não parece ser o payload; fico em dúvida se é necessário um arquivo compactado malicioso ou se ele faz hook no processo
sshdpara escutar pacotes maliciosos de um atacante remotoO texto original soa como se o atacante pudesse enviar um payload malicioso na etapa pré-autenticação de uma sessão SSH, mas também não entendo por que dizem que talvez um exploit nunca apareça. Se dá para fazer engenharia reversa do código, não daria para escrever uma prova de conceito?
Afinal, como o atacante controla uma máquina com esse backdoor?
A situação aqui é parecida. O xz tenta descriptografar certos dados antes de fazer qualquer coisa suspeita. Como é um esquema assimétrico, é possível verificar a descriptografia sem fornecer a chave secreta de criptografia, porque existe a chave pública correspondente
Como encontrar a chave secreta é praticamente impossível, e como uma falha ao descriptografar o payload não produz nenhum comportamento visivelmente diferente, o código de exploit talvez nunca seja divulgado. A única forma de criar o código de exploit seria se a chave secreta fosse descoberta de algum modo; na prática, só se o desenvolvedor do backdoor a vazasse
sshdé iniciado e carrega alibsystemd, que por sua vez carrega a biblioteca XZ contendo o código hackeadoA biblioteca XZ injeta suas próprias versões das funções da OpenSSL que verificam assinaturas RSA
Quando alguém faz login via SSH e apresenta um certificado SSH assinado para autenticação, essas funções adulteradas são chamadas
O certificado pode conter, no fluxo normal de login, asserções como nome de usuário ou função, e essas informações são usadas para decidir se o certificado é válido para o login de determinado usuário. Mas, se a função adulterada detectar um certificado assinado por uma chave específica do atacante, ela extrai alguns subcampos do certificado e os executa como comando do sistema. O contexto de execução é o
sshd, ou seja, o usuário rootInfelizmente, não conhecemos a chave de assinatura do atacante; conhecemos apenas a chave pública que o código hackeado usa para verificação. Basicamente, o atacante consegue executar comandos arbitrários como root no sistema infectado, e os vestígios, no máximo, seriam algo como tentativas de login malsucedidas. Em um sistema exposto à internet, tentativas assim já são comuns de qualquer forma
O ponto central é a necessidade da assinatura da chave do atacante. A menos que essa chave vaze ou que o algoritmo RSA seja quebrado, é impossível que outros pesquisadores ou terceiros explorem esse backdoor. Se o RSA for quebrado, teremos problemas muito maiores que este
No momento, só o atacante consegue executar o exploit, então também é impossível fazer varredura. Exceto por efeitos secundários como degradação de desempenho, é difícil de detectar — e foi justamente assim que ele acabou sendo descoberto
É difícil entender como um pacote importante, usado diariamente por tantos servidores Linux, pode deixar de ser mantido pelo autor original por falta de financiamento. Algo precisa mudar no open source
Uma solução poderia ser uma licença que obrigasse empresas ou negócios acima de certo porte a pagar custos de manutenção
Assim, o fornecedor passa a ter incentivo para manter o open source seguro: pagando mantenedores, contratando auditorias de código ou empregando pessoas em tempo integral para contribuir
Ao entrar agora no repositório do xz, ele está desativado por violação dos Termos de Serviço do GitHub. A desativação em si é compreensível, mas eu gostaria que o GitHub mantivesse o código e o histórico, exibisse um banner e bloqueasse apenas os recursos que pudessem ser abusados
Assim pesquisadores e outras pessoas poderiam aprender sobre o exploit. Em uma situação mais trivial, se uma biblioteca estivesse hospedando código malicioso e o repositório fosse removido, talvez as pessoas simplesmente tratassem como algo sem importância
Se você tem interesse no código-fonte, ele é fácil de encontrar. Esse código e o repositório Git estão ligados a vários repositórios Git no mundo todo, e o código-fonte também foi empacotado várias vezes nos releases
Como mantenedor de fato de um jogo open source pouco conhecido, vi desenvolvedores irem e virem. Simplesmente faço merge de todas as contribuições valiosas
Alguns colaboradores se aprofundam bastante em funcionalidades em meio a uma mistura de C e C++ com vários estilos de codificação. Nem sempre entendo todos os detalhes de implementação, mas, no fundo, penso que se alguém inserir uma backdoor realmente ruim, o projeto estará acabado
Felizmente, o jogo é obscuro demais e a superfície de ataque é muito pequena. Ainda assim, isso me fez parar de sentir a tentação de assinar binários do Windows por boa vontade
Essa backdoor no xz é um pesadelo enorme, e sinto muito pelos desenvolvedores originais e por todos que acabaram envolvidos nisso
Ao caminhar por uma trilha na floresta, um carro que passa pode simplesmente atropelar você. O motorista provavelmente não será pego, não há como impedir, e não há polícia por perto. Esse cenário, muito mais assustador do que uma backdoor de software, é na verdade o risco mínimo que precisamos aceitar para viver fazendo qualquer coisa. E coisas assim de fato acontecem
Mas, no fim, a grande maioria das pessoas não tenta ativamente ferir os outros. Tudo que os humanos fazem sempre se baseou nessa suposição, e ainda se baseia
A ilusão de que revisar código com um pouco mais de rigor, usar mais linters, CI e correspondência de padrões, popularizar mais a assinatura de código e verificar a identidade das pessoas vai impedir esse tipo de coisa é, ela sim, o verdadeiro problema. É um sintoma do delírio ao estilo Silicon Valley de que o mundo pode e deve ser gerenciado e controlado em todos os níveis de detalhe. Essa “cura” pode ser muito pior do que qualquer doença que ela tente evitar
[1]: http://hintjens.com/blog:106
Entendo a vantagem de criar uma comunidade em que contribuidores participem do projeto com prazer. Mas me pareceu uma forma de fazer o projeto crescer sem uma visão ou direção clara e, no fim, colocar sobre os mantenedores um fardo excessivo para enquadrar as contribuições de outras pessoas em um padrão comum
A revisão real do código é empurrada para algum momento desconhecido no futuro, sem saber se a revisão será rigorosa nem quem assumirá a responsabilidade por fazê-la ou por corrigir problemas. No fim, soa como uma receita para o caos, na qual não se tem controle sobre o que é distribuído aos usuários
Há também o problema da distribuição de código malicioso. Esse tema aparece nos comentários daquele post do blog, e Pieter descreve exatamente o mesmo cenário do caso xz
“Suponha que Mallory seja paciente, enganosa e aja por tempo suficiente como uma contribuidora válida para obter controle do projeto, e depois comece lentamente a inserir uma backdoor. Nesse caso, uma revisão cuidadosa de código também não ajuda. Mallory só precisa conquistar confiança suficiente para se tornar mantenedora, e isso não é uma questão de possibilidade, mas de método.”
Ele concluiu que “a melhor defesa é o tamanho e a diversidade da comunidade”
Mas acredito que uma revisão cuidadosa de código pode, de fato, reduzir a probabilidade de algo assim acontecer. Se todas as contribuições, sejam de contribuidores confiáveis ou externos, forem revisadas minuciosamente, aumenta a chance de detectar mais cedo comportamentos estranhos ou commits que dizem “fazer A”, mas na prática fazem B
Também é discutível se o Optimistic Merging leva a uma comunidade maior e mais diversa. Há muitos projetos com comunidades ativas mesmo tendo diretrizes de contribuição rigorosas. E isso não responde quando nem como um patch malicioso seria detectado
O problema do xz não foi uma comunidade pequena, mas o fato de não haver comunidade. Um único agente malicioso obteve controle do projeto, quase sem supervisão de mais ninguém. As diretrizes de contribuição não eram um fator no tamanho da comunidade, e isso teria acontecido usando ou não Optimistic Merging
[2]: http://hintjens.com/blog:106/comments/show#post-2409627
brew install caskou extensões do vi/emacs/vscodeRust pode ser considerada a linguagem/comunidade de programação mais segura por padrão, com um design voltado à segurança a ponto de praticamente impedir brincadeiras com ponteiros. Ainda assim, o caminho de instalação mais comum e recomendado é este, e eu também sou um completo hipócrita e faço isso com frequência
https://www.rust-lang.org/tools/install
Isso é apenas um exemplo. O hábito de abrir por conta própria a execução remota de código no estilo “dê
curlnisso e faça pipe parash”, enquanto ao mesmo tempo se discute o blocounsafede alguém, virou memória muscular para gente demaisÉ lamentável que isso tenha acontecido, mas não é surpreendente. Espero que surjam ferramentas melhores contra esses agentes maliciosos, e que sejam open source
Há perguntas que esse backdoor levanta. Que outros backdoors a mesma equipe, ou uma equipe parecida, plantou? Quantas equipes desse tipo estão em atividade? Quantas dependências são vulneráveis a esses ataques de infiltração? Qual é a superfície de ataque, no nosso setor, para esse tipo de operação clandestina direcionada?
Criar um grafo dos principais serviços de rede, como
apache httpd,postgres,mysql,nginx,openssh,dropbear ssh,haproxy,varnish,caddy,squidepostfix, de todas as suas dependências e de todos os grafos de committers dessas dependências pode ser o primeiro passo para descobrir onde há mais valor e menos vigilânciaNão há como este ser o primeiro caso em que alguém tentou algo assim. É apenas o primeiro caso que veio à tona por ter falhado. Sabemos de backdoors tentados e descobertos no kernel Linux, mas este é um ataque remoto e tem uma natureza completamente diferente
Por que não distribuir algo aparentemente inofensivo que, mesmo se detectado, pudesse parecer um bug, e em vez disso implementar um backdoor totalmente funcional e ainda tentar ocultar o modo de distribuição?
Isso deve ter sido uma decisão consciente. O motivo pode dar uma pista sobre qual era o objetivo
Isso parece significar que, para escanear remotamente o exploit, precisaríamos da chave privada do atacante, que não temos. A única outra opção é executar um script de detecção localmente
A menos que se descubra que esse problema se espalhou amplamente em sistemas reais, essa abordagem parece pior do que quando “especialistas” parecidos exigiam trocar senhas todo ano, reduzindo a segurança real e apenas fazendo a segurança parecer melhor no papel
A verificação de assinatura do backdoor deve levar cerca de 100 µs, então uma chave cuja impressão digital corresponda deveria levar esse tanto a mais para ser processada do que uma que não corresponda. Essa diferença de tempo é realisticamente detectável ao menos em uma LAN e talvez também pela internet se o scanner estiver rodando em um local próximo ao alvo
Sistemas que bloqueiam o IP do cliente após repetidas falhas de autenticação dificultariam o escaneamento
(https://bench.cr.yp.to/results-sign.html mostra a verificação Ed448 em cerca de 400 mil ciclos, o que em 4 GHz corresponde a 100 µs)
sshdcom o backdoor emite algum desafio e o atacante precisa assiná-lo?Talvez seja uma opinião impopular, mas não dá para não admirar a operação inteira. Claro que eu a condeno, mas ainda assim dá para admirar. Da concepção à execução, foi realmente como uma obra de arte, e ter sido pega tão cedo foi uma sorte enorme
Da próxima vez, é provável que os atacantes criem um payload que não provoque picos estranhos de latência em tarefas em que uma pessoa está esperando
Isso me lembra, de algum jeito, o caso em que Kim Dotcom descobriu que era alvo de escuta ilegal. Foi porque o ping dele subiu muito de repente no MW3. Ao investigar, descobriu que só os pacotes dele estavam sendo roteados fisicamente por um escritório do GCSB muito distante. O GCSB não tem autoridade para grampear residentes permanentes da Nova Zelândia. No fim, ele recebeu um pedido de desculpas pessoal do primeiro-ministro da Nova Zelândia
Acho que a parte mais engenhosa foi a escolha do projeto a infiltrar. Ler, depois do ocorrido, a discussão do pull request de IFUNC do “Hans” é doloroso, mas mostra muito bem por que esse projeto foi escolhido
Fico curioso para saber quantas pessoas havia por trás de “Jia” e “Hans”, e como elas analisaram e formularam a estratégia de comunicação e de contribuição de código. Alguns aspectos, como as personas terciárias que se faziam passar por pressão na mailing list, parecem ter sido montados de forma um tanto desleixada
Por isso ainda é possível que tenha sido uma equipe pequena e sofisticada, ou até mesmo uma pessoa sozinha. Se fosse um ator estatal, eu imaginaria que haveria pessoas criando e mantendo personas falsas em tempo integral para uma operação dessas
Teria sido um problema se alguém pensasse: “É estranho esses três usuários estarem pressionando de um jeito meio rude. Quem são eles? As contas foram todas criadas na mesma época. Suspeito. Por que alguém usaria contas falsas para forçar isso com tanta insistência? Preciso investigar”. Comparado ao esforço total investido, essa parte foi descuidada, mal planejada ou mal financiada
Acrescentando uma hipótese dramática, talvez o atacante tenha se assustado com a bomba nuclear informacional que estava prestes a detonar e a tenha sabotado de propósito
Dá para detestar o resultado final e, ao mesmo tempo, reconhecer a complexidade do ataque