Rejoignez-Nous sur

Capturez la pièce – Solutions de catégorie Blockchain

0*aqdZW1seUR1aFSFD

News

Capturez la pièce – Solutions de catégorie Blockchain

Coinbase

Par Peter Kacherginsky, Mark NesbittJoel Kenny Don Yu

Dans cet article, nous continuons notre couverture de solutions pour le Capturer la pièce la compétition que nous avons organisée pendant Defcon 2019. Nous nous concentrerons sur les cinq défis de la catégorie Blockchain couvrant une variété de sujets tels que les scripts Bitcoin, les logiciels malveillants de crypto-monnaie, les contrats intelligents Ethereum et les analyses de portefeuille.

Par Mark Nesbitt

Quand quelqu'un dit qu'il "possède" un certain nombre de bitcoins, cela signifie qu'il est capable de signer une transaction valide qui envoie ce nombre de bitcoins à quelqu'un d'autre. Examinons de plus près comment cela fonctionne réellement.

Une transaction bitcoin a contributions et les sorties. Une nouvelle transaction identifie les sorties des transactions précédentes, qui servent d’entrées à la nouvelle transaction.

Les sorties sont «verrouillées» avec un script composé de données et de codes opération. Afin de dépenser une sortie, la transaction de dépense fournit un script de «déverrouillage» concaténé avec le script de sortie et évalué selon des règles basées sur la pile. Si la pile est laissée dans un état valide, la transaction peut dépenser les pièces.

Voici un exemple de script de verrouillage simple:

 OP_CHECKSIG

Pour pouvoir utiliser une sortie comportant ce script de verrouillage, la transaction de dépense doit comporter une entrée avec un script de déverrouillage fournissant une signature valide, ce qui donne le script suivant:

  OP_CHECKSIG

Les 3 éléments sont placés dans la pile. Lors de son évaluation, OP_CHECKSIG a confirmé que est valable pour . Si la signature est validée, OP_CHECKSIG renvoie «true» à la pile, ce qui donne un état de pile valide. Ainsi, toute personne ayant la capacité de fournir une signature valide pour le spécifié dans le script de verrouillage de sortie peut dépenser les pièces.

Il existe de nombreuses façons d'écrire un script de verrouillage. Considérons un script légèrement plus compliqué:

OP_DUP OP_HASH160 <160 bit hash> OP_EQUALVERIFY OP_CHECKSIG

Que faudrait-il pour dépenser cette sortie? (Allusion: En savoir plus à ce sujet ici.)

Les deux exemples ci-dessus nécessitent en fin de compte que le script de déverrouillage comprenne une signature valide pour une clé publique liée au script de verrouillage. Mais ce n’est pas une exigence du réseau bitcoin – c’est le meilleur moyen de s’assurer que la propriété des pièces est mise en œuvre de manière sécurisée. Considérez le script ci-dessous:

OP_HASH256 <256 bit hash> OP_EQUALVERIFY

Toute personne pouvant fournir des données qui, une fois hachées, est égale à la <256 bit hash> valeur, sera en mesure de dépenser les pièces. Aucune clé privée requise!

Considérez la transaction Bitcoin testnet suivante:

https://blockstream.info/testnet/tx/23c9470a2269cf6430569afdd3e2e8f35f633b6cdbc34107ddbab932c4146ba3?expand

Le script de cette transaction est:

OP_HASH256 OP_PUSHBYTES_32 <64c9e17ec60cd8e074aa24fdb533b3147b651cc18d7c9bcd6b00ef483affc22f> OP_EQUAL

Quiconque peut trouver une valeur dont le hachage est 64c9e1… peut dépenser ces pièces.

Donc, ce défi revient essentiellement à casser SHA-256. Tu as ça!

Une stratégie pour tenter de casser une fonction de hachage cryptographique forte consiste à commencer à deviner de manière aléatoire. Je vais commencer par deviner «coinbase».

Dans l'hex, "coinbase" est "636f696e62617365".

Par Peter Kacherginsky

Dans ce casse-tête, une phrase clé protégeant un portefeuille crypto-monnaie vous est présentée, ainsi qu'un défi consistant à localiser une transaction cachée associée au portefeuille:

play fever bullet unlock error palm insect pottery tower torch memory liquid

