0xmonaco CTF 体验心得
由开发人员、艺术家和设计师组成的集体 MatchBoxDAO 宣布推出 MatchBox Arena。该团队将其称为“Web3 公司的世界杯”,并表示游戏锦标赛旨在找出哪家公司拥有最好的技术团队。首先,可以代表公司和世界顶级的crypto公司(uniswap,polygon,ledger,chainlink。。。)同台竞技真的是一个非常荣幸的事情。所以我牺牲了宝贵的春节假期,就一直在打这个比赛。 这次CTF是一个用solidity操控汽车的算法比赛(终于遇到我非常感兴趣的地方了)介绍这本质上来说是一次博弈实验,而不是一次简单的代码hackthon。更像是一个社会实验,涉及纯技术方面、经济激励、效用优化模式和理性的压力测试。对于每一个参赛者,你需要实现自己的Car合约,特别是takeyourturn这个函数。对于每一轮你都需要做出决策,具体有五种决策: 1)加速(ACCELERATE) 2)炮弹(SHELL) 3)超级炮弹(SUPER_SHELL) 4)香蕉(BANANA) 5)盾(SHIELD) 有点像跑跑卡丁车?是的。。每一种决策都会耗费掉你的金额,你的金额总量是17500。而...

成长 -- 随笔(2)
深夜陷入了沉思,回顾了一下自己的成长历程。距离上一次的成长随笔已经过去7个月了~~ https://mirror.xyz/0xaaE7a1AD2764626d09a233a9bC06C38b413637cf/By3P_3NiIriKGObdbWlFo0mDdwFDY1v9VFbjaUMmObU 既然是随笔,我觉得格式什么的,就随意了~~ 这段时间我学了啥呢~~ Uniswap V2, V3; 精通Curve ( 3 Pool, Meta Pool, Compond Pool, AAVE Pool) ~~~ Balancer V2, Kyber, Bancor ; AAVE, Clipper, DODO, Mstable, Saddle, Shell, Wombat ~~~ DODO, DODO V2, Fraxswap ~~ 对我来说,能力提升最大的是打CTF。比赛的过程,纠错发现bug的攻防真的很能提升一个人的合约能力~~~ 最开心的是,认识了组内Andrew和Jimmy两位Crypto科学家~~ 最感激的是,Melvin带着我做项目,耐心和孜孜不倦地引导我去激发自己的潜能~~...
成长 -- 随笔
我完全不敢想象自己的成长速度。 1个月前,我还在和慢雾的群上问curve的合约代码的语言是的时候。余弦大佬回了我是vyper。我现在已经可以把vyper语言看懂了, 并且对于原理也掌握了。 把curve代码看了一下一遍,其实也发现不过如此。白皮书,其实也没这么深奥。跟当年打ACM的那种级别比,还是差得有点远。 Hardhat也越来越熟悉了。当时那个编写测试用例还要问XD的那个毛头小子,已经成长了好多。 我觉得我现在完全可以独立撑起一个商业项目,唯一卡住的地方可能是JS还是不太熟悉。基本功能是OK的,但是遇到一些比较少见的bug。估计,要问人。 对于以前的我来说,3,4天吃透一个主流Defi协议,我真的想都不敢想。如果只是调研,我觉得我还是勉强可以一试。 这种成长的速度我只能用指数级别来形容。我看了一下一个月前的自己,觉得好菜。 我很希望我一个月之后,再回头看现在的我,也是觉得现在的我很菜~~ end


