小红花师傅出的题

赛时只有Pikachu师傅靠着强大的黑暗之力直接梭了。另一道题是个判断

x^3+y^3=z^3(mod 2**256) 就不说了。

随便搞几个 2**101 , 2**102, 2**103.就相等了。

这题比较神奇下面来复现下。

题目没有给出合约源代码。

只能考虑合约逆向。

首先考虑上Ropsten的测试链找合约来看看。

发现存了slot 1 和 2是一个20字节长度的值,是一个合约的地址。

合约逆向时发现这里对于stor1和stor0 的 方法进行了调用。就能实锤了。

还是先找如何payforflag()

首先slot 1函数调用成功,其次调用slot 0函数返回>270 那么就可以得到flag了。

先看slot 0合约, slot0中,storage[0]给了一个mapping uint256 ,storage[1]第二个是一个结构体数组。

且可以通过22152a06方法得知storage[1]的长度。

继续看函数,

这里满足_param1 < stor1.length的时候,我们可以修改低20字节。但是创建合约时候,数组无长度,无法做到越界任意写。

继续看其他函数 6dd0

这里如果stor1.length初始为0 ,--直接下溢 就可以越界任意写了。看看如何触发。

这里首先check传入的参数等于 数组长度*0.1eth, 然后遍历数组,找出传参的index,把index的数组索引全部向前挪动1位,之后又call这里,发现可以打重入。 然后最后把数组元素置0.

但是前提是合约得有0.1 eth,不然他转不出来。 直接selfdestruct即可。

然后算一下覆盖地址 因为返回要求270的那个函数自己%了270 不可能正常返回一个数,所以只能考虑覆盖了。


再看第一个条件。

对应的返回函数做的是一个 bytes4=>bool的映射。只有bool是false的才能调用。

妻子红slot 0xb10e的地址是上面的合约地址。

发现fallback函数。

首先取了slot1第四个元素,然后delegatecall。

看看slot1第四个元素是什么。

动态数组就直接用keccak256(abi.encode(1))算基质然后在加3即可。

这个地址就是我们的上一个合约地址。

而正好上一个合约有任意写。

恰巧的是这两个合约的地址排布十分相似。我们的第一个 变长数组的基地址与第二个一样。我们虽然不能直接覆写掉0x7bd这个签名的lock但是我们可以通过他的delegatecall改上面合约的地址从而写我们的任意合约。从而使得的这个和合约的lock签名改掉。

直接曲线救国:

contract lockUnlock{
    mapping(bytes4 => bool) locked;
 
    function unlock() public{
        locked[0x7bd955f3] = false;
    }
}

对应合约的锁就被打开了。

好题

推荐文章

发表评论

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