Les portefeuilles modernes de crypto-monnaie suivent un ensemble de normes pour créer des sauvegardes et générer des clés: BIP-39, BIP-32, BIP-44, et SLIP-44.

Le premier standard est BIP-39: Code mnémonique pour générer des clés déterministes. Il définit un moyen de coder une entropie générée aléatoirement à l'aide de mots anglais courants. BIP-39 fonctionne en divisant des blobs binaires de 128 à 256 bits en morceaux de 11 bits, chacun correspondant à un index dans une liste de mots. En recherchant un index pour chacun des mots de la phrase mnémonique ci-dessus, il est possible de reconstruire l'entropie aléatoire d'origine et de générer le germe BIP-39:

eb872c547351612701035f9a62a8c39d87c9f3af8fea5adc77bd3861384095407902f3c9e5b5d09ac422ed4e6b8c0ae7358c28b6ed40cf6e8b077775edb49fee

Les deux normes suivantes sont utilisées pour générer les clés privées réelles à partir du BIP-39 graine ci-dessus. BIP-32: «Portefeuilles déterministes hiérarchiques» définit un algorithme sécurisé pour générer une arborescence arbitrairement dimensionnée de clés privées à partir d'une clé privée maître unique dérivée d'un BIP-39 la graine. La norme utilise une notation spéciale pour définir une clé à n’importe quel niveau de l’arbre. Par exemple, m / 0/1 définit le deuxième petit-fils dérivé du premier enfant dérivé de la clé principale. Le tableau ci-dessous illustre certaines des clés privées dérivées du premier enfant:

m/0/0 — KxDTisYSXy8fwZBtxiXKNRCkipFviJLosSceTf7BXmC79xAqzDBWm/0/1 — KzbaM51UVBognvXyuMMPTgrWnEZxdwTgZDqvmbf8SyqNyetVWGqmm/0/2 — L5QG1cxQgawk7Xf8NSbwJFPbzz13uFuvMT9uGsxKgZuwHYsGC2iPm/0/3 — KxiAyNsQKSZpTZUiQA81v59bEav7vj7odnvRVicdW8FvtGRTxZNn

BIP-44: Hiérarchie à plusieurs comptes pour les portefeuilles déterministes et SLIP-0044: Types de pièces enregistrées pour BIP-0044 Standards s’appuie sur BIP-32 pour définir des chemins spécifiques correspondant à différents types de crypto-monnaie. Le tableau ci-dessous illustre certains des chemins communs:

m/44'/0'/0'/0/0 — first Bitcoin address in the chainm/44'/0'/0'/0/1 — second Bitcoin address in the chainm/44'/1'/0'/0/0 — first Bitcoin Testnet address in the chainm/44'/1'/0'/0/1 — second Bitcoin Testnet address in the chainm/44'/2'/0'/0/0 — first Litecoin address in the chainm/44'/3'/0'/0/0 — first Dogecoin address in the chain

Notez que tous les portefeuilles hiérarchiques sont dans l’arbre 44 ’. Le signe supplémentaire (guillemet simple) à côté du numéro indique que la branche d’arbre en question est renforcée.

Comme vous pouvez le constater, une seule phrase mnémonique fournie dans le défi peut produire un nombre infini d'adresses à examiner et à rechercher pour des transactions cachées. Le défi nous donne un indice que la transaction que nous recherchons se trouve dans la branche Bitcoin Testnet, qui peut être définie comme suit:

m/44'/1'/0'/0/(2³¹ addresses)

Vous trouverez ci-dessous un exemple de script qui va forcer brutalement l'espace adresse et interroger un exemple d'API blockchain pour déterminer si l'une des adresses comporte des transactions:

