Comment nous nous sommes défendus contre deux attaques contre la cryptographie sous-jacente au tBTC – rapidement, silencieusement et sans drame.

TL;DR :

Récemment, deux attaques contre le protocole GG18 et de nombreuses implémentations ont été rendues publiques : BitForge, par l'équipe Fireblocks, et TSShock, par Verichains.

tBTC reste sûr.

Nous sommes heureux d'annoncer que grâce à une divulgation responsable de Fireblocks et au codage défensif de notre équipe de développement, les deux vulnérabilités ont été atténuées dans tBTC depuis juin, des mois avant d'autres projets dans l'espace et bien avant la divulgation publique. Dans le cadre de cette expérience, nous avons décidé d'expédier et de maintenir une alternative au système Binance.

tss-lib

.

Divulgation BitForge

Le 10 mai 2023, nous avons reçu un rapport de vulnérabilité de seconde main d'un sympathique chercheur en sécurité. Le rapport de vulnérabilité proviendrait de l'équipe Fireblocks, et bien que nous les ayons contactés pour confirmation, son authenticité a été vérifiée par Dan Boneh chez A16z.

Rapport Fireblocks 2023 05 10 fireblocks-report-2023-05-10.pdf 154 Ko cercle de téléchargement Comprendre le rapport

Pour comprendre comment BitForge pourrait impacter le tBTC, il est utile de comprendre le tBTC.

tBTC est un pont Bitcoin décentralisé qui s'appuie sur des opérateurs clients choisis au hasard pour gérer le Bitcoin. Pour que les opérateurs puissent y parvenir, ils doivent être capables de créer des portefeuilles Bitcoin partagés et de signer des transactions Bitcoin. Pour produire une signature, ce groupe doit avoir un consensus de 51 sur 100.

Les mathématiques liées à la création de signatures sans qu’aucun membre n’apprenne à signer au nom de l’ensemble du groupe sont complexes. Le schéma utilisé aujourd'hui en production dans tBTC est décrit dans GG18, et l'implémentation utilisée par le principal client est celle de Binance.

tss-lib

.

Entre autres éléments de base, GG18 (et

tss-lib

) utilise le cryptosystème Paillier pour ses propriétés homomorphes[1]. Lors de la mise en place du cryptosystème Paillier, chaque participant génère deux grands nombres premiers (p, q) comme clé privée, puis N = p • q comme clé publique.[2]

La vulnérabilité BitForge tourne autour de ce qui se passe lorsqu'un signataire malveillant est capable d'utiliser un module

N = small_prime_1 • small_prime_2 • ... • small_prime_16 • q

, et aucun des autres participants ne vérifie.

Dans tBTC, un exploit réussi de la vulnérabilité BitForge pourrait exfiltrer du matériel clé, entraînant une perte de fonds. Pour ce faire, une attaque nécessiterait

  • Une attaque de l’homme du milieu réussie contre la communication des signataires – peu probable, compte tenu de notre couche réseau renforcée.

  • Un T jalonneur malveillant existant connaissant la vulnérabilité et suffisamment de T jalonné pour être choisi pour un portefeuille.

Atténuation immédiate

Maintenant que nous avons compris la vulnérabilité, nous pouvions prendre immédiatement deux mesures pour atténuer la menace.

Tout d’abord, nous avons interrompu les battements de cœur du portefeuille. tBTC s'appuie sur les signatures périodiques des portefeuilles (« battements de cœur ») pour prouver la vivacité du signataire. Étant donné que BitForge cible le protocole de signature et que tBTC ne prenait pas encore en charge les rachats en mai, la désactivation des battements de cœur signifiait que la vulnérabilité ne pouvait pas être exploitée davantage, même par un signataire malveillant déjà attribué à un portefeuille BTC.

Deuxièmement, nous avons travaillé avec la gouvernance pour désactiver la création de nouveaux portefeuilles. Étant donné que tBTC v2 a été lancé avec une restriction de participation bêta, nous savions que le risque d'un signataire malveillant était faible. Néanmoins, cette décision garantissait en outre qu'un nouveau signataire connaissant la vulnérabilité ne pouvait pas se glisser dans un nouveau portefeuille.

Ces deux mesures ont été exécutées le 11 mai 2023. Sans signatures ni DKG, aucun chemin de code dans

tss-lib

pourrait être déclenché sur le réseau principal. À ce stade, moins de 24 heures après la réponse à l'incident, nous disposions de ce que tout ingénieur en sécurité pouvait espérer dans une atténuation active des vulnérabilités : du temps.

Nous avons envisagé deux plans d'attaque.

