-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CREATE2 address collision during pool deployment allows for complete draining of the pool before the assertion is created on the Rollup contract #115
Comments
hello judge @Picodes I'd like to bring this report to your attention since it looks like it didn't pass the Validation's queue. This report is addressing the exact same issue about address collission that was assesed as a valid medium in the Panoptic Contest hosted in April 2024 Though, in this case, the funds at stake are greather, an AssertionPool would needs to collect the same amount of funds that a single validator would need to, ~1k ETH. I'd like to ask if you could take a look at this report and let me know your thoughts about it. |
Hey, it seems to reduce the hash needed to 2^81, a precondition is we can both brutal force (1) and (2). But in the context of this contest, when a staking pool needs to be created, the pool address is uniquely determined. So we will still need 2^160 hashes? Please correct me if I misunderstood anything. |
We cannot brutal assertionHash since those randomly generated pools are just meaningless and no ppl would deposit into them. |
Hey @xuwinnie The two pools are created deterministically, assertionPools are created deterministically solely on the parameters passed to the constructor, (which one of the two parameters is the rollup, thus, is a known parameter in advanced), panopticPools are created deterministically based on the salt specified by the user. You are right about people not depositing into those random generated pools, the attack would be performed on an assertionPool for an assertionHash that would be posted on the Rollup, an assertionHash that needs to crowdfund the required resources for it to be posted. The setup between the assertionPool and a panopticPool is 95% the same, the two are created deterministically, that's why I wanted to ask @Picodes to know his thoughts on this report, since the same problem was accepted in a recent contest. |
It seems in the panoptic contest those pools are not meaningless? (They are just normal pools with correct token and a brutal forced salt) |
Yes, that's the point of the collision address. Instead of brute forcing a salt as in a PanopticPool, for an AssertionPool is brute forced the assertionHash. That's the only difference between the 2 pools |
Given:
If the |
The difference between brute forcing a salt in Panoptic and an assertionHash is critical as, as shown by @xuwinnie, no one would deposit in a randomly generated assertionHash, so there is no issue here |
@Picodes I just wanted to clarify that the brute forcing would be the same as described on the Panoptic's report, but here, instead of brute forcing the salt that would be used to create the pool, it would be brute forced the assertionHash of an assertionPool where users would deposit to post such assertionHash on the Rollup contract. In the end, I agree with your judging, I just wanted to comment the exact similute between this report and the one from the Panoptic contest. |
Lines of code
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/assertionStakingPool/EdgeStakingPoolCreator.sol#L19
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/assertionStakingPool/AssertionStakingPoolCreator.sol#L19
Vulnerability details
Impact
Funds transferred to an Assertion/Edge StakingPool can be drained by an attacker via a hash collision.
Proof of Concept
(NOTE: This report is inspired from this past valid report. Necessary changes have been made to suit the Arbitrum BoLD Protocol.)
The attack consists of two parts: Finding a collision and actually draining the lending pool. We describe both here:
PoC: Finding a collision
The pools created using the
AssertionStakingPoolCreator::createPool() function
or theEdgeStakingPoolCreator::createPool() function
sets thesalt
as 0, which means, the final address where the contract will be deployed relies solely on the parameters of the constructor of the newly created contract, in this case, the rollup and assertionHash.PoC: Assertion/Edge StakinPoolCreator contracts deploy the contracts to a deterministic address
Add the below test to the
AssertionStakingPool.t.sol
test fileassertionHash
was deployed to (during the setup())The address collision an attacker will need to find are:
Both sets of addresses can be brute-force searched because:
An attacker can find any single address collision between (1) and (2) with high probability of success using the following meet-in-the-middle technique, a classic brute-force-based attack in cryptography:
The feasibility, as well as detailed technique and hardware requirements of finding a collision, are sufficiently described in multiple references:
The hashrate of the BTC network has reached 6.5x10^20 hashes per second as of time of writing, taking only just 31 minutes to achieve 2^80 hashes. A fraction of this computing power will still easily find a collision in a reasonably short timeline.
PoC: Draining the lending pool
Even given EIP-3607 which disables an EOA if a contract is already deployed on top, we show that it's still possible to drain the Assertion/Edge StakingPool entirely given a contract collision.
Assuming the attacker has already found an address collision against an undeployed Assertion/Edge StakingPool, let's say 0xCOLLIDED. The steps for complete draining of the Assertion/Edge StakingPool are as follow:
First tx:
Post Dencun hardfork, selfdestruct is still possible if the contract was created in the same transaction. The only catch is that all 3 of these steps must be done in one tx.
The attacker now has complete control of any funds sent to 0xCOLLIDED.
Second tx:
The attacker has stolen all funds from the Assertion/Edge StakingPool.
Proof of Concept
While we cannot provide an actual hash collision due to infrastructural constraints, we are able to provide a coded PoC to prove the following two properties of the EVM that would enable this attack:
Here is the PoC, as well as detailed steps to recreate it:
Tools Used
Manual Audit
Recommended Mitigation Steps
Don't use an empty salt to create the pools.
block.timestamp and block.number
. This would make impossible for an attacker to compute collisions in advance, given that now the address of the deployed contract would depend on the exact block.timestamp and block.number when the contract is created.Assessed type
Other
The text was updated successfully, but these errors were encountered: