Egis-Security / CTF_Challenge

Repository containing CTF challenges from nmirchev8, deth and bOgO.
14 stars 8 forks source link

DoS due to insufficient checks on `codehash` (deth) deth_ctf #9

Open amaron14 opened 1 month ago

amaron14 commented 1 month ago
  1. Insufficient Check for Existing Code: The check vaultAddress.codehash != bytes32(0) is used to determine if a Vault contract has already been deployed at the computed address. However, this check is insufficient because, as per EIP-1052, an address with a non-zero balance but no code will not return bytes32(0) for its codehash. Instead, it will return the hash of an empty string, keccak256("").

  2. Potential Attack Vector: An attacker can compute the address where the Vault contract will be deployed), then transfer a small amount of ETH (like 1 wei) to this address. This would cause the codehash at the address to be keccak256(""), not bytes32(0). Consequently, the condition vaultAddress.codehash != bytes32(0) would incorrectly pass, and the deployVault() function would revert with AlreadyDeployed(), preventing the legitimate deployment of the Vault contract.

This could result in a denial-of-service (DoS) attack, where the attacker can prevent a user from deploying their Vault contract by preemptively sending a small amount of ETH to the address where the contract would be deployed.

amaron14 commented 1 month ago

Vulnerability in Factory Contract: Insufficient Validation on Contract Deployment

Summary

The Factory contract contains a vulnerability in its deployVault() function that allows an attacker to prevent the deployment of a Vault contract by manipulating the state of the target address. This vulnerability is due to an insufficient check when determining whether a contract has already been deployed at a given address.

Vulnerability Details

Insecure Code Validation

In the current implementation, the deployVault() function checks whether a Vault contract has already been deployed at the computed address using the following condition:

if (vaultAddress.codehash != bytes32(0)) { revert AlreadyDeployed(); }

However, this check is insufficient because, according to EIP-1052, an address with a non-zero balance but no code will not return bytes32(0) for its codehash. Instead, it will return the hash of an empty string, keccak256("").

Attack Scenario

An attacker can:

  1. Compute the address where the Vault contract will be deployed.
  2. Transfer a small amount of ETH (e.g., 1 wei) to this address, causing its codehash to become keccak256("").
  3. When the legitimate user calls deployVault(), the vaultAddress.codehash != bytes32(0) check will pass incorrectly, causing the transaction to revert with the AlreadyDeployed() error.

Impact

This vulnerability can be exploited to perform a denial-of-service (DoS) attack, preventing legitimate users from deploying their Vault contract by preemptively sending a small amount of ETH to the target address.

0xdeth commented 1 month ago

You are correct!

Gj @amaron14.