0
点赞
收藏
分享

微信扫一扫

【CTF】paradigm-CTF babysandbox

前端王祖蓝 2021-09-28 阅读 66
日记本

babysandbox

看到题目名字就知道了题目考点: 沙盒

给出合约

BabySandbox.sol



Setup.sol


Setup.py中的isSolved()进行了是否成功解决challenge的check.

这里我不是很熟悉.slot这种用法,所以自己随便部署了一个进行试验。


应该就是取了题目合约的整个字节码。要求把合约变成一个账户。或者直接让合约自毁应该也可以。

然后我们分析下Sandbox中的各种方法


这里说的是如果caller也就是调用者是自己的话。那么就会直接调用。

delegatecall,也就是如果这里能设置出一些东西那么就可以成功改变合约状态了。


第一行检测了gas是否够用,然后calldatacopy

从调用数据的位置 f 的拷贝 s 个字节到内存的位置 t

之后他就会利用staticall继续进行检测,但是我们可以发现,他从这里进入的staticcall 是进入了 自己的合约。 相当于对自己进行了一次重入。重入之后的调用方,就是msg.sender了。也就是可以正常进入delegatecall了。

但是他利用的是staticcall在外层,所以还是不能改变合约的原有状态。

但是通过之后 他利用call进行了第二次的合约使用。也就是这里的delegatecall就可以完成任何想做的事情了。也就是我们想要的合约销毁。

那么到这里 整体的思路就很清晰了:


那么现在就考虑怎么给出一个办法,使得两次调用所执行的方法不同?

尝试思路:

我们考虑到利用全局变量进行赋值。但是可想而知这个方法并不可靠。因为我们是需要staticall通过检测的,全局变量赋值还是改变了合约的原有状态。


也就是利用类似上述的伪代码。这里是不可做的。

利用特征进行判断。但是我们可以看到每次进行交易不管是传的gas还是什么所有的call和staticall中的特征都完全相同。 所以这个方法也很难进行bypass。


考虑使用call外部变量进行改变,这种是可行的一个办法。我们可以通过在外部合约设置一个方法 我们利用内部的call方法进行请求,如果能正确返回状态值则代表当前状态就是call了。

因为外部Call方法的状态即使revert()他也会只返回一个状态码0,并不会直接阻断整个交易的正常运行。



这样就成功绕过了沙箱

这个是从github的官方wp中学到的 ,感觉应该和3的意思相同? 用等同于python的语法try catch 这样可以直接避免直接revert()


学到了很多opcode以及call staticcall delegatecall的知识。


有自学网络安全的朋友可以关注私信我哦!!!

举报

相关推荐

密码CTF

ctf进阶

mysqldump ctf

CTF笔记

ctf note

PwnTheBox CTF

JIS-CTF-VulnUpload-CTF01靶机渗透测试

ctf简单例题

0 条评论