from bitcoinlib.wallets import HDWalletfrom bitcoinlib.services.services import ServiceSEED = “play fever bullet unlock error palm insect pottery tower torch memory liquid”w = HDWallet.create(name=”Wallet”, keys=SEED, network=’testnet’)for i in range(0,1000):    address = w.key_for_path(path=”m/44'/1'/0'/0/%d” % i).address    transactions = Service(network=’testnet’).gettransactions(address)    for t in transactions:      print(t.info())

L'exécution de ce qui précède sur la ligne de commande produit le résultat suivant (après un certain temps):

$ python3 hideandseek.py 2>/dev/null(..redacted..)Inputs- 2Mv1XoyfFa6cygsdVJ32iEA8HsWHeVWWtcY 1595764 731f64c418415ca4be54416361bcfcc9b606a5349b425342655bb8f2d3406b18 0         p2sh-segwit p2sh_p2wpkh; sigs: 0 (1-of-0) not validatedOutputs- 2Mxm8UG8Cuf3NRnCS3bakhtTRLxYEBDfU2J 1416234 p2sh- mygH814iJuKrg7tCY2fspCCpxtU3jrzDsd 179362 p2pkh(..redacted..)

Une seule transaction a été détectée qui a payé mygH814iJuKrg7tCY2fspCCpxtU3jrzDsd 179362 Satoshis. En vérifiant le montant exact sur le site Web, vous utilisez le drapeau!

Par Joel Kenny

Dans ce casse-tête, vous recevez un échantillon de logiciels malveillants Android et vous devez procéder à un reverse engineering pour trouver l'adresse à laquelle il envoie le cryptage. Le malware est basé sur une technique utilisée dans Gustuff, une application de malware qui a été découverte à l'état sauvage plus tôt cette année.

Pour commencer, décompilez le .apk. Vous pouvez utiliser JADX, et il existe même un version en ligne.

En regardant le fichier AndroidManifest.xml de l’application, vous pouvez voir qu’elle dispose d’un service d’accessibilité.

android:permission=”android.permission.BIND_ACCESSIBILITY_SERVICE”>



Un service d'accessibilité sur Android peut énumérer des vues à l'écran et interagir avec elles pour le compte de l'utilisateur. Le code de ce service est dans SneakyService.java. Ce code dans onAccessibilityEvent () remplacera une adresse bitcoin lorsque l'utilisateur l'entrera dans une application cible spécifique:

if (companion.isCryptoAddress(text)) {  String decryptMsg = Encryption.decryptMsg(f4b);      AccessibilityNodeInfo source2 = accessibilityEvent.getSource();
Intrinsics.checkExpressionValueIsNotNull(source2, str);
if (!TextUtils.equals(source2.getText(), decryptMsg)) {
accessibilityEvent = accessibilityEvent.getSource();

Intrinsics.checkExpressionValueIsNotNull(accessibilityEvent, str);
Intrinsics.checkExpressionValueIsNotNull(decryptMsg, “payload”);
performSetTextAction(accessibilityEvent, decryptMsg);
}
}

Maintenant, pour trouver le drapeau, il vous suffit d'évaluer l'expression

Encryption.decryptMsg(f4b);

Le moyen rapide et basé sur le Web est d'utiliser un Terrain de jeu Java.

public class Encryption {
/* renamed from: a */
private static final byte() f3a = new byte(){(byte) 122, (byte) 61, (byte) 66, (byte) 31, (byte) 11, (byte) 0, (byte) 33, (byte) 84, (byte) 16, (byte) 68, (byte) 56, (byte) 77, (byte) 61, (byte) 66, (byte) 31, (byte)127, (byte) 66, (byte) 31, (byte)127, (byte) 42, (byte) 27, (byte) 3, (byte) 9, (byte) 17, (byte) 0, (byte) 33, (byte) 84, (byte) 31, (byte) 11, (byte) 31, (byte) 11, (byte) 31};
public static byte() encryptMsg(String str) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Key secretKeySpec = new SecretKeySpec(f3a, “AES”);
Cipher instance = Cipher.getInstance(“AES/ECB/PKCS5Padding”);
instance.init(1, secretKeySpec);
return instance.doFinal(str.getBytes(StandardCharsets.UTF_8));
}
public static String decryptMsg(byte() bArr) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
Key secretKeySpec = new SecretKeySpec(f3a, “AES”);
Cipher instance = Cipher.getInstance(“AES/ECB/PKCS5Padding”);
instance.init(2, secretKeySpec);
return new String(instance.doFinal(bArr), StandardCharsets.UTF_8);
}
}
class Playground {
public static final byte() f4b = new byte(){(byte) -92, (byte) 12, (byte) 23, (byte) 115, (byte) 84, (byte) 48, (byte) -125, (byte) -66, (byte) 40, (byte) 59, (byte) 105, (byte) 63, (byte) 19, (byte) 29, (byte) -93, (byte) -67, (byte) 92, (byte) 119, (byte) 69, (byte) -62, (byte)127, (byte) 35, (byte) 114, (byte) 85, (byte) 117, (byte) -5, (byte) -34, (byte) -94, (byte) -73, (byte) -97, (byte) 41, (byte) -78, (byte) 59, (byte) 13, (byte) -116, (byte) -103, (byte) -51, (byte) 53, (byte) -112, (byte) 25, (byte) -30, (byte) -76, (byte) 109, (byte) -52, (byte) -114, (byte) 118, (byte) -80, (byte) 0};
public static void main(String( ) args) throws Exception {
String output = Encryption.decryptMsg(f4b);
System.out.println(output);
}
}

