Ethernaut靶场通关记录|以太Ethernaut靶场打靶—6 Delegation


以太Ethernaut靶场打靶—6 Delegation

    • 概括
    • 源码审计
    • 攻击

概括 本题主要是利用delegatecall函数的不严谨使用导致可以调用其他函数获取合约所有权可参考https://blog.openzeppelin.com/on-the-parity-wallet-multisig-hack-405a8c12e8f7/
对比:
call: 最常用的调用方式,调用后内置变量 msg 的值会修改为调用者,执行环境为被调用者的运行环境(合约的 storage)。
delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。
callcode: 调用后内置变量 msg 的值会修改为调用者,但执行环境为调用者的运行环境。
源码审计
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract Delegate {address public owner; constructor(address _owner) public { owner = _owner; }function pwn() public { owner = msg.sender; } }contract Delegation {address public owner; Delegate delegate; constructor(address _delegateAddress) public { delegate = Delegate(_delegateAddress); owner = msg.sender; }fallback() external { (bool result,) = address(delegate).delegatecall(msg.data); if (result) { this; } } }

这里需要对Delegate的所有权进行夺取。我们已知Delegation 部署的地址,那么我们分析delegatecall可以调用当前的合约状态,而Delegation将Delegale实例化后放入了自身合约中,因此我们可将delegate(msg.data)进行操控使之调用Pwn()对owner权限进行更改。
注意调用函数器是由sha3()对函数器进行哈希256算法,并且截取前面10个字节来标识(即0X 8byte字节)
这里我们可以调用web3.utils.sha3(“pwn()”).slice(0,10)来计算Pwn()的标识符。从而调用实现获取所有权。
攻击 【Ethernaut靶场通关记录|以太Ethernaut靶场打靶—6 Delegation】查看当前地址
Ethernaut靶场通关记录|以太Ethernaut靶场打靶—6 Delegation
文章图片

获取权限
Ethernaut靶场通关记录|以太Ethernaut靶场打靶—6 Delegation
文章图片

成功获取合约所有权
Ethernaut靶场通关记录|以太Ethernaut靶场打靶—6 Delegation
文章图片

    推荐阅读