This repository demonstrates that a malicious module (malicious_module.go) can send packets to the IBC channel without owning the channel capability. Malicious code is added to the module's BeginBlock() method and uses reflection to obtain the IBC store key from the sdk.Context instance. After obtaining the store key, it creates the transfer packet and inserts it into the store. The packet then gets relayed to the other chain and the specified account receives the tokens.
The "demo" directory contains two chain binaries and scripts to run the chains and set up the channels between them in order to demonstrate the exploit. The scripts run on Linux and can be run with "bash run.sh". After 30+ blocks (delay is to open the transfer channel) the tokens start to appear on the receiver chain. To verify this, run the following CLI command:
./interchain-security-pd q bank balances cosmos1jcv4608cflgjz9m9tdmnf32n9j9fxctczyg55y --node tcp://localhost:26658
which should result with the output similar to this one (3 tokens get sent in each block):
balances:
- amount: "12" denom: ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9 pagination: next_key: null total: "0"
Notes: - The demo uses Interchain Security with provider and consumer chains, but this is not mandatory for exploit demonstration. It can be done between any two chains that have a transfer channel open between them. Since we are using ICS, the malicious code assumes that transfer channel id is channel-1, since this is the case in ICS.