第 2 章 | 智能合约攻击图谱全景解析

🗺 第 2 章 | 智能合约攻击图谱全景解析

——建立审计者思维的第一步,是构建一张完整的攻击路径地图


✅ 引言:攻击者不是“写错了”,而是“看穿你写错了”

智能合约是区块链上的核心执行体,它不像传统 Web 应用那样可以修补、热更新或下线回滚。
合约一旦部署,逻辑就是永久的,资产就是实时绑定的。

在主网上线的每一秒,都可能被数千个自动化 Bot 和黑客脚本实时监控。
作为开发者或审计者,我们必须清楚——攻击从不来自语法错误,而来自设计逻辑上的漏洞。

因此在进入具体的漏洞分析之前,我们必须建立一张清晰的「攻击图谱」。


🧭 攻击图谱分类结构

我们将攻击行为从技术维度系统拆解为7 大类攻击类型,每类都对应不同的攻击目标、原理、执行路径与防御策略。

攻击类型攻击目标原理简述常见案例
1. 重入攻击状态变量一致性外部合约回调,合约状态未及时更新The DAO / dForce
2. 权限控制失效管理权 / 控制权不正确的权限修饰符或初始化逻辑bZx / Parity Wallet
3. 计算精度错误资产数值失控整数溢出 / 精度误差 / 运算顺序不当YAM / Balancer
4. 预言机操控定价机制失效操控喂价合约、操作池子数据导致数据偏差Mango / Harvest
5. 外部依赖风险链下数据引爆对外部系统(VRF、Oracle、合约)信任过高Synthetix / Chainlink 滥用
6. 升级/代理缺陷存储/逻辑错乱Proxy 存储布局错位、delegatecall 滥用Curve / OpenZeppelin 示例
7. 部署初始化默认状态攻击合约部署时未初始化、未锁权限Parity 多签 / Ownable 未设置

接下来我们详细讲解每一类攻击:


🧨 1. 重入攻击(Reentrancy)

✅ 原理

当合约向外部地址发送 ETH(如使用 call{value:}),如果该地址是合约,它的 receive()fallback() 函数可能在状态变量尚未更新前重新调用原合约,从而达到反复操作未锁状态的目的。

✅ 攻击目标

  • 多次提款

  • 重复 mint

  • 多轮 claim 奖励

✅ 攻击路径(调用栈视角)

User.withdraw()→ msg.sender.call{value: X}()→ AttackContract.fallback()→ 再次调用 withdraw()→ msg.sender.call{value: X}()... 循环直到提款耗尽

✅ 真实案例

  • The DAO(2016):攻击者反复调用提款逻辑,提走 30% 资金

  • dForce(2020):重入 USDT 合约,绕过冻结检查

✅ 防御措施

  • 状态变量更新应在外部调用之前(Checks-Effects-Interactions)

  • 使用 ReentrancyGuard 修饰器封锁再次进入

  • 引入 pull-payment 模式,将提款推迟执行


🔐 2. 权限控制失效

