Full Report
This report is an in the wild story of attackers compromising many contracts in a subtle way. The name says it all: Clandestine Proxy In the Middle of Proxy (CPIMP). Smart contract deployment of upgradable contracts typically works in two types: deploy the code and then call an initialization function. Unless specifically checked, the initialize function can be called by attackers before the real user sets malicious settings. In reality, if this happened, a legitimate developer should recognize the failure and just try again. At least, that's the argument I've been hearing for a long time. So, what's different here? Attackers were able to backdoor the contracts without being noticed - real value was being accrued in these contracts for several weeks as well. The malicious actors were monitoring the intended implementation and deployment procedures. Instead of the normal flow of going from the proxy to the proxy implementation, a contract was added in the middle, similar to a MitM attack. To make matters even scarier, most blockchain explorers could not tell the difference! The implementation was shown as the correct one in the explorer. Events and storage slot contests even look correct. Even the deployment showed the incorrect events. Developers just weren't being careful enough upon review. Many project contracts were backdoored, such as EtherFi and Pendle. The malicious actors were waiting for the right moment to profit, but it was caught first. The authors of the post contacted SEAL 911 to start a war room. To not freak out the attackers and get them to exploit things now, it had to be coordinated. This meant getting all affected protocols into a war room at once. Although every remediation was custom, most of the funds were recovered! So, how did the backdoor work? It was sophisicated with persistence, detection evasion and more. First, it added functionality to become the "Super-Admin" to override ownership for ugprades, drains and executions. This allowed the malicious owner to do whatever they wanted. To make it more persistent, it restored itself in the implementation slot - this meant that not even upgrades could remove it. On L2s, if the Super Admin account had been denylisted, they had signed executions that still worked. Even crazier, they added batched direct storage writes in calls as well. Some implementations contained anti-recovery protection. By reviewing balance checks before/after a call, it would prevent 90% of funds from being taken at once. That's pretty devious! The coolest part about this is by far the reason EtherScan finds the wrong implementation contract - the main reason most developers were tricked. The detection of Etherscan consults multiple storage slots that are defined in various proxy implementations IN ORDER. By placing the legitimate implementation address at the old proxy implementations slot (defined by a standard), Etherscan would find the incorrect address! Amazing work and it makes me think that Etherscan should have a fat bug bounty program. Overall, great research in detecting, documenting, and mitigating this vulnerability. In the future, I will be more hesitant about allowing initialization functions to be frontran. Neat!
Analysis Summary
# Vulnerability: CPIMP (Clandestine Proxy In the Middle of Proxy)
## CVE Details
- **CVE ID**: N/A (Blockchain-specific smart contract vulnerability; pending formal assignment)
- **CVSS Score**: 9.8 (Critical - estimated)
- **CWE**: CWE-662 (Improper Synchronization), CWE-1059 (Incomplete Documentation/Information) - specifically initialization front-running.
## Affected Systems
- **Products**: Upgradable smart contracts using the EIP-1967 Proxy standard.
- **Affected Protocols**: EtherFi, Pendle, Bera, Orderly Network, Origin, KIP Protocol, Myx, and various other tokens/oracles.
- **Networks**: Ethereum, Binance Smart Chain, Arbitrum, Base, Berachain, Scroll, and Sonic.
- **Configurations**: Any proxy contract deployed but not yet initialized (allowing for initialization front-running).
## Vulnerability Description
The **CPIMP** attack is a sophisticated Man-in-the-Middle (MitM) hijacking of smart contract proxies. The attacker monitors the blockchain for new, uninitialized proxy deployments and front-runs the legitimate `initialize()` transaction.
Instead of just stealing ownership, the attacker inserts a "Clandestine Proxy" between the original Proxy and the intended Logic Implementation.
1. **Transparency**: The CPIMP contract forwards most calls to the legitimate implementation via an additional `delegatecall`, ensuring the protocol functions as expected to avoid detection.
2. **Persistence**: The CPIMP contains logic to re-insert itself into the implementation storage slot at the end of transactions, making the backdoor resistant to standard upgrades.
3. **Evasion**: The attacker exploits the way blockchain explorers (like Etherscan) detect implementations. By placing the legitimate address in an obsolete storage slot (older OpenZeppelin standards) and the malicious address in the current EIP-1967 slot, explorers are tricked into displaying the legitimate code while the malicious proxy retains control.
## Exploitation
- **Status**: Exploited in the wild (Clandestine/Long-term persistence).
- **Complexity**: High (Requires sophisticated knowledge of storage slots and front-running).
- **Attack Vector**: Network (Public Blockchain).
## Impact
- **Confidentiality**: Low (Smart contract code is public).
- **Integrity**: Critical (Attacker gains "Super-Admin" rights to upgrade, drain funds, or override storage).
- **Availability**: High (Potential for funds to be locked or contracts to be rendered inoperable).
## Remediation
### Patches
- There is no single "patch" for deployed/infected bytecode. Affected protocols must perform custom migrations to new, secure proxy instances or execute complex storage-write "war room" interventions to eject the CPIMP.
### Workarounds
- **Atomic Deployment**: Deploy and initialize proxy contracts in a single transaction (e.g., using a Factory contract or `CREATE2`).
- **Pre-Initialization**: Implement a constructor in the implementation contract that calls `_disableInitializers()` to prevent the logic contract itself from being taken over.
## Detection
- **Indicators of Compromise**:
- Presence of two `delegatecall` instructions in a single transaction where only one is expected.
- Presence of `Upgraded` events during the initial deployment that point to an unrecognized address.
- Discrepancies between the implementation address reported by Etherscan and the address actually stored in the EIP-1967 implementation slot (`0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`).
- **Detection Tools**:
- Dedaub’s transaction explorer and monitoring queries.
- Blocksec Phalcon (for analyzing internal call traces).
## References
- Dedaub Technical Analysis: hxxps://dedaub[.]com/blog/cpimp-attack
- SEAL 911 Incident Response: hxxps://x[.]com/seal_911
- Etherscan Implementation Logic Discussion: hxxps://x[.]com/pcaversaccio/status/1943312625175064648