L'exécution du code ci-dessus génère l'indicateur, une adresse Bitcoin: 1Ant1MoneyMoneyC1ub823ckj48m429vs3

Par Don Yu

La double dépense est l'exploit canonique de la blockchain. Il existe plusieurs moyens de doubler le coût d'une blockchain, mais le concept général est le même: un attaquant envoie une transaction à une victime. À la réception de la transaction, la victime suppose que la transaction est dans un état définitif. Dans cette hypothèse, la victime rembourse l’agresseur sous une forme ou une autre. Par exemple, l’attaquant crée une nouvelle transaction qui "écrase" essentiellement la transaction précédente en envoyant les mêmes fonds vers un autre emplacement. À ce stade, la victime aura payé car elle pensait avoir reçu une certaine quantité de crypto-monnaie. Toutefois, la transaction de double dépense redirige la crypto-monnaie que la victime avait initialement reçue vers une autre cible.

Afin de doubler les dépenses en transactions dans une blockchain UTXO, un attaquant doit d'abord soumettre une transaction qui envoie un ensemble de résultats de transaction à la victime. Une fois que la transaction est placée dans un bloc miné, elle peut être doublée. L'attaquant construit une transaction à double dépense qui utilise les mêmes résultats de transaction que la transaction d'origine. L'attaquant doit alors provoquer une certaine réorganisation de la blockchain, qui supprime le bloc avec la transaction d'origine et ajoute un bloc avec la transaction à double dépense à la blockchain. (Pour les chaînes de preuve du travail, la méthode la plus courante consiste à attaquer la blockchain à 51%). Par la suite, la transaction d'origine est essentiellement «effacée» de l'historique de la blockchain, la transaction à double dépense prenant sa place.

Dans ce défi, vous obtenez une liste de transactions comprenant un reorg et une double dépense cachée à l'intérieur. Si vous comprenez le concept de double dépense, trouver la solution est relativement simple. À quoi ressemblerait une double dépense dans la nature? Cela se produirait probablement lors d'un événement de réorg. Malheureusement, les réorganisations se produisent aussi naturellement en raison de la propagation des blocs sur un réseau minier. Cela signifie qu’après avoir trouvé une réorg, il faut alors rechercher dans la réorg une paire de transactions consommant le même UTXO.

Voici une solution que j'ai piratée ensemble:

require “json”
require ‘pp’
file = File.open “./doublespend.json”
json_data = JSON.load file
def check_for_reorg(json_data)
(1..json_data.length — 1).each do |ind|
prev = json_data(ind — 1)
curr = json_data(ind)
if has_reorg?(prev, curr)
puts “Found reorg”
doublespend_check = check_for_doublespend(prev, curr)
exit(0)
end
end
puts “No reorg found”
end
def has_reorg?(prev, curr)
hashes_prev = prev.map {|block| block(‘hash’)}
hashes_curr = curr.map {|block| block(‘hash’)}

# Assume prev.length == curr.length
(1..prev.length — 1).each do |ind|
if prev(ind)(‘hash’) != curr(ind — 1)(‘hash’)
prev_txs = prev(ind)(‘transactions’).map {|tx| tx(‘txid’)}
curr_txs = curr(ind — 1)(‘transactions’).map {|tx| tx(‘txid’)}
return true
end
end
return false
end

def check_for_doublespend(prev, curr)
prev_txs = prev.reduce(()) {|base, block| base + block(‘transactions’)}
curr_txs = curr.reduce(()) {|base, block| base + block(‘transactions’)}
prev_txs.each do |target_tx|
lookup_res = lookup_tx(target_tx, curr_txs)
if lookup_res != ()
PP.pp lookup_res
exit(0)
end
end
end
def lookup_tx(target_tx, transactions) transactions.each do |candidate_tx|
if target_tx(‘in_txos’) == candidate_tx(‘in_txos’) && target_tx(‘receiver’) != candidate_tx(‘receiver’)
return (target_tx(‘txid’), candidate_tx(‘txid’))
end
end
return ()
end
check_for_reorg(json_data)