0xmonaco CTF 体验心得
由开发人员、艺术家和设计师组成的集体 MatchBoxDAO 宣布推出 MatchBox Arena。该团队将其称为“Web3 公司的世界杯”,并表示游戏锦标赛旨在找出哪家公司拥有最好的技术团队。首先,可以代表公司和世界顶级的crypto公司(uniswap,polygon,ledger,chainlink。。。)同台竞技真的是一个非常荣幸的事情。所以我牺牲了宝贵的春节假期,就一直在打这个比赛。 这次CTF是一个用solidity操控汽车的算法比赛(终于遇到我非常感兴趣的地方了)介绍这本质上来说是一次博弈实验,而不是一次简单的代码hackthon。更像是一个社会实验,涉及纯技术方面、经济激励、效用优化模式和理性的压力测试。对于每一个参赛者,你需要实现自己的Car合约,特别是takeyourturn这个函数。对于每一轮你都需要做出决策,具体有五种决策: 1)加速(ACCELERATE) 2)炮弹(SHELL) 3)超级炮弹(SUPER_SHELL) 4)香蕉(BANANA) 5)盾(SHIELD) 有点像跑跑卡丁车?是的。。每一种决策都会耗费掉你的金额,你的金额总量是17500。而...

成长 -- 随笔(2)
深夜陷入了沉思,回顾了一下自己的成长历程。距离上一次的成长随笔已经过去7个月了~~ https://mirror.xyz/0xaaE7a1AD2764626d09a233a9bC06C38b413637cf/By3P_3NiIriKGObdbWlFo0mDdwFDY1v9VFbjaUMmObU 既然是随笔,我觉得格式什么的,就随意了~~ 这段时间我学了啥呢~~ Uniswap V2, V3; 精通Curve ( 3 Pool, Meta Pool, Compond Pool, AAVE Pool) ~~~ Balancer V2, Kyber, Bancor ; AAVE, Clipper, DODO, Mstable, Saddle, Shell, Wombat ~~~ DODO, DODO V2, Fraxswap ~~ 对我来说,能力提升最大的是打CTF。比赛的过程,纠错发现bug的攻防真的很能提升一个人的合约能力~~~ 最开心的是,认识了组内Andrew和Jimmy两位Crypto科学家~~ 最感激的是,Melvin带着我做项目,耐心和孜孜不倦地引导我去激发自己的潜能~~...
成长 -- 随笔
我完全不敢想象自己的成长速度。 1个月前,我还在和慢雾的群上问curve的合约代码的语言是的时候。余弦大佬回了我是vyper。我现在已经可以把vyper语言看懂了, 并且对于原理也掌握了。 把curve代码看了一下一遍,其实也发现不过如此。白皮书,其实也没这么深奥。跟当年打ACM的那种级别比,还是差得有点远。 Hardhat也越来越熟悉了。当时那个编写测试用例还要问XD的那个毛头小子,已经成长了好多。 我觉得我现在完全可以独立撑起一个商业项目,唯一卡住的地方可能是JS还是不太熟悉。基本功能是OK的,但是遇到一些比较少见的bug。估计,要问人。 对于以前的我来说,3,4天吃透一个主流Defi协议,我真的想都不敢想。如果只是调研,我觉得我还是勉强可以一试。 这种成长的速度我只能用指数级别来形容。我看了一下一个月前的自己,觉得好菜。 我很希望我一个月之后,再回头看现在的我,也是觉得现在的我很菜~~ end

Subscribe to shaneson.eth

