Skip to content

Commit 6f77461

Browse files
committed
Add study notes for 2025-08-20
1 parent ce862f3 commit 6f77461

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

Cauliweak9.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,41 @@ timezone: UTC+8
1515
## Notes
1616

1717
<!-- Content_START -->
18+
# 2025-08-20
19+
20+
昨天开摆了,今天也想摆,水道题吧,前几天LilCTF的区块链题目“生蚝的宝藏”
21+
22+
> 其实放题当天中午12点半就做出来了(因为在线下坐牢没事干),不过因为是借的别人的靶机打的所以也就没交(借我靶机的是我学弟,他没有提交本题flag,因此不存在影响比赛公平性的情况)
23+
24+
简单来说就是通过Ethereum JSON-RPC API获取指定合约的Runtime Bytecode,然后反编译进行逆向分析(Dedaub我的神),基本上扔给AI都能知道是进行了一次异或操作,而异或操作可逆,所以找到key和密文就行了
25+
26+
密文好找:直接根据动态数组在Storage的存储方式去读就行了(没记错的话index是固定的0x5d);而key作为constant不是很好读,好在Dedaub能搞出TAC(Three Address Code),里面能搞到key,直接异或然后调用验证函数就行了
27+
28+
具体的Writeup可以自行去官方Writeup([Docs](https://lil-house.feishu.cn/wiki/N7EIwqpoEiVngqkV8rzcgPB9nPg))中查看,此处就不过多赘述了
29+
30+
---
31+
32+
OK,以上为预期解,接下来就来到我们的非预期解时间~
33+
34+
> 可能有人会觉得有点事后诸葛亮的成分在,我也是在预期解完成本题后才发现的非预期,不过这里还是写上吧
35+
> 此处使用`ciphertext`指代存放在数组中的密文,`encrypt()`指代完整的异或加密函数
36+
37+
反编译啥的不能省,但是我们可以发现验证函数的逻辑是比对`keccak256(ciphertext)``keccak256(encrypt(input))`这两者,而`ciphertext`是在`constructor(string memory initializetext)`中通过`encrypt(initializetext)`得到的,因此我们的目标就发生了偏移:我们不需要知道`encrypt`具体在干啥,我们只需要知道`constructor`传入了什么就行
38+
39+
题目很贴心地给了合约创建的txn hash,因此我们可以直接读取交易的完整数据:`cast rpc eth_getTransactionByHash 0xtx_hash -r http://106.15.138.99:8545`
40+
41+
最后得到的数据就是完整的合约字节码,包括Constructor Bytecode和Runtime Bytecode,除此之外**最后面是传入`constructor`的参数值**,也正是我们想要的东西(这里给出我当时做题时得到的snippet):
42+
43+
```
44+
...600052601160045260246000fd5b506001019056fea264697066735822122021ebf24dde1fd17fcdd77fedee95a480bc9861c8c6717cb4263cf1512b7e7bc464736f6c634300080900330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002e34353431333534383435343933313566353536653634333337323566373434383435356637333333343033663764000000000000000000000000000000000000
45+
```
46+
47+
最后这段很明显是一个`string memory`的类型,其中`2e`表示了string的长度,后面的就是传入的string,因此我们直接把字符串传进验证函数里就行了
48+
49+
由此我们可以发现,区块链的公开性对于这类题型的摧毁还是挺大的,很多情况都能找到一种“奇技淫巧”脱离出题人的预期解,果然出题时还得好好预防这方面的操作
50+
51+
总的来说作为中等难度还算OK,只是一开始啥源码都不给这一点确实拦住了很多人,很庆幸当时很迅速地做出了直接使用cast获取字节码这一操作,节省了很多无用时间
52+
1853
# 2025-08-18
1954

2055
摸鱼,随便写点

0 commit comments

Comments
 (0)