前言
- 第四届
qwb
线下赛EGM
赛题WP
- 考点是 Return Oriented Programming
- 借用工具
ida-evm
反汇编辅助分析 - 也可借助在线工具 https://www.trustlook.com/services/smart.html 反编译辅助分析
Source
1 | 6210000060405260043610610073576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638d715d9d1461024557806360fe47b11461031a5780636d4ce63c1461035557806335f4699414610372578063b4a99a4e1461038157610073565b610078565b600080fd600060006000600060005b61012061010052565b6101005190565b60206101005101806101005252565b6101005151602061010051036101005290565b61010052565b6100ca610100516100975b565b565b6100d66100a6565b6100de6100a6565b6100e7906100b9565b565b6100f1610087565b565b34156100cc57610078565b6101086000610097565b5b7f01000000000000000000000000000000000000000000000000000000000000006101005151602061010051035101510415610152575b60016101005151016101005152610109565b61015a6100a6565b6101626100a6565b506100ce565b6101726000610097565b5b6020610100510351610100515103156101d9577f0100000000000000000000000000000000000000000000000000000000000000610100515160606101005103510151046101005151604061010051035101535b60016101005151016101005152610173565b60006101005151604061010051035101535b60406101005151061561021c5760006101005151604061010051035101535b600161010051510161010051526101eb565b6102246100a6565b5061022d6100a6565b506102366100a6565b5061023f6100a6565b506100ce565b61024d6100e9565b6102576000610097565b610100516102656212345650565b36602462013000376102756100bf565b61028061034f610097565b61028c62013000610097565b61029581610097565b6102a160243603610097565b610168565b6102ae6100bf565b6102b96102c7610097565b6102c281610097565b6100fe565b6020610100510381602060408303526020820352602060208203510660208203510360200160400160408203f35b602061010051035161010051515561030b6100a6565b506103146100a6565b506100ce565b6103226100f3565b61032a6100bf565b61033561034f610097565b610340600435610097565b61034a6000610097565b6102f5565b60006000f35b61035d6100f3565b60005433146100785760005460805260206080f35b60665433141561007857606654ff5b6066543314156100785733606655005b505050505050505050505050505050505050505050505050505050505050505050505050505050 |
Analyse
1 | contract disassembler { |
- 根据上面反编译结果及其
ida-evm
具体分析一下可以得到下面的伪代码
1 | function get() public returns (address) { |
- 根据反编译结果及其
ida-evm
具体分析set
函数和Backdoor
函数,可发现其利用mem
实现了类堆栈操作,可总结如下:
1 | function stack_push(uint256 value) private { |
- 其中我们要使
set
对应的堆栈如下
1 | -------------------------------- |
Backdoor
对应的堆栈如下
1 | ---------------------------------- |
- 当调用
Backdoor
时,它会将msg.data[0x24:]
复制到内存[0x140]
中。 这意味着如果我们的消息长于0x20
字节,它将破坏堆栈,然后覆盖返回地址,以此类推。Backdoor
中将payload
复制到内存[0x13000]
中。 因此,我们可以简单地更新堆栈帧指针,并使其指向我们的堆栈所在的0x13000
处 - 我们需要对
Backdoor
进行调用,msg.data[0x24:]
后的数据每0x20
长度为一个单位,先是一个单位的0
填充0x140
位置,接着两个单位覆盖堆栈帧指针和返回地址。总的msg.data
长度为0x164
字节,所以msg.data[24:]
长度为0x140
字节,所以假堆栈帧指针指向0x13120
。根据set_ss
所在的位置,使用0x2f5
作为返回位置。因为payload
是一次一个字节复制到mem
中,所以在覆盖接下来的四个单位时需要注意:前三个是静态值,第四个是动态值(需要注意,此时的第三个单位要按照0x40
长度对齐,所以第三个单位是0x140
),此时payload
如下所示:
1 | data = '0x8d715d9d' |
- 最后,可以构造
set_ss
,并使用其对堆栈进行读取操作。首先指定set_ss
的返回地址为0x34f
能够正常结束;然后,指定要写入存储的值;最后指定要写入的存储槽0x66
1 | 000000000000000000000000000000000000000000000000000000000000034f |
- 所以,总的
payload
如下所示:
1 | data = '0x8d715d9d' |
- 最后调用
die
即可
Exp
1 | from web3 import Web3, HTTPProvider |