Subscribe to shaneson.eth
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
原文出处:
https://nft.mirror.xyz/VdF3BYwuzXgLrJglw5xF6CHcQfAVbqeJVtueCr4BUzs
审计组和NFT组汇报一个非常重要的安全分享,这里收录一下。背景:一位白帽子发现了opensea一个发现关键的一个合约漏洞,并且已经修复。这个漏洞影响非常深远,所有组装calldata,利用functionSelector来做路由选择的合约函数都会收到影响。
发现该漏洞可被利用来窃取OpenSea市场上有活跃报价的一部分用户的钱包中的WETH。该漏洞不需要用户采取任何行动就可以利用--某些在过去签署了合法或报价的用户即使没有采取进一步行动,也会面临风险。
Wyvern Listing 包含许多不同的参数,用于指示列表或报价信息,并验证其他参与的智能合约调用,这些参数被汇总到一个单一的承诺中,由用户签署并由合约检查,从而确保只有在用户实际批准列表或报价的情况下才会转移项目。这些参数中有几个是可变长度的,Wyvern 2.2合约(在后来的ABI编码标准之前写的)将它们串联在一起,没有适当的域分离:(拼装calldata)
index = ArrayUtils.unsafeWriteAddress(index, order.target);
index = ArrayUtils.unsafeWriteUint8(index, uint8(order.howToCall));
index = ArrayUtils.unsafeWriteBytes(index, order.calldata);
index = ArrayUtils.unsafeWriteBytes(index,order.replacementPattern);
index = ArrayUtils.unsafeWriteAddress(index, order.staticTarget);
index = ArrayUtils.unsafeWriteBytes(index, order.staticExtradata);
index = ArrayUtils.unsafeWriteAddress(index, order.paymentToken);
在上面实现中,具有不同参数的订单--例如calldata = 0x01和replacementPattern = 0x0101以及calldata = 0x0101和replacementPattern = 0x01--会导致相同的计算承诺。由于这种碰撞,一个聪明的对手可以从一个列表或报价中获取签名,并提出一个不同的列表或报价--没有由用户签署,但导致相同的承诺--这将被智能合约认为是有效的。更具体地说,攻击者可以在order.calldata、order.replacementPattern,staticTarget和order.staticExtradata之间 "转移 "字节,以创建一个具有不同语义的报价或列表,从而产生相同的承诺。

卖家之前签好了一个卖单,签署的原数据可以利用字节偏移,重新解释成意义不同的新订单。调整字节偏移,各字段传到合约里,通过replacementPattern把function selector换掉,举的例子是把转移NFT的方法transferFrom换成getApproved方法,而且最后数据全拼起来order hash与之一致,用户签名依旧有效。另外,getApproved方法是view方法,保证可以成功调用。

这里核心关键是 replacePatter字段换成2进制后,为1的bit位必须包含 标识两个selector差别的 0010 1011 1010 0000 0110 0000 0010 0001这十个比特位,其他位不care,因为mask为1 就是表示从对方那这个数位的结果过来,所以只需要把10个不同的bit的值拿过来就行,其他位因为都相同,拿不拿都一样。
There is a 1 in 1024 chance that a random, 4 byte bitmask has ones in the correct places such that, when applied through the replacementPattern mechanism, the function selector would change from 0x23b872dd to 0x081812fc.
这里1/1024的概率计算,是4个字节32个比特位,要求指定的10个比特位出现1的概率是1/1024。
4个字节其他位都不care,所以指定10个比特位为1的概率,就是2^ 10=1024。
The 4 bytes 0x6bfa60bb in the maker's address, coincidentally, have 1 bits in the places corresponding to the bitwise difference between transferFrom and getApproved.
这里的 1 bits 不是表示1个比特位,是在说所有为1的比特位和表示两个selector不同10个比特位一致。
拿这个表示两个selector比特位区别的 010 1011 1010 0000 0110 0000 0010 0001,去calldata里面去移动匹配,匹配到包含这10个1的位置,进行截取就可以了。
Given that the attacker could shift the replacementPattern to start at any point in the address, the attacker could extract 16 different 4 byte starts to the replacementPattern. This means approximately 1 in 64 offers could have been exploitable.
上文中的1/64的概率,由于to地址是20个字节,selector的mask使用4个字节,所以20个字节可以有17种选择,4个字节概率是1/1024,文中按16种选择算,就是1/64,其实应该是 17/1024,即大约每60个用户就会存在一个用户可以被攻击。
在CallData组装的时候,加上随机Nonce,极大加大用户碰撞calldata的难度。
原文出处:
https://nft.mirror.xyz/VdF3BYwuzXgLrJglw5xF6CHcQfAVbqeJVtueCr4BUzs
审计组和NFT组汇报一个非常重要的安全分享,这里收录一下。背景:一位白帽子发现了opensea一个发现关键的一个合约漏洞,并且已经修复。这个漏洞影响非常深远,所有组装calldata,利用functionSelector来做路由选择的合约函数都会收到影响。
发现该漏洞可被利用来窃取OpenSea市场上有活跃报价的一部分用户的钱包中的WETH。该漏洞不需要用户采取任何行动就可以利用--某些在过去签署了合法或报价的用户即使没有采取进一步行动,也会面临风险。
Wyvern Listing 包含许多不同的参数,用于指示列表或报价信息,并验证其他参与的智能合约调用,这些参数被汇总到一个单一的承诺中,由用户签署并由合约检查,从而确保只有在用户实际批准列表或报价的情况下才会转移项目。这些参数中有几个是可变长度的,Wyvern 2.2合约(在后来的ABI编码标准之前写的)将它们串联在一起,没有适当的域分离:(拼装calldata)
index = ArrayUtils.unsafeWriteAddress(index, order.target);
index = ArrayUtils.unsafeWriteUint8(index, uint8(order.howToCall));
index = ArrayUtils.unsafeWriteBytes(index, order.calldata);
index = ArrayUtils.unsafeWriteBytes(index,order.replacementPattern);
index = ArrayUtils.unsafeWriteAddress(index, order.staticTarget);
index = ArrayUtils.unsafeWriteBytes(index, order.staticExtradata);
index = ArrayUtils.unsafeWriteAddress(index, order.paymentToken);
在上面实现中,具有不同参数的订单--例如calldata = 0x01和replacementPattern = 0x0101以及calldata = 0x0101和replacementPattern = 0x01--会导致相同的计算承诺。由于这种碰撞,一个聪明的对手可以从一个列表或报价中获取签名,并提出一个不同的列表或报价--没有由用户签署,但导致相同的承诺--这将被智能合约认为是有效的。更具体地说,攻击者可以在order.calldata、order.replacementPattern,staticTarget和order.staticExtradata之间 "转移 "字节,以创建一个具有不同语义的报价或列表,从而产生相同的承诺。