✅ 原理

  • 使用不安全的权限验证(如 tx.origin

  • 未使用修饰符限制关键函数(如 mint、pause)

  • 构造函数命名错误或未正确初始化所有者

✅ 攻击方式

  • 攻击者部署恶意合约诱导用户转账 → 利用 tx.origin 拿到控制权

  • 直接调用 initialize() → 抢占 owner

  • 提案治理中嵌入恶意逻辑 → 偷权+转钱

✅ 案例

  • Parity Wallet 多签:初始化函数未锁,被恶意调用 selfdestruct

  • bZx 协议:权限管理错误 → 任意提资产、变更参数

✅ 防御措施

  • 永远使用 msg.sender 进行权限判断

  • 初始化函数设置 onlyInitializing + initializer 修饰器

  • 使用 OpenZeppelin Ownable / AccessControl 系统化权限设计

  • 所有关键操作需 onlyOwner / 多签控制


📉 3. 精度问题与整数溢出(Overflow / Underflow)

✅ 原理

Solidity 中整数类型有固定大小(如 uint256),0.8.0 版本后默认开启溢出检测,但开发者仍需注意以下风险:

  • 多次乘法后除法顺序错误

  • 精度不足导致错误资产分配

  • 未考虑 decimals 精度混乱问题

✅ 案例

  • YAM Protocol:指数增长逻辑整数溢出,失败后治理无法提案修复

  • Balancer 池:处理复利时精度误差导致套利空间

✅ 防御措施

  • 避免复杂嵌套计算,提取中间变量

  • 所有合约中统一使用 18 decimals 资产表示

  • 对分配型计算使用 x.mul(y).div(z) 顺序

  • 高精度逻辑使用 FixedPointMathLib


📡 4. 预言机操控攻击(Oracle Manipulation)

✅ 原理

项目方常通过链上池或外部合约获取 Token 定价。但若该数据源可以被操控(如通过闪电贷调控池子余额),则可以恶意操控价格。

✅ 攻击方式

  • 利用 flashloan 操纵流动性池价格

  • 通过低流动性 token 偏移 AMM 报价

  • 喂价合约允许任何账户更新价格

✅ 案例

  • Mango Markets:攻击者操控账户资产价值,借出大量无抵押 USDC

  • Harvest Finance:反复操纵价格后套利提走资产

✅ 防御措施

  • 使用 Chainlink 等去中心化预言机

  • 采用时间加权平均价格(TWAP)而非即时价格

  • 引入价格上限/滑点保护机制


🧬 5. 外部依赖不可信(VRF / 其他合约)

✅ 原理

当合约依赖第三方数据(如 VRF 随机数、链上喂价合约、Oracle),一旦这些依赖合约被替换、暂停或被操控,可能间接引发攻击。

✅ 攻击方式

  • 合约逻辑调用 VRF,但未校验 requestID 匹配

  • 合约过度信任 msg.sender == oracle

  • VRF 合约部署者本身恶意更改返回值

✅ 案例

  • Uniswap 早期流动性挖矿项目暴露对外部状态的信任问题

  • NFT 盲盒开奖使用 block.timestamp 导致可预测性

✅ 防御建议

  • 所有 VRF / Oracle 接口应校验请求方 ID

  • 外部依赖合约需白名单化 & 定期审计

  • 异步逻辑增加 nonces 校验,避免 replay


🏗 6. 升级代理机制漏洞

✅ 原理

使用代理合约(如 UUPS / Transparent Proxy)时,合约存储 layout 必须一致,否则 delegatecall 会将逻辑合约的存储与 proxy 的存储结构打乱,造成严重逻辑错乱。

✅ 攻击方式

  • 升级合约后变量 slot 错位 → 权限丢失

  • 代理合约错误设置 implementation 地址 → 调用错误逻辑

  • initialize() 可被重复调用 → 权限重设

✅ 案例

  • Curve 使用 Vyper 编译版本兼容性错误导致 pool 实现合约变量错位

  • 多个项目在使用 UUPS 时遗漏 upgrade 安全性判断

✅ 防御建议

  • 使用 OpenZeppelin 官方推荐升级模式

  • 定义 __gap 预留 slot 空间

  • 所有可升级合约必须测试覆盖 initialize + 升级后状态验证

  • 增设 onlyProxy 校验逻辑


🚨 7. 部署初始化错误

✅ 原理

部署完成后,若初始化逻辑未被锁定,攻击者可调用 initialize()setOwner() 等函数,接管合约或进行恶意操作。

✅ 案例

  • Parity Wallet:初始化未调用,被恶意初始化+销毁

  • 合约部署后未设置 onlyOwner,结果任意人调用 mint() 铸币

✅ 防御建议

  • 使用 OpenZeppelin initializer 修饰器

  • 所有初始化函数加部署时自动调用逻辑

  • 合约上线前进行 Etherscan 验证 + read/write 调试验证状态变量是否写入


✅ 本章总结

  • 所有攻击行为,均可归类为 7 大路径

  • 每类攻击都有其“漏洞模式” + “触发机制” + “利用路径”

  • 审计者不是死盯语法,而是系统构建“攻击地图”+“风险断点链”

  • 后续章节将逐一拆解每类攻击,配合复现合约、修复对比、Gas 成本分析


🧪 课后建议

  1. 回顾你最近写过的合约,尝试对照这 7 类做一次 checklist 风险扫描

  2. 安装并运行 slither 对项目进行静态分析:

npm install -g slither-analyzer
slither ./
  1. 用图形工具画出你项目的权限调用链
    (例如:谁能 mint → 谁能 transferOwnership → 谁能 call sensitive 函数)


✅ 下一章预告|第 3 章:重入攻击 Reentrancy 全解析

👉 合约提款逻辑里隐藏的死亡递归
👉 攻击合约复现 The DAO 闪崩事件
👉 3 种修复方案 + 防御对比 + 代码演练


🧠 从下一章开始,我们将进入真正的安全攻防实战训练阶段。
你将开始写出“漏洞合约”、部署“攻击者合约”、复现真实链上攻击路径。

你准备好从开发者,转变为具备黑客视角的审计工程师了吗?

我们下一章正式开战。🔥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41379.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.4 模拟专题:LeetCode1419.数青蛙

1.题目链接:数青蛙 - LeetCode 2.题目描述 给定一个字符串 croakOfFrogs,表示青蛙的鸣叫声序列。每个青蛙必须按顺序发出完整的 “croak” 字符,且多只青蛙可以同时鸣叫。要求计算最少需要多少只青蛙才能完成该字符串,若无法完成…

Linux 搭建dns主域解析,和反向解析

#!/bin/bash # DNS主域名服务 # user li 20250325# 检查当前用户是否为root用户 # 因为配置DNS服务通常需要较高的权限,只有root用户才能进行一些关键操作 if [ "$USER" ! "root" ]; then# 如果不是root用户,输出错误信息echo "…

Leetcode 二进制求和

java solution class Solution {public String addBinary(String a, String b) {StringBuilder result new StringBuilder();//首先设置2个指针, 从右往左处理int i a.length() - 1;int j b.length() - 1;int carry 0; //设置进位标志位//从2个字符串的末尾向前遍历while(…

【NLP 49、提示工程 prompt engineering】

目录 一、基本介绍 语言模型生成文本的基本特点 提示工程 prompt engineering 提示工程的优势 使用注意事项 ① 安全问题 ② 可信度问题 ③ 时效性与专业性 二、应用场景 能 ≠ 适合 应用场景 —— 百科知识 应用场景 —— 写文案 应用场景 —— 解释 / 编写…

【NLP 43、文本生成任务】

目录 一、生成式任务 二、seq2seq任务 1.模型结构 2.工作原理 3.局限性 三、自回归语言模型训练 Decoder only 四、自回归模型结构:文本生成任务 —— Embedding LSTM 代码示例 🚀 数据文件 代码流程 Ⅰ、模型初始化 Ⅱ、前向计算 代码运行流程 Ⅲ、加载…

vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu

vscode 通过Remote-ssh插件远程连接服务器报错 could not establish connection to ubuntu,并且出现下面的错误打印: [21:00:57.307] Log Level: 2 [21:00:57.350] SSH Resolver called for "ssh-remoteubuntu", attempt 1 [21:00:57.359] r…

Linux之编辑器vim命令

vi/vim命令: 终端下编辑文件的首选工具,号称编辑器之神 基本上分为三种模式,分别是 命令模式(command mode)>输入vi的命令和快捷键,默认打开文件的时候的模式插入模式(insert mode&#x…

第一天学爬虫

阅读提示:我今天才开始尝试爬虫,写的不好请见谅。 一、准备工具 requests库:发送HTTP请求并获取网页内容。BeautifulSoup库:解析HTML页面并提取数据。pandas库:保存抓取到的数据到CSV文件中。 二、爬取步骤 发送请求…

MySQL实战(尚硅谷)

要求 代码 # 准备数据 CREATE DATABASE IF NOT EXISTS company;USE company;CREATE TABLE IF NOT EXISTS employees(employee_id INT PRIMARY KEY,first_name VARCHAR(50),last_name VARCHAR(50),department_id INT );DESC employees;CREATE TABLE IF NOT EXISTS departments…

windows下安装sublime

sublime4 alpha 4098 版本 下载 可以根据待破解的版本选择下载 https://www.sublimetext.com/dev crack alpha4098 的licence 在----- BEGIN LICENSE ----- TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA12C0 A37081C5 D0316412 4584D…

激光线检测算法的FPGA实现

激光线检测算法的FPGA实现 1. 常见的激光线检测算法 激光线检测中常用的三种算法 MAX(最大值法)、THRESH(阈值法)、COG(灰度重心法) 分别具有以下特点和工作原理: 1.1 MAX(最大值法…

小样本微调大模型

一、环境搭建 conda create -n dseek python=3.10 conda activate dseek pip install bitsandbytes Pip install numpy python -m pip install --upgrade pip setuptools wheel 安装cuda,torch,Unsloth, huggingface,wandb等,见前述章节; 微调服务器配置:单机笔记本显卡4…

深入理解指针(2)(C语言版)

文章目录 前言一、数组名的理解二、使用指针访问数组三、一维数组传参的本质四、冒泡排序五、二级指针六、指针数组七、指针数组模拟二维数组总结 前言 在上一篇文章中,我们初步了解了指针的基本概念和用法。今天,我们将继续深入探索指针在数组、函数传…

高效内存管理:x86-64架构中的分页机制

在 x86-64 架构的世界里,内存分页机制扮演着举足轻重的角色,它就像是一座桥梁,连接着虚拟地址与物理地址。简单来说,内存分页机制就是将线性地址(也就是虚拟地址)切分成一个个固定大小的页,并把…

统一开放世界与开放词汇检测:YOLO-UniOW无需增量学习的高效通用开放世界目标检测框架

目录 一、摘要 二、引言 三、相关工作 开放词汇对象检测 开放世界目标检测 参数高效学习 四、高效通用的开放世界目标检测 问题定义 高效的自适应决策学习 开放世界通配符学习 五、Coovally AI模型训练与应用平台 六、实验 数据集 评价指标 实施细节 定量结果 …

fileinclude

##解题思路 场景首页没有什么提示,只有个flag在flag.php中,而且需要更改language,还有个index.php的路径,先记住它 习惯性查看源代码,得到了题目真正的内容,关键在于lan变量读取我们传入的Cookie值中的lang…

链表-LeetCode

这里写目录标题 1 排序链表1.1 插入法 O(n)1.2 归并排序 1 排序链表 1.1 插入法 O(n) /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullpt…

计算机网络基础:WiFi 与蓝牙的原理与应用

计算机网络基础:WiFi 与蓝牙的原理与应用 一、前言二、WiFi 原理2.1 概述2.2 工作频段2.2.1 2.4GHz 频段2.2.2 5GHz 频段2.3 调制技术2.3.1 正交频分复用(OFDM)2.3.2 直接序列扩频(DSSS)2.4 通信协议2.5 网络架构2.5.1 独立基本服务集(IBSS)2.5.2 基础服务集(BSS)2.5.…

深入解析 Java 类加载机制及双亲委派模型

🔍 Java的类加载机制是确保应用程序正确运行的基础,特别是双亲委派模型,它通过父类加载器逐层加载类,避免冲突和重复加载。但在某些特殊场景下,破坏双亲委派模型会带来意想不到的效果。本文将深入解析Java类加载机制、…

【数据可视化艺术·进阶篇】热力图探秘:用色彩演绎场馆和景区的人流奥秘

假期出游,你是不是也遇到过这样的状况:想去的热门景点,放眼望去全是攒动的人头,根本没法好好欣赏风景;而景区里一些小众角落,却冷冷清清,鲜有人至。还有在轨道交通枢纽、大型体育场这些地方&…