Skip to content

Commit

Permalink
mitm for L1
Browse files Browse the repository at this point in the history
  • Loading branch information
xavier-romero committed Jan 28, 2025
1 parent ed87dcb commit 14e46b6
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 3 deletions.
7 changes: 4 additions & 3 deletions cdk_bridge_infra.star
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ def create_reverse_proxy_config_artifact(plan, args):
src="./templates/bridge-infra/haproxy.cfg"
)

l1rpc_service = plan.get_service("el-1-geth-lighthouse")
l1rpc_host = args["l1_rpc_url"].split(":")[1].replace("//", "")
l1rpc_port = args["l1_rpc_url"].split(":")[2]
l2rpc_service = plan.get_service(
name=args["l2_rpc_name"] + args["deployment_suffix"]
)
Expand All @@ -103,8 +104,8 @@ def create_reverse_proxy_config_artifact(plan, args):
"haproxy.cfg": struct(
template=bridge_ui_proxy_config_template,
data={
"l1rpc_ip": l1rpc_service.ip_address,
"l1rpc_port": l1rpc_service.ports["rpc"].number,
"l1rpc_ip": l1rpc_host,
"l1rpc_port": l1rpc_port,
"l2rpc_ip": l2rpc_service.ip_address,
"l2rpc_port": l2rpc_service.ports["rpc"].number,
"bridgeservice_ip": bridge_service.ip_address,
Expand Down
189 changes: 189 additions & 0 deletions docs/mitm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# MITM tests in Kurtosis
## Reorg + Null answers

Run kurtosis setting ```l1_rpc_url``` to ```http://mitm:8234```

```bash
ENCLAVE_NAME=cdk
kurtosis run --enclave $ENCLAVE_NAME . '{"args":{"l1_rpc_url": "http://mitm:8234"}}'
```

As soon as you see Kurtosis executing steps (deploying L1), you can deploy the MITM image. If you run this too early (before Kurtosis starts the deployment), then the deployment fails with a "Address already in use", which is probably some kind of kurtosis bug.

This step is required to L1 contract deployment to work, so if you take too long to launch the docker, the contract deployment could fail as well.
```bash
ENCLAVE_NAME=cdk
docker run --detach --rm --name mitm -p 8234:8234 --network kt-${ENCLAVE_NAME} \
mitmproxy/mitmproxy \
mitmdump --mode reverse:http://el-1-geth-lighthouse:8545 -p 8234
```

Once Kurtosis is fully deployed, we proceed to set the real injection.

Firstly, we deploy an interactive MITM as we need to install some extra packages.
```bash
ENCLAVE_NAME=cdk

docker stop mitm

docker run -it --rm --name mitm -p 8234:8234 --network kt-${ENCLAVE_NAME} \
mitmproxy/mitmproxy \
bash
```

Then, inside the docker run these commands:

```bash
pip3 install rlp eth_utils pycryptodome

> mitm.py cat <<EOF
import json
import rlp
from eth_utils import keccak, to_hex
from random import randint
def block_hash(block: dict) -> str:
fields = [
'parentHash', 'sha3Uncles', 'miner', 'stateRoot', 'transactionsRoot',
'receiptsRoot', 'logsBloom', 'difficulty', 'number', 'gasLimit',
'gasUsed', 'timestamp', 'extraData', 'mixHash', 'baseFeePerGas',
'withdrawalsRoot', 'blobGasUsed', 'excessBlobGas',
'parentBeaconBlockRoot'
]
numeric_fields = [
'difficulty', 'number', 'gasLimit', 'gasUsed', 'timestamp',
'baseFeePerGas', 'blobGasUsed', 'excessBlobGas'
]
rlp_input = []
if not isinstance(block, dict):
return None
if not all(x in block for x in fields):
return None
for x in fields:
if x in numeric_fields:
rlp_input.append(int(block[x], 16))
else:
rlp_input.append(
bytes.fromhex(block[x][2:])
)
if x == 'mixHash':
# nonce is set to 16 0s just after mix_Hash
rlp_input.append(bytes.fromhex('0000000000000000'))
rlp_encoded = rlp.encode(rlp_input)
block_hash = to_hex(keccak(rlp_encoded))
return block_hash
def fuck_block(block):
_block_hash = block_hash(block)
if not _block_hash:
return block, False
if _block_hash != block["hash"]:
print(f"Found block hash issue: {_block_hash} vs {block['hash']}")
return block, False
block['extraData'] = '0x5ca1ab1e'
block['transactions'] = []
block['transactionsRoot'] = \
'0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'
block["hash"] = block_hash(block)
return block, True
class Reorg:
def __init__(self, reorg_perc, null_perc):
self.reorg_perc = reorg_perc
self.null_perc = null_perc
self.blocks_done = {}
def response(self, flow):
null_result = False
do_reorg = False
_i = randint(0, 99)
if _i < self.null_perc:
null_result = True
else:
_i = randint(0, 99)
if _i < self.reorg_perc:
do_reorg = True
if not (null_result or do_reorg):
return
reorg_header = ""
if flow.response.headers.get("Content-Type") == "application/json":
body = json.loads(flow.response.text)
if not isinstance(body, dict):
return
if null_result:
body["result"] = None
flow.response.text = json.dumps(body)
reorg_header = "NULL_RESULT"
else:
_result = body.get("result", {})
if not isinstance(_result, dict):
reorg_header = "NOT_A_DICT"
else:
_block_number = int(_result.get("number", "0x0"), 16)
_peer = flow.client_conn.peername
_peer_addr = _peer[0] if _peer else "UNKNOWN"
self.blocks_done[_peer_addr] = \
self.blocks_done.get(_peer_addr, [])
if _block_number == 0:
reorg_header = "ZERO_BLOCK"
else:
if _block_number in self.blocks_done.get(_peer_addr):
reorg_header = \
f"BLOCK_ALREADY_REORGED_{_block_number}"
else:
result, modified = fuck_block(body["result"])
if modified:
self.blocks_done[_peer_addr] \
.append(_block_number)
body["result"] = result
flow.response.text = json.dumps(body)
reorg_header = f"REORG_{_block_number}"
else:
reorg_header = "NOT_MODIFIED"
else:
reorg_header = "NO_JSON"
flow.response.headers["reorg"] = reorg_header
reorg_percentage = 40
null_result_percentage = 20
addons = [
Reorg(reorg_percentage, null_result_percentage)
]
EOF

mitmproxy --mode reverse:http://el-1-geth-lighthouse:8545 -p 8234 -s mitm.py
```

At that point the "fault" is already working.

By inspecting answers, you can see extra headers added to help understanding if that has been modified.

Modified block will have that header, no transactions, and fixed extraData:

![Reorged block](mitm/reorged.png)


Answers with removed result, will have that header:

![Nulled answer](mitm/nulled.png)
Binary file added docs/mitm/nulled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/mitm/reorged.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 14e46b6

Please sign in to comment.