{"id":20925335,"url":"https://github.com/apehex/forta-bot-evasion","last_synced_at":"2026-04-11T16:03:08.744Z","repository":{"id":200207913,"uuid":"690647610","full_name":"apehex/forta-bot-evasion","owner":"apehex","description":"A collection of agents scanning the blockchain for specific evasion techniques","archived":false,"fork":false,"pushed_at":"2024-01-26T19:47:23.000Z","size":725,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-19T18:09:44.494Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apehex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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-12T15:37:34.000Z","updated_at":"2024-05-11T14:10:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"bfd3a1b5-6116-4a95-8dd8-382c1b33f0f7","html_url":"https://github.com/apehex/forta-bot-evasion","commit_stats":null,"previous_names":["apehex/forta-bot-evasion"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apehex%2Fforta-bot-evasion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apehex%2Fforta-bot-evasion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apehex%2Fforta-bot-evasion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apehex%2Fforta-bot-evasion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apehex","download_url":"https://codeload.github.com/apehex/forta-bot-evasion/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243318758,"owners_count":20272144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-18T20:31:23.568Z","updated_at":"2025-12-27T21:06:56.883Z","avatar_url":"https://github.com/apehex.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Detecting Evasion Techniques\n\n## Description\n\nImplementation for the detection techniques described in the [report about smart contract evasion techniques][report-web3-evasion] by the [Apehex][github-apehex].\n\nHere, \"evasion\" refers to any tactic that deceives end-users or circumvents defense mechanisms.\n\n## Support\n\nThe bots use the transaction traces, so they only runs on Ethereum for now.\n\n## Table of Contents\n\n- [Metamorphic Contracts](#metamorphic-contracts)\n- [Red Pill Contracts](#red-pill-contracts)\n- [Scoring The Transactions](#scoring-the-ransactions)\n- [Options](#options)\n- [Development](#development)\n  - [Changelog](#changelog)\n  - [Todo](#todo)\n  - [Performances](#performances)\n- [Credits](#credits)\n- [License](#license)\n\n## Metamorphic Contracts\n\nMetamorphic contracts have the ability to change their bytecode while keeping their address.\nThey leverage the opcode `CREATE2` in a factory contract to control the deployment address of a \"mutant\" contract.\n\n### Examples\n\nMetamorphism has been used by MEV bots and hackers.\nThis technique requires 2 intermediate contracts, the factory and implementation contracts, to (re)deploy the mutant contract.\n\nFactory deployment:\n\n- Tornado hack: [0x3e93ee75ffeb019f1d841b84695538571946fd9477dcd3ecf0790851f48fbd1a](https://explorer.phalcon.xyz/tx/eth/0x3e93ee75ffeb019f1d841b84695538571946fd9477dcd3ecf0790851f48fbd1a)\n- 0age demo: [0x0f7c1dad199b29bc016c0984194b7b29ba68b130bd3d9a83e5bb20de7159d33c](https://explorer.phalcon.xyz/tx/eth/0x0f7c1dad199b29bc016c0984194b7b29ba68b130bd3d9a83e5bb20de7159d33c)\n- MEV bot: [0x29b2d5787757d494907b349662a3730340c88641d5ae78037928c2870d2b4cce](https://explorer.phalcon.xyz/tx/eth/0x29b2d5787757d494907b349662a3730340c88641d5ae78037928c2870d2b4cce)\n\nImplementation + mutant creation:\n\n- Tornado hack: [0x3e93ee75ffeb019f1d841b84695538571946fd9477dcd3ecf0790851f48fbd1a](https://explorer.phalcon.xyz/tx/eth/0x3e93ee75ffeb019f1d841b84695538571946fd9477dcd3ecf0790851f48fbd1a)\n- 0age demo: [0x7bff38c773d511cb00b9addef32b4703c69d46a3470eb0f8257b65470067a5d4](https://explorer.phalcon.xyz/tx/eth/0x7bff38c773d511cb00b9addef32b4703c69d46a3470eb0f8257b65470067a5d4)\n- MEV bot: [0x3bfcc1c5838ee17eec1ddda2f1ff0ac1c1ccdbd30dd520ee41215c54227a847f](https://explorer.phalcon.xyz/tx/eth/0x3bfcc1c5838ee17eec1ddda2f1ff0ac1c1ccdbd30dd520ee41215c54227a847f)\n\nMutant destruction:\n\n- MEV bot: [0xff7c1a73c054b75f146afe109972a608afd9503b6962e062c392e131b1678b89](https://explorer.phalcon.xyz/tx/eth/0xff7c1a73c054b75f146afe109972a608afd9503b6962e062c392e131b1678b89)\n\n### Alerts\n\nThe metamorphic contracts are spotted when created to perform static analysis on the bytecode:\n\n- `METAMORPHISM-FACTORY-DEPLOYMENT`:\n    - the factory address is attached as a label\n- `METAMORPHISM-MUTANT-DEPLOYMENT`:\n    - the mutant address is attached as a label\n\nFor all the alerts:\n\n- Type is always set to `Suspicious`\n- Severity is always `Info`\n- Metadata:\n  - `confidence`: the estimated probability of a given detection\n  - `chain_id`: the chain id\n  - `from`: the transaction sender\n  - `to`: the transaction recipient\n  - `anomaly_score`: the alert rate for this combination of bot / alert type\n\n### Detection Process\n\nOut of all the transactions on the target contracts, the factory creation and the mutant creation are the most outstanding.\n\nThe factory is detected by static analysis on its bytecode.\nAnd the mutant contract is detected by identifying specific \"metamorphic init code\" and comparing its creation code to its runtime code.\n\n|Factory detection | Mutant detection |\n| ---------------- | ---------------- |\n|![Metamorphism: factory detection][image-metamorphism-factory-detection]|![Metamorphism: factory detection][image-metamorphism-mutant-detection]|\n\nIn both cases, one of the main indicator is finding \"metamorphic init code\".\nThis init code is a stager that is required to leverage the `CREATE2`, it looks like this:\n\n```\n5860208158601c335a63aaf10f428752fa158151803b80938091923cf3\n```\n\n### Indicators\n\n#### Metamorphic Factory\n\n- runtime bytecode contains OPCODE `CREATE`\n- runtime bytecode contains OPCODE `CREATE2`\n- creation bytecode contains metamorphic init code\n\n#### Mutant Contract\n\n- creation bytecode is metamorphic init code\n- runtime bytecode is not included in creation bytecode\n- runtime bytecode has changed\n\n## Red Pill Contract\n\nRed-pill contracts try to detect simulation environments by looking for default values in the global variables.\n\nThey perform innocuous actions during simulation and activate the malicious functions only on the mainnet.\n\n### Examples\n\nBoiled to the essential, a red-pill contract looks like:\n\n```solidity\ncontract RedPill {\n    function print() public view returns (string memory) {\n        if (block.coinbase == address(0x0000000000000000000000000000000000000000)) {\n            return \"blue pill\";\n        } else {\n            return \"red pill\";\n        }\n    }\n}\n```\n\n### Alerts\n\nThe red-pill contracts are spotted when created to perform static analysis on the bytecode:\n\n- `LOGIC-BOMB-RED-PILL-DEPLOYMENT`:\n    - the address of the contract is attached as a label\n\nFor all the alerts:\n\n- Type is always set to `Suspicious`\n- Severity is always `Info`\n- Metadata:\n  - `confidence`: the estimated probability of a given detection\n  - `chain_id`: the chain id\n  - `from`: the transaction sender\n  - `to`: the transaction recipient\n  - `anomaly_score`: the alert rate for this combination of bot / alert type\n\n### Detection Process\n\nThe detection looks for conditional branches depending on the global variables.\nThese tests have a pattern that can be directly found in the bytecode with regex.\n\nIt matches chunks of HEX encoded bytecode like:\n\n```\n600073ffffffffffffffffffffffffffffffffffffffff164173ffffffffffffffffffffffffffffffffffffffff16141561012757\n```\n\n```\n6000                                          # PUSH1 0\n73ffffffffffffffffffffffffffffffffffffffff16  # cast to address\n41                                            # block.coinbase\n73ffffffffffffffffffffffffffffffffffffffff16  # cast to address\n1415                                          # equality test\n610127                                        # PUSH2 =\u003e instruction offset\n57                                            # JUMPI\n```\n\nThe detection regex accounts for variation in the compilation process due to solidity version and optimization parameters.\n\n### Indicators\n\n- bytecode contains a comparison between `COINBASE` and `address(0x0000000000000000000000000000000000000000)`\n- bytecode contains a comparison between `PREVRANDAO` and `0`\n\nNote: depending on the EVM version the opcode `0x44` is called `DIFFICULTY` or `PREVRANDAO`.\n\n## Scoring The Transactions\n\nThe bot decisions are guided by probability metrics / scores.\n\n### Interpretation Of Probabilities\n\nThe confidence that a transaction match a given target is a ratio that can be interpreted as follows:\n\n- if equal to `0.5`, it is undecided, the bot didn't find enough evidence for / against\n- from `0.5` to `1`, the chances go toward the certainty of a match\n- from `0.5` to `0`, the agent is ruling out the possibility of a match\n\n### Scoring Process\n\nThese metrics are computed in two steps:\n\n- first all the indicators (IOCs) are computed\n- then each indicator is quantified\n- then these individual indicators are combined into a probability\n\nThe indicators for each evasion technique are listed in the previous sections.\n\n### Quantifying The Indicators\n\nThe indicators are boolean values that signal the presence / absence of a given feature in the transaction.\n`True` and `False` values are quantified by their impact on the score:\n\n- `0.5` when the indicator has no impact\n- `0.5` to `1` the more it increases the probability of a match\n- `0.5` to `0` the more it lessens the probability of a match\n\n### Combining Probabilities\n\nFinally, the list of quantified indicators is turned into probabilities with the conflation function, $\\xi$:\n\n$$\\begin{align}\nConflation(p_1, ..., p_N) \u0026= \\xi(p_1, ..., p_N) \\\\\n                          \u0026= \\frac{{\\prod_{i=1}}^{N} p_i}{{\\prod_{i=1}}^{N} p_i + {\\prod_{i=1}}^{N} (1 - p_i)}\n\\end{align}$$\n\nGiven a list of probabilities $\\{p_i\\}$ and an extra probability $p$, the conflation has the following properties:\n\n- if $p = 0.5$ then $\\xi(p_1, ..., p_N, p) = \\xi(p_1, ..., p_N)$\n- if $p \u003e 0.5$ then $\\xi(p_1, ..., p_N, p) \u003e \\xi(p_1, ..., p_N)$\n- if $p \u003c 0.5$ then $\\xi(p_1, ..., p_N, p) \u003c \\xi(p_1, ..., p_N)$\n\nFor example:\n\n- when an indicator (presence / absence) doesn't add information it can be scored as `0.5`.\n- `0.9` to greatly increase the probability\n- `0.4` to slightly decrease the probability\n- `0.1` to strongly decrease the probability\n- etc\n\nRather than each individual score, it is the tendency of the list of scores that drives the overall metric toward a low / high probability.\n\n## Options\n\nThe bot settings are located in `src/options.py`:\n\n```python\nMIN_CONFIDENCE = 0.7 # probability threshold\nALERT_HISTORY_SIZE = 16384 # in number of transactions recorded\n```\n\nThe bot only fires alerts when the probability score for a given threat is above `MIN_CONFIDENCE`.\n\nIt keeps a local history of all the alerts raised to compute stats.\nThe history size is set by `ALERT_HISTORY_SIZE`.\n\n## Tests\n\nThe bots use the libraries [`toolblocks`][github-apehex-toolbox] and [`ioseeth`][github-apehex-ioseeth], which come with extensive unit tests.\n\nThey can be run in the root directory of each of these packages with `python -m pytest`.\n\n## Development\n\nContributions welcome!\n\n### Changelog\n\nSee [CHANGELOG](.github/CHANGELOG.md).\n\n### TODO\n\nSee [TODO](.github/TODO.md).\n\n### Performances\n\nThe web requests are cached.\n\nBytecode queries and balance checks require time and are performed only when relevant.\n\n## Credits\n\nOriginal work by [apehex](https://github.com/apehex).\n\nRelies on the packages:\n\n- [`ioseeth`][github-apehex-ioseeth] for the detection logic\n- [`toolblocks`][github-apehex-toolbox] for the data wrangling\n\n## License\n\nSee [LICENSE.md](LICENSE.md).\n\n[github-apehex]: https://github.com/apehex/\n[github-apehex-ioseeth]: https://github.com/apehex/web3-threat-indicators\n[github-apehex-toolbox]: https://github.com/apehex/web3-toolbox\n[image-metamorphism-factory-detection]: .github/images/metamorphism-factory-detection.png\n[image-metamorphism-mutant-detection]: .github/images/metamorphism-mutant-detection.png\n[report-web3-evasion]: https://github.com/apehex/web3-evasion-techniques/blob/main/report/web3-evasion-techniques.pdf\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapehex%2Fforta-bot-evasion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapehex%2Fforta-bot-evasion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapehex%2Fforta-bot-evasion/lists"}