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
2
3
4
player // 查看地址
await getBalance(player) //查看余额
ethernaut //查看ethernaut智能合约,这是这个game的主要使用的合约
await ethernaut.owner() // 查看ethernaut合约的所有者

没什么难点,跟着一路点就行了.

  1. 点击Get new instance开始游戏

  2. 执行await contract.info()
    -> “You will find what you need in info1().”

  3. 执行await contract.info1()
    -> “Try info2(), but with “hello” as a parameter.”

  4. 执行await contract.info2("hello")
    -> “The property infoNum holds the number of the next info method to call.”

  5. 执行await contract.infoNum()
    -> 查看数组发现下个方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    await 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
  6. 执行await contract.info42()
    -> “theMethodName is the name of the next method.”

  7. 执行await contract.theMethodName()
    -> “The method name is method7123949.”

  8. 执行await contract.method7123949()
    -> “If you know the password, submit it to authenticate().”

  9. 提示要获取密码查看智能合约的abi发现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    contract.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")

  10. 转账之后等一会,会发现Submit instance完成level0

0x1 fallback