Skip to content

This agent detects when an attacker could trigger a selfdestruct of a UUPS implementation contract, leaving a proxy contract permanently broken.

Notifications You must be signed in to change notification settings

venglov/UUPSUpgradeable-Exploit-Agent

Repository files navigation

UUPSUpgradeable Exploit Agent


Description

This agent detects when an attacker could trigger a selfdestruct of a UUPS implementation contract, leaving a proxy contract permanently broken. The agent is separated into three threads:

  • First thread detects contracts that are not initialized.
  • Second thread detects the main exploit and tries to anticipate it - if new contract logic exists but selfdestruct method is reachable in the byte-code - this thread will provide the alert too.
  • Third thread detects when a contract is initialized by TransferOwnership event where the previous owner was 0x0000000000000000000000000000000000000000

For a detailed description of the issue refer to the post-mortem.

Agent Flow

UUPSUpgradeable.png

Supported Chains

  • Ethereum

Alerts

  • UUPS-EXPLOIT

    • Fired when there is Upgraded(address) event in the log and new implementation address returns an empty byte-code
    • Severity is always set to Critical
    • Type is always set to Exploit
    • Metadata:
      • tx_hash - hash of the transaction
      • new_implementation - address of the new implementation
      • attacker_address - sender of the transaction
  • LOGIC-NOT-INIT

    • Fired when the delegatecall target address has an owner with an address 0x0000000000000000000000000000000000000000
    • Severity is always set to High
    • Type is always set to Unknown
    • Metadata:
      • tx_hash - hash of the transaction
      • contract - address of the implementation
      • proxy - address of the proxy
  • LOGIC-CAN-SELFDESTRUCT

    • Fired when selfdestruct method is reachable in the byte-code
    • Severity is always set to High
    • Type is always set to Unknown
    • Metadata:
      • tx_hash - hash of the transaction
      • new_implementation - address of the new implementation
  • CONTRACT-INIT

    • Fired when a contract is initialized by the TransferOwnership event where the previous owner was 0x0000000000000000000000000000000000000000
    • Severity is always set to Medium
    • Type is always set to Info
    • Metadata:
      • tx_hash - hash of the transaction
      • new_owner - address of the new owner
      • contract - address of the implementation

Requirements

  • Python: 3.10

Run the agent

npm start

Tests

This attack has not, as far as we know, been executed on chain.

You can test the agent using

npm test

There are 6 test that should pass:

  • test_returns_main_exploit_finding()
  • test_returns_finding_if_logic_contract_not_initialized()
  • test_returns_finding_if_new_logic_contract_can_be_selfdestructed()
  • test_returns_finding_if_contract_was_initialized()
  • test_returns_zero_finding_if_upgraded_event_is_correct_and_code_cant_selfdestruct()
  • test_returns_zero_finding_if_logic_contract_is_initialized_already()

For these purposes, web3 and event mocks are used. You can check web3 mock in src/test/web3_mock.py and events mocks in src/test/agent_test.py

About

This agent detects when an attacker could trigger a selfdestruct of a UUPS implementation contract, leaving a proxy contract permanently broken.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published