Attaccare uno Smart Contract
Come accennato nel capitolo precedente il codice eseguito dagli Smart Contract Bitcoin e' pubblico e quindi puo' essere analizzato ed eventualmente attaccato.
Last updated
Come accennato nel capitolo precedente il codice eseguito dagli Smart Contract Bitcoin e' pubblico e quindi puo' essere analizzato ed eventualmente attaccato.
Last updated
Questo argomento e' collegato a quanto descritto in Bitcoin Smart Contract 101, proseguire senza aver seguito il capitolo precedente potrebbe essere difficile :)
Se provenite dal precedente capitolo e non avete minato blocchi dopo aver inoltrato la transazione finale siete gia' pronti.
Altrimenti potete eseguire il seguente per ripristinare la situazione
Ricapitolando: adesso la transazione che contiene il redeem script ed i parametri di input per sbloccare la UTXO associata al P2SH e' in mempool.
Qui sulla sinistra trovate due localhost bookmarks riguardo la mempool.
Bitcoin regtest mempool mostra un resoconto della mempool senza i dettagli delle singole transazioni.
Hansel get raw mempool mostra i dettagli delle singole transazioni.
Tramite il seguente comando siamo in grado di recuperare il primo transaction ID disponibile in mempool (arrivando dall'esercizio precedente abbiamo solo una transazione in mempool).
Per poter accedere al codice sorgente (redeem script + parametri di input) dello Smart Contract bisogna prima ottenere lo ScriptSig!
Noterete che lo ScriptSig e' composto da due sequenze esadecimali separate da uno spazio. L'ultima sequenza e' sempre la versione serializzata del redeem script.
Per attaccare uno Smart Contract abbiamo bisogno di capire come funziona e quindi di poter leggere la versione del redeem script che mostra i nomi delle opcodes altrimenti e' un po' dura :)
Osservando a fondo il redeem script deduciamo che l'unica verifica svolta e' l'OP_EQUAL finale.
Questo significa che conoscendo il parametro di input corretto possiamo costruire una nuova transazione che dirotti il pagamento.
I parametri di input sono gia' all'interno dello ScriptSig!
Inoltre tutte le informazioni necessarie per costruire la transazione che dirotta i fondi sono all'interno della transazione in mempool!
Con la release di Bitcoin Core 0.12 nel 2016 e' stato inserito il BIP-125 che consente di sostituire una transazione in mempool con una, che spende la stessa UTXO, le quali fee per i miner sono maggiori.
Per svolgere il nostro attacco dobbiamo quindi dedurre quante fee erano inizialmente previste dalla transazione che vogliamo attaccare.
Le fee di una transazione sono la differenza fra l'ammontare di bitcoin dell'UTXO che stiamo spendendo e l'ammontare di bitcoin inviati.
Possiamo utilizzare lo stesso script del capitolo precedente per creare la transazione dell'hacker!!
L'ultimo passaggio che rimane da fare e' inviare la transazione e poi controllare che sia stata sostiuita in mempool.
Se riceviamo un errore absurdly-high-fee
e' perche' abbiamo esagerato con le fee e Bitcoin Core ci blocca preventivamente, possiamo bypassare (ai soli fini ludici mi raccomando!!) questo controllo aggiungendo un secondo parametro 1000
al sendrawtransaction
.
Ottimo! Con il seguente comando possiamo verificare che la transazione attualmente in mempool e' diretta verso l'address del LOHACKER!
La gestione della mempool non e' supervisionata delle regole di consenso emergente riguardante i blocchi di Bitcoin.
Vero e' che se la maggior parte dei nodi della rete implementano il BIP-125 rigorosamente sara' possibile sostituire una transazione nella mempool di tutti i nodi solo se questa e' stata creata con l'apposito valore in nSequence
.
Quindi si potrebbe creare la transazione che utilizza la UTXO P2SH "con password" senza attivare il BIP-125 (impostando a false l'ultimo parametro qua). Cosi' facendo la transazione malevola dell'hacker sara' rifiutata dai nodi, che implementano rigorosamente il BIP-125, perche' in conflitto con la transazione gia' in mempool la quale non aveva attivato l'RBF.
Chiaramente quando si parla di gestire bitcoin con Smart Contract non possiamo affidarci ai "se" ed i "ma" quindi sempre meglio progettare Smart Contract che non siano attaccabili mentre risiedono in mempool: vincolarne sempre l'esecuzione con successo o meno alle opcodes OP_CHECKSIG
/OP_CHECKMULTISIG
e con adeguati flag SIGHASH