抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

MagicNumber

1. 题目要求

  • 1.1 To solve this level, you only need to provide the Ethernaut with a Solver, a contract that responds to whatIsTheMeaningOfLife() with the right number.

    Easy right? Well… there’s a catch.

    The solver’s code needs to be really tiny. Really reaaaaaallly tiny. Like freakin’ really really itty-bitty tiny: 10 opcodes at most.

    Hint: Perhaps its time to leave the comfort of the Solidity compiler momentarily, and build this one by hand O_o. That’s right: Raw EVM bytecode.

    Good luck

  • 1.2 译:要解决这个关卡,你只需要向 Ethernaut 提供一个,一个用正确的数字Solver响应的合约。whatIsTheMeaningOfLife()

    简单吧?嗯…有一个问题。

    求解器的代码需要非常小。真的很小。就像 freakin’ really really itty-bitty tiny:最多 10 个操作码。

    提示:也许是时候暂时离开 Solidity 编译器的舒适环境,并手动构建这个 O_o。没错:原始 EVM 字节码。

    祝你好运!

  • 1.3 题目代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MagicNum {

address public solver;

constructor() {}

function setSolver(address _solver) public {
solver = _solver;
}

/*
____________/\\\_______/\\\\\\\\\_____
__________/\\\\\_____/\\\///////\\\___
________/\\\/\\\____\///______\//\\\__
______/\\\/\/\\\______________/\\\/___
____/\\\/__\/\\\___________/\\\//_____
__/\\\\\\\\\\\\\\\\_____/\\\//________
_\///////////\\\//____/\\\/___________
___________\/\\\_____/\\\\\\\\\\\\\\\_
___________\///_____\///////////////__
*/
}

-

2. 分析

tips: 参考博客

  • 2.1有一个在调用时whatIsTheMeaningOfLife应答0x000000000000000000000000000000000000000000000000000000000000002a(bytes32) 的函数。这是十进制的 42 的十六进制转换。2)我们的合约代码必须小于10字节

    这些要求似乎无法实现,即使使用原始字节码来定义函数、处理函数选择器等,也将远远超过 10 字节的代码。

    但是我们真的需要有那个功能吗?最后,我们必须塑造合约代码才能通过挑战。如果我们的合同,无论它如何执行,返回42怎么办?

    这就是诀窍!如果你认为它就像拥有一个 Solidity 智能合约而不是只有一个fallback函数,那么无论你尝试低级调用哪个函数,它都将始终且只执行该fallback函数。

  • 2.2 现在我们需要部署我们刚刚在上一节中编写的最小合约。当一个智能合约被创建时(via CREATEor CREATE2opcode),EVM 会执行一次构造函数代码,并且部署的智能合约的代码会被 opcode 返回RETURN(这个返回的代码称为运行时代码,它是将要执行的代码当您与智能合约交互时)

  • 参考视频 写的攻击合约:

1
2
3
4
5
6
7
8
9
10
11
12
13
contract Hack {
constructor(MagicNum target) {
bytes memory bytecode = hex"69602a60005260206000f3600052600a6016f3";
address addr;
assembly {
addr := create(0, add(bytecode, 0x20), 0x13)
}

require(addr != address(0));
target.setSolver(addr);

}
}

3. 解题

  • 3.1 获取关卡实例地址:0x5072f4af6D9B0907833C43b199000347158f685d
  • 3.2 传入实例地址部署攻击合约
  • image-20230225145738845
  • 3.3 提交实例
  • image-20230225145824963
  • 3.4 成功!!!!

评论



政策 · 统计 | 本站使用 Volantis 主题设计