Ethernaut openzeppelin writeup
0xFF 前言
在做jarvisOJ的Crypto时有一道babybank, 看的我是一脸懵逼, 最后了解到这里有一些开源的智能合约的wargame. 于是准备详细了解下这方面的知识.
下边是一些名词解释吧.
智能合约
智能合约简单的说就是就是一串部署在区块链上的代码, 运行于集成在一条区块链系统上集成的虚拟机里, 用来
更详细的智能合约请看这里:
智能合约的脆弱性
我们知道了智能合约就是有人编写的一串程序, 那么就会有漏洞目前已知的包括切不限于:
- 整数溢出
- 逻辑问题
- 越权访问
- 拒绝服务
- 函数误用
- …
一系列问题, 而且因为以太坊自身问题, 合约一旦部署就不能被修改.
eth与gas
eth
ether这个好理解, 就是以太坊上用的RMB.
gas
gas在我的理解里就是类似燃料的东西, 可以通过eth购买, 用户每次执行一个DApp都要支付一定gas, 而支付gas的多少是由DApp的功能逻辑的复杂成的决定的.
因为在以太坊上运行一个程序,要在每个节点都进行相同的运算以验证其输出, 所以为了防止有些用户进行密集型运算占用大量资源,所以以太坊的创建者为以太坊伤的资源限制了价格.
solidity
solidity是以太坊的智能合约变成语言, 在对智能合约脆弱性进行攻击之前我们需要先了解一些关于solidity的基础知识.
这里我推荐官方文档、或者这个小游戏cryptozombies.
0x0 level 0
这一关只是一些基础知识,教我们这些没接触过Ethernaut的人使用方式.还有一些常用命令:
1 | player // 查看地址 |
没什么难点,跟着一路点就行了.
点击
Get new instance
开始游戏执行
await contract.info()
-> “You will find what you need in info1().”执行
await contract.info1()
-> “Try info2(), but with “hello” as a parameter.”执行
await contract.info2("hello")
-> “The property infoNum holds the number of the next info method to call.”执行
await contract.infoNum()
-> 查看数组发现下个方法1
2
3
4
5
6
7
8
9await contract.infoNum()
t {s: 1, e: 1, c: Array(1)}
c: Array(1)
0: 42
length: 1
__proto__: Array(0)
e: 1
s: 1
__proto__: Object执行
await contract.info42()
-> “theMethodName is the name of the next method.”执行
await contract.theMethodName()
-> “The method name is method7123949.”执行
await contract.method7123949()
-> “If you know the password, submit it to authenticate().”提示要获取密码查看智能合约的abi发现:
1
2
3
4
5
6
7
8
9
10
11
12
13contract.abi
(11) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {constant: true, inputs: Array(0), name: "password", outputs: Array(1), payable: false, …}
1: {constant: true, inputs: Array(0), name: "infoNum", outputs: Array(1), payable: false, …}
2: {constant: true, inputs: Array(0), name: "theMethodName", outputs: Array(1), payable: false, …}
3: {inputs: Array(1), payable: false, stateMutability: "nonpayable", type: "constructor"}
4: {constant: true, inputs: Array(0), name: "info", outputs: Array(1), payable: false, …}
5: {constant: true, inputs: Array(0), name: "info1", outputs: Array(1), payable: false, …}
6: {constant: true, inputs: Array(1), name: "info2", outputs: Array(1), payable: false, …}
7: {constant: true, inputs: Array(0), name: "info42", outputs: Array(1), payable: false, …}
8: {constant: true, inputs: Array(0), name: "method7123949", outputs: Array(1), payable: false, …}
9: {constant: false, inputs: Array(1), name: "authenticate", outputs: Array(0), payable: false, …}
10: {constant: true, inputs: Array(0), name: "getCleared", outputs: Array(1), payable: false, …}发现password()方法,调用之
await contract.password()
-> “ethernaut0”
将之使用authenticate()方法发送.
await contract.authenticate("ethernaut0")
转账之后等一会,会发现
Submit instance
完成level0