pcw109550 / log-me-maybe

2023 WACON Finals - Log Me Maybe

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Log Me Maybe

This repository stores CTF challenge Log Me Maybe which was appeared at 2023 WACON Finals. You may learn how Ethereum's event log works under the hood.

Category: Blockchain + Crypto

Description

🪵

[TEAM-TOKEN]

Author's Intention

You can theoretically(if you are a block producer) write 2048-bit arbitary data in Ethereum's block header's logBlooms field. ethgoesbloom attempted to fill in entire bloom bits. By generalizing ethgoesbloom's idea, you can write a 2048-bit RSA public modulus in logBlooms field(or anything). By solving this challenge, you will get a strong understanding of how Ethereum logs🪵 work under the hood.

To get flag, you must execute get_flag():

def get_flag(self):
    try:
        block_number = int(input("block number: "))
        p = int(input("prime: "))
        assert block_number >= 0 and p >= 1
    except:
        raise Exception(f"Invalid input")
    data = {
        "jsonrpc": "2.0",
        "method": "eth_getBlockByNumber",
        "params": [hex(block_number), False],
        "id": 1,
    }
    try:
        res = RPC(f"{self.endpoint}:{self.port}", data)
        bloom = int(res["result"]["logsBloom"], 16)
        q = bloom // p
        assert p.bit_length() == 1024 and isPrime(p)
        assert q.bit_length() == 1024 and isPrime(q)
        assert p * q == bloom
    except Exception as e:
        raise Exception(f"No flag")
    print(FLAG)

Flag

WACON2023{storing_rsa_public_modulus_on_ethereum_block_header_with_blooms}

Solution

Exploit scripts mostly generalized from ethgoesbloom.

  1. Pick RSA primes $p$, $q$ which size is 1024 bits. $N = p q$
  2. Mine topics by running exploit/log-me-maybe/miner.py.
  3. Deploy contract exploit/log-me-maybe/src/Attack.sol which receives calldata and writes topic abusing LOG4 EVM instruction.
  4. Call contract with mined topics.
  5. Interact with frontend and get flag.

Ethereum LogsBloom src: Ref

func LogsBloom(logs []*Log) []byte {
	buf := make([]byte, 6)
	var bin Bloom
	for _, log := range logs {
		bin.add(log.Address.Bytes(), buf)
		for _, b := range log.Topics {
			bin.add(b[:], buf)
		}
	}
	return bin[:]
}

Challenge Setup - Users

Deploy dist directory as tarball. Online challenge.

Distribute single token(located at src/hidden.py) per team.

Distribute netcat endpoint, which serves paradigm CTF style frontend, like

1 - launch new instance
2 - kill instance
3 - get flag

Challenge setup - Infra

Go to src directory

cd src/

If docker or docker compose is not installed, install it(only works on linux amd64).

./install-docker.sh

Build docker image.

./docker-image-build.sh

Spawn two terminals(maybe use tmux). Run

./expose-proxy.sh PORT_EXTERNAL

which opens PORT_EXTERNAL to users. Default: 12345. For reverse proxying RPC requests, for isolating blockchain for each team. Access via http.

./expose-server.sh EXTERNAL_IP

which opens port 33333 to users. This is the controller. Access via nc.

There can be up to 13 docker container which hosts geth, each of them acquiring ports from 20000 to 20012. These docker container only allow localhost access to inbound traffic.

geth Database Initialization

This section briefly explains how to create src/docker/data which is a geth database, based on src/genesis.json. You can configure genesis to fund users.

"alloc": {
    "eB2005888B3bCE12686EcA77fb77edb74362f72b": {
    "balance": "0x1b1ae4d6e2ef500000"
    },
    "78f3220F17D095a0a397a1DC621aF4EB4C57aB85": {
    "balance": "0x1b1ae4d6e2ef500000"
    }
},

Address 0x78f3220F17D095a0a397a1DC621aF4EB4C57aB85 will be the block sealer on clique.

Address 0xeB2005888B3bCE12686EcA77fb77edb74362f72b will be the user address.

Each address holds 0x1b1ae4d6e2ef500000 == 500 ETH.

Clique Genesis

Refer here

Address: 78f3220F17D095a0a397a1DC621aF4EB4C57aB85 Password: waconwacon1234

Genesis DB init

geth init genesis.json --datadir=./data
geth account new --datadir=./data
geth init --datadir=./data genesis.json

About

2023 WACON Finals - Log Me Maybe

License:MIT License


Languages

Language:Solidity 98.3%Language:Python 1.1%Language:Shell 0.5%Language:Makefile 0.0%Language:Dockerfile 0.0%Language:Nix 0.0%