"Le grand"

Nous avons appelé le premier plan d'atténuation à l'étude « The Big One ». Comme son nom l’indique, il prévoyait des mesures drastiques.

Premièrement, nous devrions mettre en œuvre une alternative à

tss-lib

et GG18 qui ne souffraient pas de la vulnérabilité BitForge. Nous avions déjà prévu de fournir la prise en charge des signatures Schnorr en tant qu'amélioration des performances.

Si vous n'êtes pas familier avec les signatures Schnorr, considérez-les comme une mise à niveau majeure du système de signature ECDSA largement utilisé aujourd'hui sur Bitcoin et Ethereum. Les signatures Schnorr simplifient considérablement les constructions de seuils sans les hypothèses supplémentaires des signatures BLS... mais plus important encore, elles sont aujourd'hui prises en charge sur Bitcoin !

Cet ajout signifierait une mise à jour majeure de la version du

garder le noyau

Client P2P alimentant tBTC – une chose difficile à faire tranquillement. Heureusement, il figurait déjà sur notre feuille de route, donc son expédition ne ferait pas naître de soupçons sur une vulnérabilité non divulguée.

La dernière étape de ce plan nécessiterait la rotation de tous les portefeuilles BTC du système : faisable, mais lent, nécessitant un effort de coordination à l'échelle de la communauté.

"Réparer le Paillier"

Le deuxième plan d'atténuation, appelé « Corriger le Paillier », tenterait de résoudre le problème sur place.

Premièrement, nous fournirions un correctif côté client pour empêcher les petits nombres premiers générés accidentellement. Même si cela ne protégerait pas contre un client construit de manière malveillante, cela éviterait

Ensuite, nous expédierions une atténuation complète contre BitForge, en utilisant les preuves Paillier ZK « sans petit facteur » trouvées dans le protocole ECDSA de seuil CGGMP21.

Après discussion, il est devenu clair que ce plan était le choix le plus conservateur ; et il s’est avéré que nous avions déjà mis en œuvre la plupart des preuves requises lors d’un effort de recherche antérieur.

Nous avons commencé à implémenter les preuves ZK pour une version client privé.

Prouver l’honnêteté de l’opérateur

Lors de la mise en œuvre du correctif complet, nous avons également entrepris de confirmer nos conclusions jusqu'à présent.

Nous savions qu’aucun nouvel opérateur ne pourrait attaquer le tBTC… mais qu’en est-il des opérateurs existants ? Si les détails de la vulnérabilité BitForge étaient divulgués, les opérateurs pourraient-ils mettre leurs fonds en danger ?

Au moment de la divulgation, tBTC disposait de 4 portefeuilles, chacun comptant 100 membres. Si nous pouvions prouver qu'aucun petit facteur n'a été utilisé lors de la génération de ces portefeuilles, nous pourrions éviter tout doute raisonnable la rotation des portefeuilles et avoir d'autant plus confiance dans la sécurité du système.

Chaque membre de chaque portefeuille possède un module de Paillier. Nous avons utilisé la force brute.

La divulgation originale n’était pas précise sur le fonctionnement de l’attaque, mais écrivait :

