{"id":19539273,"url":"https://github.com/pcw109550/log-me-maybe","last_synced_at":"2026-05-15T10:42:33.952Z","repository":{"id":204524965,"uuid":"694684752","full_name":"pcw109550/log-me-maybe","owner":"pcw109550","description":"2023 WACON Finals - Log Me Maybe","archived":false,"fork":false,"pushed_at":"2023-11-02T07:02:12.000Z","size":117,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-26T04:42:18.495Z","etag":null,"topics":["blockchain","ctf","ctf-challenges","ctf-writeup","ethereum"],"latest_commit_sha":null,"homepage":"","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pcw109550.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-21T13:42:40.000Z","updated_at":"2023-10-31T05:35:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"e8faf19f-cf02-4144-81e8-32df599058b9","html_url":"https://github.com/pcw109550/log-me-maybe","commit_stats":null,"previous_names":["pcw109550/log-me-maybe"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pcw109550/log-me-maybe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcw109550%2Flog-me-maybe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcw109550%2Flog-me-maybe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcw109550%2Flog-me-maybe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcw109550%2Flog-me-maybe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pcw109550","download_url":"https://codeload.github.com/pcw109550/log-me-maybe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcw109550%2Flog-me-maybe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33063825,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-15T02:00:06.351Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","ctf","ctf-challenges","ctf-writeup","ethereum"],"created_at":"2024-11-11T02:38:55.651Z","updated_at":"2026-05-15T10:42:33.917Z","avatar_url":"https://github.com/pcw109550.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Log Me Maybe\n\nThis repository stores CTF challenge `Log Me Maybe` which was appeared at 2023 [WACON](https://wacon.world/) Finals. You may learn how Ethereum's event log works under the hood.\n\nCategory: `Blockchain` + `Crypto`\n\n## Description\n\n🪵\n\n[TEAM-TOKEN]\n\n## Author's Intention\n\nYou 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.\n\n[ethgoesbloom]: https://github.com/smartcontracts/ethgoesbloom/tree/master\n\nTo get flag, you must execute `get_flag()`:\n```py\ndef get_flag(self):\n    try:\n        block_number = int(input(\"block number: \"))\n        p = int(input(\"prime: \"))\n        assert block_number \u003e= 0 and p \u003e= 1\n    except:\n        raise Exception(f\"Invalid input\")\n    data = {\n        \"jsonrpc\": \"2.0\",\n        \"method\": \"eth_getBlockByNumber\",\n        \"params\": [hex(block_number), False],\n        \"id\": 1,\n    }\n    try:\n        res = RPC(f\"{self.endpoint}:{self.port}\", data)\n        bloom = int(res[\"result\"][\"logsBloom\"], 16)\n        q = bloom // p\n        assert p.bit_length() == 1024 and isPrime(p)\n        assert q.bit_length() == 1024 and isPrime(q)\n        assert p * q == bloom\n    except Exception as e:\n        raise Exception(f\"No flag\")\n    print(FLAG)\n```\n\n## Flag\n\n```\nWACON2023{storing_rsa_public_modulus_on_ethereum_block_header_with_blooms}\n```\n\n## Solution\n\nExploit scripts mostly generalized from [ethgoesbloom].\n\n1. Pick RSA primes $p$, $q$ which size is 1024 bits. $N = p q$\n2. Mine topics by running [exploit/log-me-maybe/miner.py](https://github.com/pcw109550/log-me-maybe/blob/main/exploit/log-me-maybe/miner.py). \n3. Deploy contract [exploit/log-me-maybe/src/Attack.sol](https://github.com/pcw109550/log-me-maybe/blob/main/exploit/log-me-maybe/src/Attack.sol) which receives calldata and writes topic abusing [`LOG4`](https://ethervm.io/#A4) EVM instruction.\n4. Call contract with mined topics.\n5. Interact with frontend and get flag.\n\nEthereum LogsBloom src: [Ref](https://github.com/ethereum/go-ethereum/blob/233db64cc1d083e6251abe768c97e0454e2ca898/core/types/bloom9.go#L119C1-L129C2)\n\n```go\nfunc LogsBloom(logs []*Log) []byte {\n\tbuf := make([]byte, 6)\n\tvar bin Bloom\n\tfor _, log := range logs {\n\t\tbin.add(log.Address.Bytes(), buf)\n\t\tfor _, b := range log.Topics {\n\t\t\tbin.add(b[:], buf)\n\t\t}\n\t}\n\treturn bin[:]\n}\n```\n\n## Challenge Setup - Users\n\nDeploy [dist](dist) directory as tarball. Online challenge.\n\nDistribute single token(located at [src/hidden.py](src/hidden.py)) per team.\n\nDistribute netcat endpoint, which serves paradigm CTF style frontend, like\n```\n1 - launch new instance\n2 - kill instance\n3 - get flag\n```\n\n## Challenge setup - Infra\n\nGo to src directory\n```sh\ncd src/\n```\n\nIf docker or docker compose is not installed, install it(only works on linux amd64).\n```sh\n./install-docker.sh\n```\n\nBuild docker image.\n```sh\n./docker-image-build.sh\n```\n\nSpawn two terminals(maybe use tmux). Run\n\n```sh\n./expose-proxy.sh PORT_EXTERNAL\n```\nwhich opens `PORT_EXTERNAL` to users. Default: 12345. For reverse proxying RPC requests, for isolating blockchain for each team. Access via http.\n\n```sh\n./expose-server.sh EXTERNAL_IP\n```\nwhich opens port 33333 to users. This is the controller. Access via nc.\n\nThere 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.\n\n### geth Database Initialization\n\nThis section briefly explains how to create [src/docker/data](src/docker/data) which is a geth database, based on [src/genesis.json](src/genesis.json). You can configure genesis to fund users.\n\n```json\n\"alloc\": {\n    \"eB2005888B3bCE12686EcA77fb77edb74362f72b\": {\n    \"balance\": \"0x1b1ae4d6e2ef500000\"\n    },\n    \"78f3220F17D095a0a397a1DC621aF4EB4C57aB85\": {\n    \"balance\": \"0x1b1ae4d6e2ef500000\"\n    }\n},\n```\n\nAddress `0x78f3220F17D095a0a397a1DC621aF4EB4C57aB85` will be the block sealer on clique.\n\nAddress `0xeB2005888B3bCE12686EcA77fb77edb74362f72b` will be the user address.\n\nEach address holds `0x1b1ae4d6e2ef500000 == 500 ETH`.\n\n#### Clique Genesis\n\nRefer [here](https://ethereum.stackexchange.com/questions/51091/clique-genesis-file)\n\nAddress: `78f3220F17D095a0a397a1DC621aF4EB4C57aB85`\nPassword: `waconwacon1234`\n\n#### Genesis DB init\n\n```sh\ngeth init genesis.json --datadir=./data\ngeth account new --datadir=./data\ngeth init --datadir=./data genesis.json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcw109550%2Flog-me-maybe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpcw109550%2Flog-me-maybe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcw109550%2Flog-me-maybe/lists"}