CTF 第一次接触智能合约(主要描述一下操作流程)

合约地址

0x421DbB4ca0Fdb1872e5780BD95743085357CD7B8

源代码

pragma solidity ^0.4.23;
contract Trans{
    
    string flag;
    mapping(address => uint256) balances;
    constructor () public {
        flag = WHAT_YOU_WANT;
    }
    
    function getBalance() public returns (bool){
        balances[msg.sender] = 100;
        return true;
    }
    
    function showBalance() public view returns (uint256){
        return balances[msg.sender];
    }
    
    function Transfer(address[] _addr, uint256 _value) public returns (bool){
        uint times = _addr.length;
        uint256 amount = uint256(times) * _value;
        require(_value > 0 && balances[msg.sender] >= amount);
        require(times > 0 && times < 10);
        balances[msg.sender] -= amount;
        for(uint i = 0; i < times; i++){
            balances[_addr[i]] += _value;
        }
        return true;
    }
    
    function getFlag() public view returns (string){
        require(balances[msg.sender] > 9999999);
        return flag;
    }
}

这道题目就是一个整数溢出类型的漏洞

题目分析

首先通过分析getFlag我们知道,我们的账号的余额必须大于9999999
getBalance函数只是初始化账户为100
我们必须通过Transfer函数来控制余额,首先是这个函数允许一个地址数组和一个uint256整数值
相当于我们有一个账号,现在只有一百元,给10个账号发钱,然后发出去的钱从自己账号中扣除
但是整个过程中的操作都是用符号操作而没有用 safeMath,再加上合约没有判断 amount 是否会溢出
uint256 类型能表示的范围是 0 ~ ((2 ** 256) - 1) ,因此我们可以让 amount 大于 ((2 ** 256) - 1)

payload:

["0x00E7aC6a5614Bcc4e131872B8Ae055D9ccFE4110","0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c"] 
57896044618658097711785492504343953926634992332820282019728792003956564819968

第一个地址为自己的地址,第二个地址随便填就行(前提是合法的地址)
第二个值为2的255次方,由于是两个账号,所以总共扣除的值是2的256次方,大于最大值,使得溢出,则自己的账号不会扣钱
在这里插入图片描述

操作流程

这个简单描述一个整个过程,对于第一次接触的人来说,肯定会有很多坑

在这里插入图片描述

  • 点击存入

在这里插入图片描述

  • 点击测试水管
    在这里插入图片描述

  • 多点几下
    在这里插入图片描述

然后你的账户就会由0变为1

  • 访问这个http://remix.ethereum.org(有时需要科学上网)
    当然这个可以自己本地搭建,但是我总是莫名其妙的问题,我就放弃了

  • 选择环境
    在这里插入图片描述

  • 编译题目代码
    在这里插入图片描述
    在这里插入图片描述

  • 配置题目合约
    在这里插入图片描述

上面At Address填入题目给的地址,然后下面就会出现几个按钮,这几个按钮就是对应代码的几个方法,只是相当于UI化了而已

接下来的工作就是审计代码,找出漏洞了,good lucky~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值