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

Ethernaut Level 11: Elevator - 接口实现攻击

🎯 Ethernaut Level 11: Elevator - 接口实现攻击

关卡链接: Ethernaut Level 11 - Elevator
攻击类型: 接口实现攻击
难度: ⭐⭐⭐☆☆

📋 挑战目标

目的是使电梯达到最顶层,即使题目合约的 toptrue。关键在于理解接口定义与实际实现的差别,以及如何利用这个差别进行攻击。

请添加图片描述

🔍 漏洞分析

接口的安全风险

本关卡重在考验我们对智能合约接口的认知程度:

  • 接口定义函数签名,但不定义它们的逻辑
  • 这是一种无需知道实现细节就可以与其他合约交互的方法
  • 但也意味着攻击者可以控制接口的实现逻辑

关键漏洞代码

function goTo(uint _floor) public {Building building = Building(msg.sender);if (!building.isLastFloor(_floor)) {floor = _floor;top = building.isLastFloor(floor);  // 第二次调用!}
}

攻击向量

goTo 函数中,isLastFloor 被调用两次:

  1. 第一次调用:必须返回 false,否则无法进入修改 top 的逻辑
  2. 第二次调用:我们可以让它返回 true 来设置 top = true

我们可以通过创建一个 isLastFloor() 来利用这一点,它将第一次返回 false,第二次返回 true

💻 Foundry 实现

攻击合约代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;import "forge-std/Test.sol";
import "../src/Ethernaut.sol";
import "../src/levels/ElevatorFactory.sol";interface Building {function isLastFloor(uint) external returns (bool);
}contract ElevatorAttacker is Building {Elevator instance;bool top = false;constructor(address _elevator) {instance = Elevator(_elevator);}// 关键:状态变化的接口实现function isLastFloor(uint _floor) external override returns (bool) {top = !top;  // 第一次调用时 top 变为 true,第二次变为 falsereturn !top; // 第一次返回 false,第二次返回 true}function attack(uint _floor) public {instance.goTo(_floor);}
}contract ElevatorTest is Test {Ethernaut ethernaut;ElevatorFactory elevatorFactory;function setUp() public {ethernaut = new Ethernaut();elevatorFactory = new ElevatorFactory();ethernaut.registerLevel(elevatorFactory);}function testElevatorExploit() public {// 创建关卡实例address levelInstance = ethernaut.createLevelInstance(elevatorFactory);Elevator instance = Elevator(levelInstance);// 检查初始状态assertEq(instance.top(), false);assertEq(instance.floor(), 0);// 部署攻击合约ElevatorAttacker attacker = new ElevatorAttacker(levelInstance);// 执行攻击attacker.attack(1);// 验证攻击成功assertEq(instance.top(), true);assertEq(instance.floor(), 1);// 提交关卡bool levelSuccessfullyPassed = ethernaut.submitLevelInstance(payable(levelInstance));assert(levelSuccessfullyPassed);}
}

关键攻击步骤

  1. 实现 Building 接口:创建一个合约实现 Building 接口
  2. 状态变化逻辑:在 isLastFloor() 中实现状态变化
  3. 调用 goTo 函数:通过攻击合约调用 goTo()
  4. 验证结果:检查 top 是否为 true
// 状态变化的关键实现
function isLastFloor(uint _floor) external override returns (bool) {top = !top;  // 切换状态return !top; // 第一次返回 false,第二次返回 true
}

🛡️ 防御措施

1. 避免多次调用外部函数

// ❌ 不安全:多次调用外部函数
contract VulnerableElevator {function goTo(uint _floor) public {Building building = Building(msg.sender);if (!building.isLastFloor(_floor)) {  // 第一次调用floor = _floor;top = building.isLastFloor(floor);  // 第二次调用!}}
}// ✅ 安全:只调用一次并缓存结果
contract SecureElevator {function goTo(uint _floor) public {Building building = Building(msg.sender);bool isLast = building.isLastFloor(_floor);  // 只调用一次if (!isLast) {floor = _floor;top = isLast;  // 使用缓存的结果}}
}

2. 使用 view 函数

// ✅ 使用 view 函数防止状态改变
interface Building {function isLastFloor(uint) external view returns (bool);  // view 修饰符
}contract SecureElevator {function goTo(uint _floor) public {Building building = Building(msg.sender);if (!building.isLastFloor(_floor)) {floor = _floor;top = building.isLastFloor(floor);  // view 函数保证一致性}}
}

3. 使用白名单机制

contract SecureElevator {mapping(address => bool) public approvedBuildings;address public owner;modifier onlyApprovedBuilding() {require(approvedBuildings[msg.sender], "Unauthorized building");_;}function addApprovedBuilding(address building) public {require(msg.sender == owner);approvedBuildings[building] = true;}function goTo(uint _floor) public onlyApprovedBuilding {// 安全逻辑}
}

4. 实现内部逻辑

contract SecureElevator {uint public floor;bool public top;uint public topFloor = 10;  // 定义最高层function goTo(uint _floor) public {require(_floor <= topFloor, "Floor too high");floor = _floor;top = (_floor == topFloor);  // 内部判断逻辑}
}

🔧 相关工具和技术

接口安全检测

// 检测接口实现的一致性
contract InterfaceChecker {function checkConsistency(address building, uint floor) public {Building b = Building(building);// 多次调用检查一致性bool result1 = b.isLastFloor(floor);bool result2 = b.isLastFloor(floor);require(result1 == result2, "Inconsistent interface implementation");}
}

合约分析工具

# 使用 Slither 检测接口安全问题
slither . --detect external-function# 使用 Mythril 分析
Myth analyze <contract.sol> --execution-timeout 60

🎯 总结

核心概念:

  • 接口是一种无需知道实现细节就可以与其他合约交互的方式
  • 但永远不要盲目相信它们!
  • 多次调用外部函数可能产生不一致的结果

攻击向量:

  • 实现恶意的接口逻辑
  • 利用多次调用之间的状态变化
  • 操纵函数返回值以达到攻击目的

防御策略:

  • 只调用一次外部函数并缓存结果
  • 使用 view 函数修饰符防止状态改变
  • 实现白名单机制控制访问
  • 尽可能使用内部逻辑而不依赖外部实现

🔗 相关链接

  • 原文
  • GitHub 项目

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

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

相关文章:

  • 恶意软件行为图像数据集
  • 如何找到网站管理员做房产应看的网站
  • 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 的对比
  • 量化交易的思维导图
  • 商城网站建设框架网站有哪些