L'origine de la vulnérabilité est que les parties ne vérifient pas si le module de Paillier, noté N, est à facteurs petits (un nombre premier de taille inférieure à 2 100 est considéré comme petit) ou s'il est bipremier (il est donc le produit d'exactement deux nombres premiers)

La version la plus difficile à détecter de l'attaque relative au tBTC est celle où un attaquant utilise un petit facteur de l'ordre de 2 100 et un autre de l'ordre de 21 948. Plus le module a de facteurs, plus il est facile de le factoriser. Plus un facteur est petit, plus il est facile de le factoriser. Nous nous préparions au pire et espérions le meilleur !

Tout d’abord, nous avons créé un ensemble de clés malveillantes. La bibliothèque python libnum est bonne pour cela :

importer des bits libnum = 100 total_bits = 2048 q = libnum.generate_prime(bits) p = libnum.generate_prime(total_bits - bits) N = p * q print(p, q, N)

Cela crée des modules de 2 048 bits générés aléatoirement avec un petit facteur (~2^100) et un grand facteur (~2^1948).

Ensuite, nous avons évalué le temps nécessaire à leur factorisation à l'aide de sympy.ntheory.factorint :

importer l'heure depuis sympy.ntheory import factorint start = time.time() facteurs = factorint(N) end = time.time() print(factors, str(end - start))

Tous les tests pris en compte ! Voici les statistiques :

N. 64 min 4016,88 q1 35906,3 médiane 65896,9 q3 123775 max 453262 moyenne 105729 stddev 107148 stderr 13393,6

Le 12 mai 2023, deux jours après le début de notre atténuation active, nous avons confirmé qu'il n'y avait pas de nombres premiers inférieurs à 50 bits sur nos ordinateurs portables... et nous nous sommes préparés à un processus de factorisation plus long dans le cloud.

Ensuite, nous avons créé 8 x 48 cœurs Digital Ocean Droplets optimisés pour le processeur et 1 x 16 cœurs, pour un total de 400 cœurs.

factorielle

exécute un seul thread (et est la plus rapide des bibliothèques de factorisation que nous avons trouvées) ; chaque boîte a reçu un numéro à prendre en compte par noyau.

import sys depuis sympy.ntheory import factorint import time import json N = int(sys.argv[1], 16) start = time.time() facteurs = factorint(N) end = time.time() fichier = open(f '{sys.argv[2]}.txt', "w") file.writelines([json.dumps(factors), "\n", str(end - start)]) file.close()

Nous avons réparti les modules entre les machines puis avons commencé l'affacturage.

python3 factor.py <moduli1> 1 & désavouer python3 factor.py <moduli2> 2 & désavouer ... python3 factor.py <moduli48> 48 & désavouer

Nous avons vérifié que nous avions 48 cœurs sur chaque machine fonctionnant à 100 % d'utilisation, puis vérifié périodiquement pour nous assurer que rien ne plantait.

Nous avons fait fonctionner les machines du 2023-05-15T16:01Z au 2023-05-22T19:21Z, soit 7 jours, 3 heures, 20 minutes ou 616 800 secondes au total. Aucun des 400 fils de discussion n'a trouvé de facteurs.

C'est environ 4,8 écarts-types au-dessus de la moyenne et 36 % plus long que la tentative d'affacturage la plus longue que nous ayons vue, ce qui nous donne l'assurance que nous avons tenté d'affacturer suffisamment longtemps.

Pour qu’un petit facteur soit présent, l’attaquant doit avoir :

  • J'ai découvert l'attaque bien avant les chercheurs en sécurité.

  • Modification du client avant la création du portefeuille. Le portefeuille le plus récent a été enregistré le 2023-04-19.

  • D'une manière ou d'une autre, ils ont évité que leur petit facteur soit détecté par l'algorithme ci-dessus.

Avec tout cela ensemble, nous savions qu’aucune des clés n’était menacée par cette attaque potentielle.

Un patch complet

L'article CGGMP21 utilise également le cryptosystème Paillier. La différence est que lors de la génération des clés, le protocole fait prouver à chaque participant sans aucune connaissance que

  • Leur module ne contient pas de petits facteurs. p66.

  • Leur module est un module de Paillier-Blum. p36.

  • Leurs paramètres de Ring-Pedersen sont bien formés. p37.

Le 16 mai 2023, nous disposions d'un prototype de toutes les épreuves et avons commencé l'examen interne.

Le 5 juin, nous avons créé un fork privé, puis construit et expédié discrètement le binaire client en utilisant une version privée et personnalisée de

tss-lib

pour effectuer les preuves ci-dessus.

Parce que nous prévoyions déjà une version majeure du client pour activer une nouvelle fonctionnalité, radicale, nous avons pu discrètement inclure le correctif – sans divulguer la vulnérabilité ni avertir les pirates potentiels.

Le 6 juin, Trail of Bits a commencé à vérifier notre correctif et le 7 juin, nous avons corrigé tous les résultats. [3]

Thèse tss-lib Rapport récapitulatif de la remédiation BitForge Thèse tss-lib Rapport récapitulatif de la remédiation BitForge.pdf 772 Ko download-circle Divulgation TSShock

Le 14 juillet, nous avons reçu un autre rapport faisant état d'un problème critique, cette fois de la part de l'équipe Verichains via ImmuneFi. Le plus inquiétant est que l'équipe a inclus une preuve de concept qui, selon elle, démontrait une exfiltration clé du

garder le noyau

client.

Cependant, en creusant, nous avons réalisé que le PoC de l'équipe Verichains était basé sur une ancienne version du client,

v2.0.0-m3

– pas la version bêta de la version client privée que les joueurs bêta utilisaient.

Le 18 juillet, nous avons confirmé que le client corrigé en privé par l'atténuation BitForge avait également sécurisé tBTC contre la nouvelle vulnérabilité, baptisée TSShock, et que l'attaque n'était pas possible sur le réseau principal.

Comment? En travaillant sur l'atténuation de BitForge, nous avons découvert le problème de collision de hachage derrière TSShock qui avait déjà été résolu publiquement et l'avons intégré au client corrigé en privé. Nous avons apprécié la divulgation de Verichains et sommes satisfaits du résultat.

Points à retenir

La divulgation responsable est difficile

Comme toujours, l’un des aspects les plus difficiles de la divulgation responsable consiste souvent à trouver la bonne personne à qui parler.

Au cours des derniers jours, j'ai travaillé avec un groupe de whitehats, d'auditeurs et d'autres responsables de la sécurité pour tenter de résoudre l'aspect le plus difficile de la divulgation responsable : trouver la bonne personne à qui parler. pic.twitter.com/pPjt7D51ZE

– @samczsun.com (@samczsun) 7 août 2023

Ici, nous avons eu la chance d'avoir reçu la divulgation de BitForge si tôt : plusieurs intermédiaires étaient impliqués avant que nous soyons en contact avec l'équipe Fireblocks.

On ne sait pas comment nous aurions pu faire mieux ici... les référentiels concernés ont un processus de divulgation publié, nous avons un programme de primes ImmuneFi, nous répondons rapidement aux e-mails via

sécurité@threshold.network

, et nous suivons la norme security.txt.

D’un autre côté, nous avons eu quelques problèmes pour vérifier que le problème rencontré par ThorChain le 16 août était bien TSShock – et non une nouvelle vulnérabilité. Je n'ai pas pu l'obtenir, malgré mes contacts sur Twitter, via des contacts Telegram partagés, etc.

Nous devons trouver un meilleur moyen de coordination au sein de l'industrie, en particulier entre les projets comportant des dépendances partagées critiques telles que

tss-lib

.

Quand il y a de la fumée il y a du feu.

Le Binance

tss-lib

a eu un certain nombre de problèmes au fil des années. Il n'est pas mis à jour fréquemment, la couverture des tests n'est pas excellente et la plupart des améliorations du code au cours des dernières années ont été apportées en réponse à des divulgations.

Nous le savons, car nous sommes nous-mêmes parmi les contributeurs les plus fréquents.

Après BitForge et TSShock, on n'a plus confiance dans l'amont

tss-lib

référentiel, y compris l’atténuation appropriée de ces problèmes.

Au lieu de cela, nous recommandons à tous

tss-lib

les utilisateurs devraient envisager d'utiliser notre fork, qui est désormais open source.

Travail futur

En plus des problèmes avec

tss-lib

... la famille GG18 de protocoles à seuil a également présenté un certain nombre de vulnérabilités au fil des ans. Et même si toute cryptographie doit résister à l’épreuve du temps, là où il y a de la fumée, il y a souvent du feu – et si nous pouvons éviter les risques, nous devrions le faire.

De nombreux projets nécessitent un seuil ECDSA, et pour ceux-ci, nous recommandons la mise à niveau vers CGGMP21.

Heureusement, nous avons une alternative plus solide. Depuis le 14 novembre 2021, Bitcoin a activé un nouveau système de signature : Schnorr. Depuis avril, notre plan consiste à migrer tBTC vers les signatures Schnorr, en utilisant ROAST/FROST et GJKR (RFC 10) pour éviter les complexités liées à la mise en œuvre de seuils ECDSA. L'équipe a accepté de recommander que le programme bêta-staker soit laissé en place jusqu'à ce que la migration vers Schnorr ait lieu.

Attendez-vous à en savoir plus sur cet effort plus tard cette année !

Remerciements

La sécurité des logiciels est un gros travail, et l'atténuation de ces vulnérabilités reposait sur un certain nombre de personnes.

Nous tenons à remercier...

  • Ari et l'équipe de Fireblocks pour leurs découvertes.

  • MacLane Wilkison, Tux et Dan Boneh pour leur aide dans la vérification de la divulgation.

  • Promethea Rashke pour son travail sur le portage des preuves de CGGMP21 vers tss-lib, Beau Rancourt pour son travail de factorisation des modules Paillier existants, et Jakub Nowakowski, Piotr Dyraga et Lukasz Zimnoc pour leur travail de coordination de notre réponse et de révision de tout le code.

  • Tjaden Hess et Trail of Bits pour leur aide et leurs commentaires vérifiant nos mesures d'atténuation.

  • Les Threshold DAO pour leur incroyable réactivité.

Chronologie

Pour ceux que cela intéresse, voici une chronologie plus détaillée. Notez que toutes les heures sont UTC.

  • 10/05/2023 21h19 : Recevez la divulgation originale de la vulnérabilité.

  • 2023-05-10 21:53 : Répartir le travail : Kuba récupère les modules de Paillier existants afin que nous puissions vérifier et commencer à les factoriser. Promethea commence à patcher tss-lib. Beau commence à écrire du code de factorisation et des benchmarks. Piotr prépare une transaction pour la gouvernance tBTC afin de suspendre la création de nouveaux portefeuilles.

  • 2023-05-11 00h06 : Kuba extrait et partage les 400 modules existants.

  • 2023-05-11 13h08 : Piotr confie la transaction visant à suspendre la création d'un nouveau portefeuille à la gouvernance.

  • 11/05/2023 19h45 : Promethea implémente le brouillon des preuves nécessaires dans un fork privé de tss-lib.

  • 2023-05-12 16h35 : Beau génère avec succès un biprime de taille appropriée et commence à essayer de le factoriser.

  • 2023-05-12 19h15 : Beau utilise des nombres premiers plus faciles à factoriser pour comparer différentes bibliothèques de factorisation et avoir une idée de l'évolution des performances. primefac est le plus performant.

  • 15/05/2023 12h12 : la gouvernance tBTC désactive la nouvelle génération de portefeuille.

  • 15/05/2023 16h36 : Beau commence à factoriser les 400 modules à l'aide de gouttelettes Digital Ocean optimisées pour le processeur.

  • 17/05/2023 14h49 : Promethea ajuste le correctif tss-lib pour qu'il soit entièrement rétrocompatible avec les clients keep.

  • 19/05/2023 13h58 : Promethea identifie les collisions de hachage potentielles et ajoute un correctif.

  • 2023-05-22 19:21 : Beau arrête les machines d'affacturage. Aucun facteur trouvé.

  • 2023-05-25 17h01 : Piotr planifie un audit Trail of Bits pour les modifications et crée un nouveau fork d'avis de sécurité de tss-lib pour faciliter l'audit.

  • 05/06/2023 14h25 : Piotr insère discrètement les modifications dans la version keep-core v2.0.0-m3.

  • 06/06/2023 21h42 : tjade273 (Trail of Bits Auditor) termine sa première passe du correctif de sécurité tss-lib.

  • 2023-06-07 14:51 : Promethea identifie que Ntilde, (un autre module Paillier) est également vulnérable et que le correctif doit également être appliqué au protocole de repartage (nous n'utilisons pas le repartage ; nous l'avons quand même corrigé).

  • 2023-06-13 14h34 : Promethea termine le repartage et le correctif Ntilde.

  • 2023-07-14 10h11 : Découvrez via ImmuneFi que Verichains a trouvé un exploit impliquant des collisions de hachage que Promethea avait déjà corrigé.

  • 18/07/2023 15h04 : Kuba confirme que le PoC Verichains n'a pas d'impact sur le client keep-core corrigé en privé.

  • 20/07/2023 11h34 : Expédiez keep-core v2.0.0-m4 qui inclut le correctif ntilde et de repartage.

  • 2023-06-29 22h49 : tjade273 termine l'audit du repartage et du correctif Ntilde.

  • 2023-08-16 13:46 : Un autre projet tweete à propos d'une nouvelle vulnérabilité (c'est la même). Nous suspendons la publication de cette divulgation pour enquêter.

