solidity漏洞实践(一)

题目描述

漏洞源码如下

pragma solidity ^0.4.19;
contract Vuln{
    
    
    address public owner;
    string public name     = "Chain";
    string public symbol   = "CHA";
    uint8  public decimals = 18;
    uint public totalSupply=10000000000;
    bool  public isLoan=false;
    bool public solved;
    event  Approval(address indexed from, address indexed to, uint number);
    event  Transfer(address indexed from, address indexed to, uint number);
    event  Deposit(address indexed to, uint number);
    event  Withdrawal(address indexed from, uint number);

    mapping (address => uint)                       public  balanceOf;
    mapping (address => mapping (address => uint))  public  allowance;
    constructor() public{
    
    
        owner=msg.sender;
        balanceOf[owner]=totalSupply/2;
        balanceOf[address(this)]=totalSupply/2;
    }


    function withdraw(uint number) public {
    
    
        require(balanceOf[msg.sender] >= number);
        balanceOf[msg.sender] -= number;
        (msg.sender).transfer(number);
        emit Withdrawal(msg.sender, number);
    }


    function approve(address to, uint number) public returns (bool) {
    
    
        allowance[msg.sender][to] = number;
        emit Approval(msg.sender, to, number);
        return true;
    }

    function transfer(address _to, uint _value) public returns (bool) {
    
    
        require(balanceOf[msg.sender] - _value >= 0);
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
    return true;
    }

    function fakeflashloan(uint256 value,address target,bytes memory data) public{
    
    
        require(isLoan==false&&value>=0&&value<=1000);
        balanceOf[address(this)]-=value;
        balanceOf[target]+=value;

        address(target).call(data);

        isLoan=true;
        require(balanceOf[target]>=value);
        balanceOf[address(this)]+=value;
        balanceOf[target]-=value;
        isLoan=false;
    }

    function transferFrom(address from, address to, uint number)
        public
        returns (bool)
    {
    
    
        require(balanceOf[from] >= number);

        if (from != msg.sender && allowance[from][msg.sender] != 2**256-1) {
    
    
            require(allowance[from][msg.sender] >= number);
            allowance[from][msg.sender] -= number;
        }

        balanceOf[from] -= number;
        balanceOf[to] += number;

        emit Transfer(from, to, number);

        return true;
    }
    function isSolved() public returns(bool){
    
    
        return solved;
    }

    function complete() public {
    
    

        require(balanceOf[msg.sender]>10000);
        require(allowance[address(this)][msg.sender]>10000);
        solved=true;

    }
}

在这里插入图片描述

这里面我发现了两个漏洞
一是在transfer中可能出现uint256溢出漏洞
二是在fakeflashloan中可能出现的call注入漏洞
于是
要拿到flag的第一个条件可用溢出漏洞解决
第二个条件可用call注入漏洞解决
一.
在这里插入图片描述
在这里插入图片描述
成功满足第一个require

二.
在这里插入图片描述
在这里插入图片描述
成功满足第二个require

调用complete函数后成功获取flag!
在这里插入图片描述
由于自己本身对该漏洞方面的题目不是很熟悉,所以几乎是看了别人的解决方法自己动手实践了一次,请多见谅。

猜你喜欢

转载自blog.csdn.net/m0_68764244/article/details/125382239