Par Peter Kacherginsky

Le challenge Ethereum smart contract est conçu pour informer les joueurs des pièges courants du code Solidity. Dans le cadre du défi, les joueurs ont pour instruction de provoquer l'autodestruction du contrat intelligent. Il n'y a qu'une seule fonction qui puisse être appelée et qui causerait cela:

function destroyme() public { 
require(msg.sender == owner);
selfdestruct(msg.sender);
}

Remarquez le exiger fonction qui s'assure que seul le propriétaire du contrat peut l'appeler. Le propriétaire du contrat est défini dans le constructeur et sur le créateur du contrat d'origine:

constructor() public payable {
owner = msg.sender;
}

Normalement, nous serions bloqués à ce stade sans la fonction hackme nommée de manière suspicieuse qui envoie un delegatecall () à une adresse spécifiée par l'utilisateur et à un identifiant de fonction codé en dur:

function hackme(address _address) public {                 _address.delegatecall(“0x12345678”);
}

Delegatecall est une fonction unique conçue pour appeler des bibliothèques tout en préservant le contexte du contrat d’appel. Voici comment cela est défini dans Solidity docs:

Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the DELEGATECALL (CALLCODE until Homestead) feature of the EVM. This means that if library functions are called, their code is executed in the context of the calling contract, i.e. this points to the calling contract, and especially the storage from the calling contract can be accessed.

Dans cet esprit, si nous appelions la fonction hackme () avec une adresse de contrat de bibliothèque et une fonction qui modifie le propriétaire du stockage local, elle modifierait en réalité le propriétaire du contrat de challenge.

Il y a un dernier morceau du puzzle et c'est le code dur 0x12345678 paramètre dans la fonction delegatecall. La valeur est un identificateur de bas niveau utilisé pour sélectionner une fonction spécifique dans le contrat. Voici comment cela est défini dans Solidity docs:

The first four bytes of the call data for a function call specifies the function to be called. It is the first (left, high-order in big-endian) four bytes of the Keccak (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype, i.e. the function name with the parenthesised list of parameter types. Parameter types are split by a single comma — no spaces are used

Dans cette optique, il peut exister une fonction permettant à un prototype haché de générer les quatre octets. 0x12345678. Nous pourrions essayer de forcer le prototype de fonction ou de le corriger manuellement dans notre contrat intelligent; Cependant, nous pourrions aussi prendre un raccourci en utilisant une fonction de repli:

A contract can have exactly one unnamed function. This function cannot have arguments and cannot return anything. It is executed on a call to the contract if none of the other functions match the given function identifier (or if no data was supplied at all).

À l'aide d'une fonction de secours et d'un contrat personnalisé, nous pouvons remplacer la variable propriétaire du contrat de défi et exécuter la fonction d'autodestruction. Vous trouverez ci-dessous un exemple de contrat Solidity à cet effet:

pragma solidity ^0.5.0;
contract Hackme {
address public owner;
function() external payable {
owner = msg.sender;
}
}

Nous espérons que vous avez apprécié la résolution des problèmes de cette catégorie et vous souhaitons la bienvenue dans la dernière partie de la série de solutions Capture the Coin.

Si les défis de ce blog vous intéressent à plein temps, rejoignez-nous à Coinbase pour aider à créer la marque la plus fiable du secteur Crypto. ici!



Traduction de l’article de Coinbase : Article Original

BlockBlog

Le Meilleur de l'Actualité Blockchain Francophone & Internationale | News, Guides, Avis & Tutoriels pour s'informer et démarrer facilement avec Bitcoin, les Crypto-Monnaies et le Blockchain. En Savoir Plus sur L'Équipe BlockBlog

Commenter cet Article

Commenter cet Article

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

Plus dans News

Les Plus Populaires

Acheter des Bitcoin

Acheter des Alt-Coins

Sécuriser vos Cryptos

Vêtements et Produits Dérivés

Top
commodo Praesent Aenean elit. dolor. vel,