[1] : Un schéma de cryptage homomorphe vous permet d'effectuer des calculs sur le texte crypté et de pouvoir le déchiffrer correctement plus tard. Pour Paillier,

décrypter(encrypt(message1) • encrypt(message2)) == message1 + message2

.

[2] : Il est facile, informatiquement, de vérifier que

N = p · q

mais difficile de comprendre ce que p et q reçoivent uniquement N. Voir Factorisation entière. Le plus grand nombre pris en compte était RSA-250, un nombre à 250 chiffres décimaux, en 2020. Le temps de calcul total était d'environ 2 700 années-cœurs de calcul.

[3] : Les commentaires de la revue pull ont été perdus lors de la fusion de la divulgation de sécurité. Nous travaillons avec GitHub pour les restaurer. En attendant, voici une capture d'écran :

Et voici le résumé de remédiation élaboré par Trail of Bits.

annexe

Ns malveillants pour l’analyse comparative

https://gist.github.com/beaurancourt/c26f437baa62ebda45d069998273b053

Résultats de référence

Mesuré en secondes, par ordre d'indice.

Résultats du calendrier de référence de vulnérabilité. Résultats du calendrier de référence de vulnérabilité. GitHub Gist : partagez instantanément du code, des notes et des extraits. Résumé 262588213843476