卖家之前签好了一个卖单,签署的原数据可以利用字节偏移,重新解释成意义不同的新订单。调整字节偏移,各字段传到合约里,通过replacementPattern把function selector换掉,举的例子是把转移NFT的方法transferFrom换成getApproved方法,而且最后数据全拼起来order hash与之一致,用户签名依旧有效。另外,getApproved方法是view方法,保证可以成功调用。

这里核心关键是 replacePatter字段换成2进制后,为1的bit位必须包含 标识两个selector差别的 0010 1011 1010 0000 0110 0000 0010 0001这十个比特位,其他位不care,因为mask为1 就是表示从对方那这个数位的结果过来,所以只需要把10个不同的bit的值拿过来就行,其他位因为都相同,拿不拿都一样。
There is a 1 in 1024 chance that a random, 4 byte bitmask has ones in the correct places such that, when applied through the replacementPattern mechanism, the function selector would change from 0x23b872dd to 0x081812fc.
这里1/1024的概率计算,是4个字节32个比特位,要求指定的10个比特位出现1的概率是1/1024。
4个字节其他位都不care,所以指定10个比特位为1的概率,就是2^ 10=1024。
The 4 bytes 0x6bfa60bb in the maker's address, coincidentally, have 1 bits in the places corresponding to the bitwise difference between transferFrom and getApproved.
这里的 1 bits 不是表示1个比特位,是在说所有为1的比特位和表示两个selector不同10个比特位一致。
拿这个表示两个selector比特位区别的 010 1011 1010 0000 0110 0000 0010 0001,去calldata里面去移动匹配,匹配到包含这10个1的位置,进行截取就可以了。
Given that the attacker could shift the replacementPattern to start at any point in the address, the attacker could extract 16 different 4 byte starts to the replacementPattern. This means approximately 1 in 64 offers could have been exploitable.
上文中的1/64的概率,由于to地址是20个字节,selector的mask使用4个字节,所以20个字节可以有17种选择,4个字节概率是1/1024,文中按16种选择算,就是1/64,其实应该是 17/1024,即大约每60个用户就会存在一个用户可以被攻击。
在CallData组装的时候,加上随机Nonce,极大加大用户碰撞calldata的难度。
No activity yet