-
审计:是对项目代码库的外部安全评估,通常由项目团队提出请求并付费
- 它检测并描述(在报告中)具有潜在漏洞、严重性/难度、潜在漏洞场景和建议的修复措施的安全问题。
- 它还提供了对代码质量、文档和测试的主观见解。
- 不同的审计团队的审计报告的范围/深度/格式各不相同,但通常涵盖相似的方面。
-
审计范围:对于基于以太坊的智能合约项目,范围通常是链上智能合约代码,有时还包括与智能合约交互的链下组件。
-
审计目标:审计的目标是评估项目代码(以及任何相关规范、文档)并提醒项目团队(通常在启动之前)注意需要解决的潜在安全相关问题,以改善安全态势、减少攻击面并降低风险。
-
审计非目标:无论如何,审计_都不是_“无错误”代码的安全保障,而是由经过培训的安全专家在合理的时间、理解、专业知识和可判定性限制内尽最大努力的结果。
-
审计目标:安全公司为付费客户执行审计。因此,审计工作面向项目所有者而非项目用户/投资者的优先事项_。_审计并非_旨在_提醒潜在项目用户注意任何固有风险。这不是他们的业务/技术目标。
-
审计需求:基于智能合约的项目没有足够的内部以太坊智能合约安全专业知识和/或时间来进行内部安全评估,因此依赖于在这些领域拥有专业知识的外部专家。即使项目内部有一些专业知识,他们仍然会受益于一个公正的外部团队,他们拥有补充/互补的技能,可以审查项目代码库的假设、设计、规范和实施。
-
审计类型:取决于项目的范围/性质/状态,但通常分为以下几类:
- 新审计:针对正在启动的新项目
- 重复审核:针对正在修订新/修复功能的现有项目的新版本
- 修复审计:用于审查对当前/之前审计结果所做的修复
- 保留审计:不断审查项目更新
- 事件审计:用于审查漏洞事件、找出事件的根本原因、识别潜在漏洞并提出修复建议。
-
审计时间表:取决于要评估的项目的范围/性质/状态以及审计类型。修复/保留审计可能需要几天,而新/重复/事件审计则可能需要几周。
-
审计工作:通常同时涉及多名审计员,以获得对项目的独立、冗余或补充/互补的评估专业知识。
-
审计成本:取决于审计的类型/范围,但通常每周成本高达 10,000 美元,具体取决于项目的复杂性、市场对审计的需求/供应以及审计公司的实力/声誉。
-
审计前提条件应包括:
- 明确定义要评估的项目范围,通常采用 Github 存储库中项目文件/文件夹的特定提交哈希值的形式
- 公共/私有存储库
- 公开/匿名团队
- 项目设计和架构的规范
- 项目实施和业务逻辑的文档
- 威胁模型和具体关注领域
- 先前的测试、使用的工具、其他审计
- 时间表、工作量和成本/付款
- 参与动态/问题/澄清、调查结果沟通和报告的渠道
- 双方接触点
-
审计局限性:审计是必要的(至少目前),但还不够:
- 风险虽然降低了,但是由于审计时间/精力有限、对项目规范/实施的了解有限、对新兴和快速发展的技术的安全专业知识有限、审计范围有限、项目复杂性大以及自动/手动分析的局限性等多种因素,残余风险仍然存在。
- 并非所有审计都是平等的——它很大程度上取决于审计员的专业知识/经验、针对项目复杂性/质量投入的努力以及所使用的工具/流程。
- 审计可在短时间内(通常为几周)提供项目的安全快照。但是,智能合约需要随着时间的推移不断改进,以添加新功能、修复错误或进行优化。每次更改后都依赖外部审计是不切实际的。
-
审计报告:包括范围、目标、工作量、时间表、方法、所用工具/技术、调查结果摘要、漏洞详细信息、漏洞分类、漏洞严重性/难度/可能性、漏洞利用场景、漏洞修复以及有关编程最佳实践的信息建议/建议。
-
审计结果分类:审计期间发现的漏洞通常分为不同的类别,这有助于了解漏洞的性质、潜在影响/严重性、受影响的项目组件/功能和漏洞利用场景。例如,Trail of Bits 使用以下分类:
- 访问控制:与用户授权和权利评估相关
- 审计和日志记录:与操作审计或问题记录相关
- 身份验证:与用户身份识别相关
- 配置:与服务器、设备或软件的安全配置相关
- 密码学:与保护数据的隐私或完整性有关
- 数据泄露:与敏感信息的意外泄露有关
- 数据验证:与不恰当地依赖数据的结构或值有关
- 拒绝服务:与导致系统故障有关
- 错误报告:与以安全方式报告错误情况有关
- 修补:与保持软件更新相关
- 会话管理:与已认证用户的识别相关
- 时间:与竞争条件、锁定或操作顺序有关
- 未定义行为:与程序触发的未定义行为相关
-
审计结果可能性/难度:根据OWASP ,可能性或难度是衡量此特定漏洞被攻击者发现和利用的可能性或难度的粗略指标。OWASP 提出了三种可能性级别:低、中、高。例如,Trail of Bits 将每个发现分为四个难度级别:
- 未确定:本次攻击中尚未确定攻击难度
- 低:普遍被利用,存在利用此漏洞的公共工具或可编写脚本
- 中等:攻击者必须编写漏洞利用程序,或者需要对复杂系统有深入的了解
- 高:攻击者必须拥有系统的特权内部访问权限,可能需要了解极其复杂的技术细节,或者必须发现其他弱点才能利用此问题
-
审计结果影响:根据 OWASP,这可估计漏洞被利用后对系统造成的技术和业务影响的程度。OWASP 提出了低、中、高三个影响级别。
-
审计结果严重性:根据 OWASP,可能性估计和影响估计会结合起来计算此风险的总体严重性。这是通过确定可能性是低、中还是高,然后对影响进行同样的操作来实现的。
-
OWASP 提出了 3x3 严重性矩阵,将三个可能性级别与三个影响级别相结合
-
严重程度矩阵(可能性-影响 = 严重程度):低-低 = 注意;低-中 = 低;低-高 = 中;中-低 = 低;中-中 = 中;中-高 = 高;高-低 = 中;高中 = 高;高-高 = 严重;
-
Trail of Bits 用途:
- 信息性:该问题不会造成直接风险,但与安全最佳实践或纵深防御相关
- 未确定:本次交战期间尚未确定风险程度
- 低:风险相对较小,或不是客户指出的重要风险。
- 中等:个人用户的信息面临风险,信息被利用将损害客户声誉,造成中等程度的财务影响,可能对客户产生法律影响
- 高:用户数量巨大,对客户声誉非常不利,或造成严重的法律或财务影响
-
ConsenSys 用途:
- 次要:问题本质上是主观的。它们通常是关于最佳实践或可读性的建议。代码维护者应自行判断是否解决此类问题。
- 中等:问题本质上是客观存在的,但不是安全漏洞。除非有明确的理由不予解决,否则应予以解决。
- 重大问题:问题是指可能无法直接利用或需要满足特定条件才能利用的安全漏洞。所有重大问题都应得到解决。
- 严重:问题是需要修复的可直接利用的安全漏洞。
-
项目审计清单(请参阅此处了解 Trail of Bits 建议):
- 解决简单的问题:1)启用并解决每个编译器警告2)增加单元和功能测试覆盖率3)删除死代码、陈旧分支、未使用的库和其他无关紧要的负担。
- 文档:1) 描述您的产品的功能、用户、使用原因以及交付方式。2) 添加与代码一致的预期行为注释。3) 标记并描述您的测试和结果(正面和负面)。4) 包括过去的评论和错误。
- 提供所包含的代码电池:1)记录在与内部网络完全断开连接的计算机上从头开始创建构建环境的步骤2)包括外部依赖项3)记录构建过程,包括调试和测试环境4)记录部署过程和环境,包括此过程的所有特定版本的外部工具和库。
-
审计技术:涉及应用于项目代码库的不同方法的组合,并附带规范和文档。许多是使用工具执行的自动分析,有些则需要人工协助。
- 规格分析(手动)
- 文档分析(手册)
- 测试(自动化)
- 静态分析(自动化)
- 模糊测试(自动化)
- 符号检查(自动化)
- 形式验证(自动化)
- 手动分析(手动)
你也可以将它们视为手动/半自动/全自动,其中半自动和全自动之间的区别在于,前者需要用户定义属性,而后者除了分类结果外几乎不需要用户配置。全自动工具往往易于使用,而半自动工具则需要一些人工协助,因此资源成本更高。
-
规范分析:规范详细描述了项目及其各个组件在其设计和架构中应该做什么(有时还包括为什么)。
- 从安全角度来看,它指定了资产是什么、资产在哪里、参与者是谁、参与者的特权、谁被允许在何时访问什么、信任关系、威胁模型、潜在攻击媒介、场景和缓解措施。
- 分析项目规范可以为审计人员提供上述详细信息,并让他们评估所做的假设并指出任何不足之处
- 很少有智能合约项目在首次审计阶段就提供详细的规范。他们最多会提供一些关于实施内容的文档。审计人员花费大量时间从文档/实施中推断规范,这让他们没有时间进行漏洞评估。
-
文档分析:文档是根据设计和架构要求对已实现内容的描述。
- 文档回答了“如何”设计/构建/实施某些事物,而不一定解决“为什么”和设计/需求目标
- 文档通常以 Github 存储库中的 Readme 文件的形式出现,描述单个合约功能以及功能性 NatSpec 和单个代码注释。
- 在许多情况下,文档可以替代规范,并为项目团队的假设、要求和目标提供关键见解
- 在查看代码之前了解文档有助于审计人员节省时间推断项目架构、合同交互、程序约束、资产流、参与者、威胁模型和风险缓解措施
- 文档和代码之间的不匹配可能表明文档陈旧/不良、软件缺陷或安全漏洞
- 审计人员应鼓励项目团队进行全面记录,这样他们就不需要浪费时间通过阅读代码来推断这一点
-
测试:软件测试或验证是一个众所周知的基本软件工程原语,用于确定软件在使用不同的输入执行时是否产生预期的输出。
- 智能合约测试有着类似的动机,但与 Web2 软件相比,尽管其规模(以代码行数计算)相对较小,但可以说更为复杂
- 智能合约开发平台(Truffle、Embark、Brownie、Waffle、Hardhat 等)相对较新,对测试的支持程度也不同
- 一般来说,项目在审计阶段进行的测试很少。测试与主网合约和状态的集成和可组合性并非易事
- 测试覆盖率和测试用例可以很好地表明项目的成熟度,并为审计人员提供有关漏洞评估的假设/边缘案例的宝贵见解
- 审计人员应该期待高水平的测试和测试覆盖率,因为这是必备的软件工程学科,尤其是当智能合约在设计上向区块链上的每个人公开,最终持有价值数千万美元的资产时
- “程序测试可以用来显示错误的存在,但永远无法显示错误的不存在!” - EW Dijkstra
-
静态分析:是一种不实际执行程序而分析程序属性的技术。
- 这与软件测试形成对比,在软件测试中,程序实际上是使用不同的输入来执行/运行的
- 对于智能合约,静态分析可以针对Solidity 代码进行,也可以针对 EVM 字节码进行。Slither在 Solidity 层面进行静态分析,而Mythril分析 EVM 字节码。
- 静态分析通常是控制流和数据流分析的组合
-
模糊测试:或模糊测试是一种自动化软件测试技术,涉及向计算机程序提供无效、意外或随机数据作为输入。然后监视程序是否存在异常,例如崩溃、内置代码断言失败或潜在的内存泄漏
- 模糊测试与智能合约尤其相关,因为任何人都可以通过随机输入在区块链上与智能合约进行交互,而不必具有正当理由或期望(任意拜占庭行为)
- Echidna和Harvey是两种流行的智能合约模糊测试工具
-
符号检查:是一种检查程序正确性的技术,即通过使用符号输入来表示一组状态和转换,而不是分别枚举单个状态/转换来进行证明/验证
- 模型检查或属性检查是一种检查系统有限状态模型是否满足给定规范(也称为正确性)的方法
- 为了用算法解决此类问题,系统模型及其规范均以某种精确的数学语言来表述。为此,该问题被表述为逻辑任务,即检查结构是否满足给定的逻辑公式。
- 一个简单的模型检查问题包括验证命题逻辑中的公式是否满足给定的结构
- 有时,通过一次性考虑大量状态,可以更高效地遍历状态空间,而不是一次枚举一个可达状态。当这种状态空间遍历基于一组状态和转换关系的表示(如逻辑公式、二元决策图 (BDD) 或其他相关数据结构)时,模型检查方法就是符号化的。
- 模型检查工具面临状态空间的组合爆炸,通常称为状态爆炸问题,必须解决这个问题才能解决大多数实际问题
- 符号算法避免明确构建有限状态机 (FSM) 的图形;相反,它们使用量化命题逻辑中的公式隐式地表示图形
-
形式验证:使用数学的形式化方法,证明或反证系统底层算法在特定形式规范或属性方面的正确性的行为
- 形式化验证可以有效地检测难以手动或使用简单的自动化工具检测的复杂错误
- 形式化验证需要对被验证程序进行规范,以及将规范与实际实现进行转换/比较的技术
- Certora 的Prover 和 ChainSecurity 的VerX是智能合约形式化验证工具的典型代表。Runtime Verification Inc 的KEVM是一个用于模拟 EVM 语义的形式化验证框架。
-
手动分析:是对使用工具进行自动分析的补充,满足智能合约审计的关键需求
- 使用工具进行自动分析成本低廉(通常是开源免费软件)、速度快、确定性和可扩展性(取决于工具是半自动化还是全自动),但其性能的好坏取决于它所了解的属性,而这通常仅限于 Solidity 和 EVM 相关的约束
- 相比之下,人工分析成本高昂、速度慢、不确定且不可扩展,因为人类在智能合约安全方面的专业知识在今天是一种稀有/昂贵的技能,而且我们的速度较慢、容易出错且不一致。
- 然而,手动分析是目前推断和评估业务逻辑和应用程序级约束的唯一方法,而大多数严重漏洞都存在于这些约束中
-
误报:指显示存在漏洞但实际上并非漏洞的发现。此类误报可能是由于分析中存在错误假设或简化,没有正确考虑漏洞实际存在所需的所有因素。
- 假阳性需要对结果进行进一步的人工分析,以调查它们确实是假阳性还是真阳性
- 大量误报会增加验证的人工工作量,并降低对早期自动/手动分析准确性的信心
- 真正的阳性结果有时可能会被归类为假阳性结果,这会导致漏洞被利用而不是被修复
-
假阴性:指漏报的发现,这些发现本应表明存在漏洞,但实际上根本没有报告。此类假阴性可能是由于错误的假设或分析不准确,没有正确考虑漏洞实际存在所需的最低因素。
- 按照定义,除非有其他分析揭示了假阴性的存在,或者漏洞被利用,否则不会报告甚至不会意识到假阴性
- 大量的假阴性降低了对早期手动/自动分析有效性的信心。
-
审计公司(代表性;不详尽):ABDK 、Arcadia 、Beosin 、Blockchain Consilium 、BlockSec 、CertiK 、ChainSafe 、ChainSecurity 、Chainsulting 、CoinFabrik 、ConsenSys Diligence 、Dedaub 、G0 、Hacken 、Haechi 、Halborn 、HashEx 、Iosiro 、Least Authority 、MixBytes 、NCC 、NewAlchemy 、OpenZeppelin 、PeckShield 、Pessimistic 、PepperSec 、Pickle 、Quantstamp 、QuillHash 、Runtime Verification 、Sigma Prime 、SlowMist 、SmartDec 、Solidified 、Somish 、Trail of Bits和Zokyo 。
-
智能合约安全工具:在帮助智能合约开发人员和审计人员展示(潜在)可利用的漏洞、突出危险的编程风格或揭示常见的滥用模式方面至关重要。然而,这些都无法取代人工审查/验证的需要,以评估特定于合约的业务逻辑和其他复杂的控制流、数据流和价值流方面。
-
安全工具类别:测试工具、测试覆盖率工具、linting工具、反汇编工具、可视化工具、静态分析工具、动态分析工具和智能合约形式化验证工具。
-
Slither_是一个用 Python 3 编写的 Solidity 静态分析框架。它运行一套漏洞检测器,打印有关合约详细信息的视觉信息,并提供 API 以轻松编写自定义分析。Slither 使开发人员能够发现漏洞、增强代码理解能力并快速制作自定义分析的原型。_它在公开的免费版本中实现了74 个检测器(带有奖杯,展示 Slither 在现实世界合约中的发现)。
-
滑行特点:
- 以较低的误报率检测易受攻击的 Solidity 代码
- 识别源代码中发生错误的位置
- 轻松集成到持续集成和 Truffle 构建中
- 内置“打印机”快速报告关键合同信息
- 使用 Python 编写自定义分析的检测器 API
- 能够分析使用 Solidity >= 0.4 编写的合约
- 中间表示(SlithIR)可实现简单、高精度的分析
- 正确解析 99.9% 的公共 Solidity 代码
- 每份合约平均执行时间不到 1 秒
-
Slither 错误和优化检测可以在 Truffle/Embark/Dapp/Etherlime/Hardhat 应用程序或单个 Solidity 文件上运行:
- Slither 默认运行所有检测器。若要仅运行选定的检测器,请使用_--detect detector1,detector2_ 。若要排除检测器,请使用_--exclude detector1,detector2_ 。
- 要排除具有信息性或低严重性的检测器,请使用_--exclude-informational_或_--exclude-low_
- _--list-detectors_列出可用的检测器
-
_Slither 打印机允许使用--print和以下选项_打印合同信息(使用 contract-summary、human-summary 和 inherit-graph 进行快速审查,使用 call-graph、cfg、function-summary 和 vars-and-auth 等进行深入审查):
- 调用图:将合约的调用图导出到点文件
- cfg: 导出每个函数的CFG
- 构造函数调用:打印执行的构造函数
- 合同摘要:打印合同摘要
- 数据依赖性:打印变量的数据依赖关系
- echidna:出口针鼹鼠指导信息
- evm:打印函数中节点的evm指令
- function-id:打印函数的 keccack256 签名
- function-summary:打印函数摘要
- human-summary:打印一份人类可读的合同摘要
- 继承:打印合约间的继承关系
- 继承图:将每个合约的继承图导出到点文件中
- modifiers:打印每个函数调用的修饰符
- require:打印每个函数的 require 和 assert 调用
- slithir:打印函数的 slithIR 表示
- slithir-ssa:打印函数的 slithIR 表示
- variable-order:打印状态变量的存储顺序
- vars-and-auth:打印写入的状态变量和函数的授权
-
_Slither 可升级性检查使用slither-check-upgradeability工具通过以下选项_帮助审查使用 delegatecall 代理模式的合约:
- 变成常量:不应该是常量的变量
- function-id-collision:函数 id 碰撞
- 函数阴影:函数阴影
- missing-calls:缺少对 init 函数的调用
- 缺少初始化修饰符 (missing-initializer()):未调用初始化修饰符 (initializer())
- 多次调用:多次调用 Init 函数
- order-vars-contracts:v2 中的变量顺序不正确
- order-vars-proxy:代理的变量顺序不正确
- 变量已初始化:具有初始值的状态变量
- were-constant:应为常量的变量
- extra-vars-proxy:代理中的额外变量
- 缺失变量:v2 中缺失的变量
- extra-vars-v2:v2 中的额外变量
- init-inherited:Initializable 不可继承
- init-missing:缺少可初始化项
- 初始化目标:必须调用的初始化函数
- 初始化程序缺失:缺少初始化程序()
-
Slither代码相似性检测器(一种面向研究的工具)使用最先进的机器学习来检测类似(易受攻击的) Solidity 函数
- 它使用来自 etherscan_verified_contracts 的预训练模型,其中包含 60,000 份合约和超过 850,000 个函数
- 它使用 FastText(一种向量嵌入技术)来生成每个函数的紧凑数值表示
- 它有四种模式:(1)测试- 在合约数据集中找到与你自己的函数相似的函数(2)绘图- 提供多个采样函数相似性的视觉表示(3)训练- 构建大型合约数据集的新模型(4)信息- 检查预训练模型或评估代码的内部信息
-
Slither 合约扁平化工具_slither-flat_生成了代码库的扁平化版本,具有以下特点:
- 支持三种策略:1)MostDerived:导出所有最派生的合约(每个文件都是独立的)2)OneFile:将所有合约导出到一个独立的文件中3)LocalImport:将每个合约导出到一个单独的文件中,并在其前言中包含导入“..”
- 支持循环依赖
- 支持所有编译平台(Truffle、embark、buidler、etherlime……)。
-
Slither 格式工具_slither-format_自动生成补丁。补丁与 git 兼容。应用补丁前应仔细检查。此工具支持的检测器包括:
- 未使用状态
- solc-版本
- 语用
- 命名约定
- 外部函数
- 警员州
- 常数函数
-
Slither ERC 一致性工具_slither-check-erc_检查 ERC 是否符合 ERC20、ERC721、ERC777、ERC165、ERC223 和 ERC1820:
- 所有功能均具备
- 所有事件都存在
- 函数返回正确的类型
- 必须查看的函数是视图
- 事件的参数已正确索引
- 函数发出事件
- 衍生合约不会破坏一致性
-
Slither 属性生成工具_slither-prop_可完全自动生成可使用单元测试或 Echidna 测试的代码属性(例如不变量)。可测试的 ERC20 场景包括:
- 可转让 - 测试正确的代币转让
- 可暂停 - 测试可暂停功能
- NotMintable - 测试没有人可以铸造代币
- NotMintableNotBurnable - 测试确保没有人可以铸造或销毁代币
- NotBurnable - 测试没有人可以销毁代币
- 可销毁 - 测试代币销毁。需要“burn(address) returns()”函数
-
Slither 新检测器:Slither 的插件架构让您可以集成从命令行运行的新检测器。检测器的骨架包括:
- 参数:允许您从命令行运行检测器
- HELP :是从命令行打印的信息
- IMPACT :表示问题的影响。允许的值为 INFORMATIONAL|LOW|MEDIUM|HIGH
- CONFIDENCE :表示您对分析的信心。允许的值为 LOW|MEDIUM|HIGH
- WIKI :常量用于自动生成文档。
- __detect()_是实现检测逻辑的函数,需要返回检测结果列表。
-
Manticore是一个用于分析以太坊智能合约(除了 Linux 二进制文件和 WASM 模块)的符号执行工具。详情 请参阅教程。
- 程序探索:Manticore 可以使用符号输入执行程序,并探索其可能达到的所有状态
- 输入生成:Manticore 可以自动生成导致给定程序状态的具体输入。
- 错误发现:Manticore 可以检测二进制文件和智能合约中的崩溃和其他故障情况
- 仪器仪表:Manticore 通过事件回调和指令挂钩提供对状态探索的细粒度控制
- 编程接口:Manticore 通过 Python API 公开对其分析引擎的编程访问
-
Echidna是_一个 Haskell 程序,用于对以太坊智能合约进行模糊测试/基于属性的测试。它使用基于合约 ABI 的复杂语法模糊测试活动来伪造用户定义的谓词或 Solidity 断言。_
-
针鼹鼠特点:
- 生成适合您实际代码的输入
- 可选的语料库收集、变异和覆盖指导,以发现更深层次的错误
- 由 Slither 提供支持,在模糊测试活动之前提取有用信息
- 源代码集成,用于识别模糊测试活动后覆盖了哪些行
- 基于 Curses 的复古 UI、纯文本或 JSON 输出
- 自动最小化测试用例以便快速分类
- 无缝集成到开发工作流程中
- 模糊测试活动的最大 gas 使用量报告
- 支持使用 Etheno 和 Truffle 进行复杂的合约初始化
-
Echidna 用法(详情见教程):
- 执行测试运行器:Echidna 的核心功能是一个名为 echidna-test 的可执行文件。echidna-test 将合约和不变量列表(应始终保持为真的属性)作为输入。对于每个不变量,它会生成对合约的随机调用序列,并检查不变量是否成立。如果它能找到某种方法来伪造不变量,它会打印这样做的调用序列。如果不能,您可以确信合约是安全的。
- 编写不变量:不变量表示为 Solidity 函数,其名称以 echidna_ 开头,没有参数,并返回布尔值。
- 收集和可视化覆盖率:完成活动后,Echidna 可以将覆盖率最大化的语料库保存在使用 corpusDir 配置选项指定的特殊目录中。此目录将包含两个条目:(1) 名为 coverage 的目录,其中包含 Echidna 可以重放的 JSON 文件;(2) 名为 covered.txt 的纯文本文件,其中包含带有覆盖率注释的源代码副本。
-
Eth-security-toolbox是_一个 Docker 容器,预安装并预配置了 Trail of Bits 的所有以太坊安全工具_。其中包括:
- 基于 Echidna 属性的模糊测试器
- Etheno 集成工具和差异测试仪
- Manticore 符号分析器和正式合约验证器
- Slither静态分析工具
- 拨浪鼓 EVM 升降器
- 不那么智能的合约存储库
-
Ethersplay是_一个_Binary Ninja 插件,它启用 EVM 反汇编程序和相关分析工具\。
- 将原始二进制格式的 evm 字节码作为输入
- 呈现所有函数的控制流程图
- 显示 Manticore 覆盖范围
-
Pyevmasm是_以太坊虚拟机 (EVM) 的汇编器和反汇编器库_。它包括一个命令行实用程序和一个 Python API。
-
Rattle是_一个 EVM 二进制静态分析框架,旨在处理已部署的智能合约_(不再积极开发)。
- 获取 EVM 字节串并使用流敏感分析来恢复原始控制流图
- 将控制流图提升为 SSA/无限寄存器形式,并优化 SSA - 删除 DUP、SWAP、PUSH 和 POP
- 从堆栈机到 SSA 形式的转换删除了 60% 以上的 EVM 指令,并为那些希望读取与之交互的智能合约的人提供了更加友好的界面
-
Evm_cfg_builder是_一种用于从 EVM 字节码中提取控制流图 (CFG) 的工具,并被 Ethersplay、Manticore 和 Trail of Bits 的其他工具使用_。
- 使用专用的值集分析从 EVM 字节码中可靠地恢复控制流图 (CFG)
- 恢复函数名称
- 恢复属性(例如,应付、查看、纯粹)
- 将 CFG 输出到点文件
- 库 API
-
Crytic-compile是 Trail of Bits 安全工具中使用的智能合约编译库,支持 Truffle、Embark、Etherscan、Brownie、Waffle、Hardhat 等开发环境。插件用于 Crytic 工具中,包括:
- 滑行
- 针鼹
- 蝎尾狮
- evm-cfg-生成器
-
Solc-select是_一个用于在 Solidity 编译器版本之间快速切换的脚本_。
- solc-select:管理安装和设置不同的 solc 编译器版本
- solc:solc 的包装器,根据通过 solc-select 设置的内容选择正确的版本
- solc 二进制文件从 https://binaries.soliditylang.org/ 下载,其中包含 Linux 和 macOS 的许多历史和现代 solc 版本的官方工件
-
Etheno是_以太坊测试的瑞士军刀。它是一个 JSON RPC 多路复用器、分析工具包装器和测试集成工具_。
- JSON RPC 多路复用:Etheno 运行一个 JSON RPC 服务器,可以多路复用对一个或多个客户端的调用:1)用于过滤和修改 JSON RPC 调用的 API 2)通过将 JSON RPC 序列发送到多个以太坊客户端来实现差异测试 3)同时部署到多个网络并与它们交互
- 分析工具包装器:Etheno 为 Manticore 等高级分析工具提供 JSON RPC 客户端 1)降低使用高级分析工具的进入门槛 2)无需自定义脚本来设置帐户和合约状态 3)无需 Solidity 源代码即可分析任意交易
- 与 Ganache 和 Truffle 等测试框架集成:1)使用单个命令运行本地测试网络 2)使用 Truffle 迁移来引导 Manticore 分析 3)单元测试中的符号语义注释
-
MythX是_一项功能强大的安全分析服务,可在您的开发生命周期中发现以太坊智能合约代码中的 Solidity 漏洞。_这是一项付费的基于 API 的服务,它在后端使用多种工具,包括静态分析器 (Maru)、符号分析器 (Mythril) 和灰盒模糊器 (Harvey),共实现46 个检测器。Mythril是MythX的开源组件。
-
MythX流程:
- 提交您的代码:分析请求使用 TLS 加密,您提交的代码只有您自己才能访问。为获得最佳效果,请同时提交智能合约的源代码和编译后的字节码。
- 激活全套分析技术:MythX 运行的时间越长,它就能检测到更多的安全漏洞。
- 收到一份详细的分析报告:MythX 可检测 SWC Registry 中列出的大多数漏洞。报告将返回您代码中发现的所有弱点的列表,包括问题的确切位置及其 SWC ID。生成的报告只有您才能访问。MythX 提供 3 种扫描模式:快速、标准和深度。您可以在此处查看差异。
-
MythX 工具:当您将代码提交给 API 时,它会被多个微服务并行分析,这些工具会协作以在提供的执行时间内返回更全面的结果。
- 解析 Solidity AST 的静态分析器
- 检测可能的脆弱状态的符号分析器,以及
- 检测易受攻击的执行路径的灰盒模糊测试器
-
MythX 覆盖范围:扩展到SWC 注册表中发现的大多数 SWC,这里列出了 46 个探测器以及所使用的分析类型。
-
MythX 基于 SaaS(安全即服务)平台,其前提是:
- 与本地运行安全工具相比,性能更高
- 比任何独立工具都具有更高的漏洞覆盖率
- 随着智能合约安全形势的发展,我们将通过新的和改进的安全测试不断改进我们的安全分析技术。
-
MythX 对使用其 SaaS API 提交的智能合约代码提供隐私保证:
- 代码分析请求使用 TLS 加密
- 为了提供全面的报告并提高性能,它将部分合同数据存储在我们的数据库中,包括部分源代码和字节码,但这些数据永远不会离开其安全服务器,也不会与任何外部方共享。
- 它会保存您的分析结果,以便您以后可以检索它们,但只有您可以访问该报告。
-
MythX 运行时间:快速扫描运行 5 分钟,标准扫描运行 30 分钟,深度扫描运行 90 分钟。
-
MythX 官方集成、工具和库包括:
- MythX CLI:使用 MythX 作为命令行界面 (CLI) 的统一工具,现已完全支持 Truffle 项目。
- MythX-JS:Typescript 库,用于将 MythX 集成到您的 JS 或 TS 项目中。
- PythX:用于将 MythX 集成到您的 Python 项目中的 Python 库。
- MythX VSCode:VSCode 扩展,允许您扫描智能合约并直接从代码编辑器查看结果。
-
MythX 定价:
- 按需收费(9.99 美元/3 次扫描):所有扫描模式和预付费扫描包
- 开发人员(49 美元/月):快速和标准扫描模式;每月 500 次扫描
- 专业版(249 美元/月):所有扫描模式;每月 10,000 次扫描
- 企业(定制定价):针对您团队的特定需求的定制计划;定制验证服务;定制支持保留费
-
Scribble是_一种验证语言和运行时验证工具,可将高级规范转换为 Solidity 代码。它允许您使用属性注释 Solidity 智能合约_(请参阅此处)。
- 原则/目标:1)开发人员和审计人员容易理解规范 2)规范易于推理 3)可以使用现成的分析工具有效地检查规范 4)少量的核心规范构造足以表达和推理更高级的构造
- 将 Scribble 规范语言中的注释转换为具体的断言
- 通过这些经过仪器化但等效的合约,人们可以使用 Mythril、Harvey、MythX
-
模糊测试即服务:这是 ConsenSys Diligence 最近推出的一项服务,项目可以提交其智能合约以及使用 Scribble 语言编写的嵌入式内联规范或属性。这些合约通过 Harvey 模糊测试器运行,该模糊测试器使用指定的属性来优化模糊测试活动。服务会报告模糊测试中的任何违规行为,以供项目修复。
-
Karl是_一款智能合约监控器,使用 Mythril 检测引擎检查安全漏洞。它可用于实时监控以太坊区块链上新部署的易受攻击的智能合约。_
-
Theo是_一个具有类似 Metasploit 界面的开发工具,它会将你带入 Python REPL 控制台,你可以在其中使用可用功能进行智能合约侦察、检查存储、运行漏洞或针对特定智能合约的前端或后端交易。_特点:
- 自动智能合约扫描,生成可能的漏洞列表
- 发送交易以利用智能合约
- 交易池监控
- Web3 控制台
- 先卖后卖交易
- 等待交易列表并发送其他交易
- 估算交易的 gas 意味着只发送成功的交易
- 禁用 gas 估算将发送具有固定 gas 数量的交易。
-
Visual Auditor是_Visual Studio Code 的扩展,它为_[Vyper提供安全感知语法和语义突出显示](https\://marketplace.visualstudio.com/items?item>Solidity和\<a href=)。 [](https\://marketplace.visualstudio.com/items?item>**\<a href=)
- 语法突出显示:访问修饰符(外部、公共、应付……)、安全相关内置函数、全局函数、方法和用户/矿工污染信息(address.call()、tx.origin、msg.data、block.*、now)、存储访问修饰符(内存、存储)、注释中的开发人员说明(TODO、FIXME、HACK……)、自定义函数修饰符、合约创建/事件调用、轻松区分算术运算和逻辑运算、使构造函数和后备函数更加突出
- 语义突出显示:突出显示 StateVars(常量、继承),检测并警告 StateVar 阴影,突出显示函数主体中的函数参数
- 审查功能:审计注释/书签 - @audit - @audit-ok - (见下文)、用于导入外部扫描仪结果的通用接口 - cdili json 格式(见下文)、codelens 内联操作:图形、报告、依赖项、继承、解析、ftrace、展平、生成单元测试存根、函数签名哈希、uml
- 图形和报告功能:从 vscode 中访问您最喜欢的 Sūrya 功能、带有调用流突出显示的交互式调用图等,从代码自动生成 UML 图以支持您的威胁建模练习或文档
- 代码增强:将鼠标悬停在以太坊帐户地址上即可下载字节码、源代码或在浏览器中打开;将鼠标悬停在 ASM 指令上即可显示其签名;将鼠标悬停在关键字上即可显示基本安全说明;将鼠标悬停在 StateVar 上即可显示声明信息
- 视角:驾驶舱与轮廓
-
Surya通过提供有关合约结构的信息来帮助审计人员理解和可视化 Solidity 智能合约,并生成调用图和继承图。它还支持以多种方式查询函数调用图,以协助手动检查合约。
- 与 Visual Auditor 集成
- 命令:graph、ftrace、flatten、describe、inheritance、dependencies、parse、mdreport
-
SWC 注册表:智能合约弱点分类注册表(SWC 注册表)是 EIP-1470 中提出的弱点分类方案的一种实现。
- 它与通用弱点枚举 (CWE) 中使用的术语和结构大致相同,同时涵盖了智能合约特有的各种弱点变体
- 该项目的目标如下:1)提供一种直接的方法来对智能合约系统中的安全问题进行分类。2)定义一种通用语言来描述智能合约系统架构、设计或代码中的安全问题。3)作为一种训练和提高智能合约安全分析工具性能的方法。
- 该存储库由 MythX 团队维护,目前包含 37 个条目
-
Securify :是一款以太坊智能合约的安全扫描器,可实现用 Datalog 编写的静态分析,支持 38 种漏洞
-
VerX :是一个可以自动证明以太坊智能合约的时间安全性的验证器。该验证器基于三个理念的精心组合:将时间安全性验证简化为可达性检查、用于计算交易中精确符号状态的高效符号执行引擎,以及将交易结束时的符号状态近似为抽象状态的延迟抽象。
-
SmartCheck :是一种可扩展的静态分析工具,用于发现用 Solidity 编程语言编写的以太坊智能合约中的漏洞和其他代码问题。它将 Solidity 源代码转换为基于 XML 的中间表示,并根据 XPath 模式对其进行检查。
-
Runtime Verification (RV)提供的基于K-Framework 的分析、建模和验证工具:提供KEVM ,它是 K-Framework 中的 EVM 模型。它是 EVM 的第一个可执行规范,完全通过了官方测试套件,并可作为构建各种分析工具和其他 EVM 语义扩展的平台。
-
Certora Prover :检查智能合约是否满足一组用 Specify 语言编写的规则。每条规则都会在所有可能的交易上进行检查,当然这不是通过明确枚举交易来完成的,而是通过符号技术来完成的。
- Certora Prover 为用户提供的一组安全规则提供完整的路径覆盖。例如,规则可能会检查在 ERC20 合约中只能铸造有限数量的代币。证明器要么保证规则适用于所有路径和所有输入,要么生成证明违反规则的测试输入。
- 众所周知,Certora Prover 解决的问题是不可判定的,这意味着总会存在一些病态的程序和规则,而 Certora Prover 会在没有明确答案的情况下超时
- Certora Prover 将智能合约(EVM 字节码或 Solidity 源代码)和一组规则作为输入,这些规则以 Certora 的规范语言编写。然后,Prover 使用两种计算机科学技术的组合自动确定合约是否满足所有规则:抽象解释和约束求解
-
DappHub 的Hevm :是专为单元测试和调试智能合约而制作的 EVM 实现。它可以运行单元测试、属性测试、交互式调试合约并显示 Solidity 源代码,或者运行任意 EVM 代码。
-
夺旗赛 (CTF):是一项有趣且具有教育意义的挑战,参与者必须破解存在漏洞的不同(虚拟)智能合约。它们有助于理解如何在野外利用漏洞的复杂性。热门的包括:
- 捕获以太币:是由史蒂夫·马克思 (Steve Marx)创建的一组二十项挑战,旨在测试对以太坊合约、账户和数学等概念的了解。
- Ethernaut :是 OpenZeppelin 推出的一款基于 Web3/Solidity 的战争游戏,在以太坊虚拟机中进行。每个级别都是一个需要“破解”的智能合约。该游戏 100% 开源,所有级别都是其他玩家的贡献
- Damn Vulnerable DeFi v2 :是tinchoabbate创建的一组 12 个与 DeFi 相关的挑战。根据挑战的不同,你应该阻止系统运行,窃取尽可能多的资金,或者做一些其他意想不到的事情。
- Paradigm CFT :是Paradigm 的samczsun创建的一组十七项挑战。
-
智能合约安全工具有助于协助审计人员审查智能合约。它们可以自动执行许多可以编入规则的任务,这些规则具有不同的覆盖率、正确性和精确度。与手动分析相比,它们速度快、成本低、可扩展且具有确定性。但它们也容易受到误报的影响。它们目前特别适合检测 Solidity 和 EVM 级别的常见安全陷阱和最佳实践。借助不同程度的手动协助,它们还可以编程来检查应用程序级别的业务逻辑约束。
-
审计流程可以看作是一个如下的十个步骤的过程:
- 阅读项目规范/文档以了解需求、设计和架构
- 运行快速自动化工具(如 linters 或静态分析器)来调查常见的 Solidity 缺陷或缺失的智能合约最佳实践
- 手动代码分析以了解业务逻辑并检测其中的漏洞
- 运行速度较慢但更深入的自动化工具,如符号检查器、模糊测试器或形式验证分析器,这些工具通常需要事先制定属性/约束,在分析过程中进行指导,并在运行后对其结果进行评估
- 与其他审计员讨论上述发现,以确定任何误报或缺失的分析
- 向项目团队传达状态,以澄清有关业务逻辑或威胁模型的问题
- 在审计期间重复上述操作,留出一些时间撰写报告
- 撰写报告总结上述内容,详细说明调查结果和建议
- 向项目团队提交报告并讨论发现、严重程度和潜在的解决方案
- 评估项目团队的修复并验证它们确实消除了调查结果中发现的漏洞。
-
阅读规范/文档:对于具有智能合约设计和架构规范的项目,这是推荐的起点。很少有新项目在审计阶段有规范。其中一些项目有部分文档。一些要点:
- 规范从项目的技术和业务目标和要求开始。它描述了项目的设计和架构如何帮助实现这些目标。
- 智能合约的实际实施是目标、要求、规范、设计和架构的功能体现,理解这些对于评估实施是否确实满足目标和要求至关重要
- 文档是根据设计和架构要求对已实现内容的描述。
- 规范回答了“为什么”某件事需要按照目前的方式设计/构建/实施。文档回答了“如何”设计/构建/实施某件事,而不一定回答“为什么”,并让审计人员自行推测原因。
- 文档通常采用 Readme 文件的形式,描述单个合约功能,并结合功能性 NatSpec 和单个代码注释。鼓励项目提供详细的规范和文档,可以为审计人员节省大量时间和精力来了解项目目标/结构,并防止他们做出与实施相同的假设,而这是导致漏洞的主要原因。
- 在缺乏规范和文档的情况下,审计人员只能通过阅读代码和使用 Surya 和 Slither 打印机等工具来推断目标、需求、设计和架构。这会占用大量时间,导致没有时间进行更深入/复杂的安全分析。
-
运行静态分析器:自动化工具(例如 linters 或静态分析器)可帮助调查常见的 Solidity 缺陷或缺失的智能合约最佳实践
- Slither 和 MythX 等工具在其检测器的上下文中对智能合约执行控制流和数据流分析,这些检测器对常见的安全陷阱和最佳实践进行编码。
- 评估他们的发现(通常在几秒/几分钟内可用)是基于 Solidity 语言、EVM 或以太坊区块链的众所周知的约束/属性来检测常见漏洞的一个很好的起点。
- 某些检测器结果中可能存在假阳性,需要手动验证其是否为真/假阳性
-
手动代码审查:需要了解业务逻辑并检测其中的漏洞。
- 自动分析器不理解应用程序级逻辑及其约束。它们仅限于 Solidity 语言、EVM 或以太坊区块链的约束/属性。
- 需要对代码进行手动分析,以检测实施过程中相对于规范或文档的安全相关偏差。
- 审计人员可能需要直接从代码或与项目团队的讨论中推断业务逻辑及其隐含的约束,然后评估这些约束/属性是否适用于代码库的所有部分。
-
运行更深层次的自动化工具:例如模糊测试器(例如 Echidna)、符号检查器(例如 Manticore)、工具套件(例如 MythX)以及使用 Scribble 或 Certora Prover 正式验证自定义属性,需要更多的设置和准备时间,但有助于运行更深入的分析以发现应用程序级属性中的边缘情况和数学错误等。
- 鉴于这些需要了解项目的应用逻辑,建议至少在初步的手动代码审查后使用它们,或者有时在与项目团队就规范/实施进行更深入的讨论后使用它们
- 分析这些工具的输出需要对工具本身、其领域特定语言,有时甚至是其内部工作原理有相当的专业知识
- 使用这些工具评估假阳性结果有时很有挑战性,但它们发现的真正阳性结果非常重要,即使是最好的手动分析也会遗漏极端情况
-
与其他审计人员进行头脑风暴:如果审计人员就智能合约的实施、假设、发现和漏洞进行头脑风暴,那么林纳斯定律:“只要有足够的眼光,所有的错误都是浅显的”可能也适用于审计人员。
- 虽然有些审计公司鼓励主动/被动讨论,但也有一些公司的做法是让审计人员单独进行评估,以鼓励独立思考而不是集体思考。前提是集体思考可能会使审计团队偏向于关注某些方面,而忽略一些漏洞。
- 混合方法可能会很有趣,审计团队最初集思广益,讨论项目的目标、规范/文档和实施,但后来他们自己使用防火墙独立进行评估,最后聚在一起汇总他们的调查结果。
-
与项目团队讨论:与项目团队建立开放的沟通渠道有助于澄清规范、文档、实施中的任何假设,或讨论中期调查结果。
- 调查结果还可立即在私人存储库中与项目团队共享,以讨论影响、修复和其他含义。
- 如果审计跨越数周,每周进行一次同步电话会议可能会有所帮助。与此相对的是,独立进行整个评估,以免受到项目团队的意见和观点的影响。
-
报告撰写:审计报告是整个评估的最终汇编,涵盖审计的所有方面,包括审计范围/覆盖范围、时间表、团队/工作量、摘要、工具/技术、调查结果、漏洞利用场景、建议的修复、短期/长期建议以及任何附录,其中包含有关工具和基本原理的更多详细信息。
- 执行摘要通常概述审计报告,重点/不足之处说明发现的漏洞数量/类型/严重程度以及风险的总体评估。它还可能包括对智能合约、(推断的)参与者、资产、角色、权限、访问控制、交互、威胁模型和现有风险缓解措施的描述
- 报告主要关注审计结果、其类型/类别、可能性/影响、严重性、评级依据、潜在漏洞场景、智能合约受影响部分以及潜在补救措施
- 它还可能涉及代码质量、可读性/可审计性和其他与文档、代码结构、函数/变量命名约定、测试覆盖率等相关的软件工程最佳实践的主观方面,这些方面不会构成迫在眉睫的安全风险,但却是影响安全漏洞的引入和持续的反模式和流程的指标
-
报告交付:向项目团队交付报告是一项关键的可交付成果和里程碑。除非分享中期发现/状态,否则这将是项目团队首次获得评估详细信息。
- 交付通常通过共享的在线文档进行,并附有一份读出文件,审计员将报告重点提交给项目团队进行讨论,并就调查结果及其严重程度评级进行辩论
- 项目团队通常需要一些时间来审查审计报告,并针对调查结果、严重程度或建议的修复提出反驳意见
- 根据事先的协议,项目团队和审计公司可能会公开发布审计报告(在完成所有必要的修复后),或者项目可能会出于某种原因决定将其保密
-
评估修复:审计后,项目团队可能会针对报告的发现进行任何必要的修复,并要求审计公司审查他们的回复
- 大多数发现可能都已得到修复,并且审查可能需要确认所应用的修复(可能与审计建议的修复不同)确实减轻了发现所报告的风险
- 研究结果可能会被质疑为不相关、超出项目威胁模型,或者仅仅被认为在项目可接受的风险模型范围内
- 审计公司可能会评估所采用的具体修复措施并确认/否认其风险缓解措施。除非是修复/保留类型的审计,否则此阶段通常不会超过一天,因为它通常超出商定的审计期限。
-
人工审查方法:审计人员采用不同的方法人工审查智能合约代码中的漏洞。
- 从访问控制开始
- 从资产流开始
- 从控制流开始
- 从数据流开始
- 推断约束
- 了解依赖关系
- 评估假设
- 评估安全检查表
-
从访问控制开始:访问控制是最基本的安全原语,它解决了“谁”有权访问“什么”的问题。(在正式的访问控制模型中,“谁”指的是主体,“什么”指的是客体,访问控制矩阵表示主体和客体之间的权限。)
- 虽然总体理念可能是智能合约是无需许可的,但实际上,对于与它们交互/使用它们的不同参与者,它们确实具有不同的权限/角色。
- 一般分为用户和管理员。出于安全启动或其他目的,许多智能合约都有一个管理员角色,通常是部署合约的地址。管理员通常可以控制关键配置和应用程序参数,包括(紧急)合约资金的转移/提取。
- 首先了解智能合约实施的访问控制,然后检查它们是否正确、完整和一致地应用,这是了解访问流程和检测违规行为的好方法
-
从资产流开始:资产是由智能合约管理的 Ether 或 ERC20/ERC721/其他代币。鉴于利用目标资产的价值,开始评估资产流入/流出/流经/跨智能合约及其依赖关系是有意义的。
- 谁:资产只能根据应用逻辑通过授权/指定的地址提取/存入
- 何时:资产应仅在授权/指定的时间窗口内或根据应用逻辑在授权/指定的条件下提取/存入(何时)
- 哪些:只有授权/指定类型的资产才应根据应用逻辑提取/存入
- 原因:根据应用逻辑,仅应出于授权/指定的原因提取/存入资产
- 其中:资产应根据应用逻辑提取/存入授权/指定的地址
- 类型:只有授权/指定类型的资产才应根据应用逻辑提取/存入
- 金额:仅应根据应用逻辑提取/存入授权/指定金额的资产
-
评估控制流:控制流分析智能合约之间和内部的控制转移,即执行顺序。
- 过程间(过程只是函数的另一个名称)控制流通常由调用图表示,该调用图显示哪些函数(调用者)在智能合约之间或内部调用了哪些其他函数(被调用者)
- 过程内(即函数内)控制流由条件(if/else)、循环(for/while/do/continue/break)和返回语句决定。
- 过程内和过程间控制流分析均有助于追踪智能合约中的执行和数据流
-
评估数据流:数据流分析智能合约内部和跨智能合约的数据传输
- 通过分析调用站点中用作函数参数的参数值的数据(变量/常量)来评估过程间数据流
- 通过分析函数内控制流路径上变量/常量(状态/内存/调用数据)的分配和使用来评估过程内数据流。
- 过程内和过程间数据流分析均有助于追踪智能合约中全局/本地存储/内存变化的流程
-
推断约束:程序约束基本上是程序应遵循的规则。语言级别和 EVM 级别的安全约束众所周知,因为它们是语言和 EVM 规范的一部分。但是,应用程序级别的约束是隐含在实现的业务逻辑中的规则,可能未在规范中明确描述,例如,当向智能合约存入一定数量的 ERC-20 代币时,将 ERC-721 代币铸入地址,并在提取早期存款时将其销毁。审计人员在手动分析智能合约代码时可能必须推断出此类约束。
- 推断程序约束的一种方法是评估与特定逻辑相关的大多数程序路径上正在执行的操作,并将其视为约束。如果一条或极少数程序路径上缺少此类约束,则可能表明存在漏洞(假设约束与安全相关),或者这些程序路径是例外情况,约束无需成立。
- 还可以使用符号检查器来验证程序约束,符号检查器会在这些约束不成立的执行路径上生成反例或见证。
-
了解依赖关系:当程序代码的正确编译或运行依赖于其他智能合约的代码/数据(这些代码/数据不一定由项目团队开发)时,就会存在依赖关系。
- 显式程序依赖关系在导入语句和继承层次结构中捕获。例如,许多项目使用 OpenZeppelin 的社区开发、审计和久经考验的智能合约来实现令牌、访问控制、代理、安全等。
- 通过智能合约与其他协议交互以及反之亦然,可组合性是预期和鼓励的,这会导致通过预言机等对外部智能合约的状态/逻辑产生新出现或隐含的依赖关系。
- 这对于依赖其他相关协议来实现稳定币、收益生成、借贷、衍生品、预言机等的 DeFi 协议尤其令人感兴趣/担忧。
-
评估假设:许多安全漏洞都是由错误的假设造成的,例如谁可以在何时、在什么条件下、出于什么原因访问什么等等。识别程序代码所做的假设并评估它们是否确实正确可以成为许多审计结果的来源。一些常见的错误假设示例包括:
- 只有管理员可以调用这些函数
- 初始化函数只会被合约部署者调用一次(例如可升级合约)
- 函数总是按照一定的顺序被调用(正如规范所期望的那样)
- 参数只能具有非零值或特定阈值内的值,例如地址永远不会为零值
- 某些地址或数据值永远无法被攻击者控制。它们永远无法到达可能被滥用的程序位置。(在程序分析文献中,这被称为污点分析)
- 函数调用总会成功,因此不需要检查返回值
-
评估安全检查表:检查表是逐项列出的要点列表,可以快速、有条不紊地遵循(稍后通过其列表编号引用),以确保所有列出的项目都已根据相关领域进行处理。
- 这种基于清单的方法在《清单宣言:如何正确行事》一书中广为人知,该书的作者是著名外科医生、作家和公共卫生领袖阿图尔·葛文德。在对这本书的评论中,马尔科姆·格拉德威尔写道:“葛文德首先区分了无知的错误(我们因为了解不够而犯的错误)和无能的错误(我们因为没有正确利用我们所知道的东西而犯的错误)。他写道,现代世界的失败实际上是第二种错误,他向我们介绍了一系列医学领域的例子,展示了外科医生的日常工作现在变得如此复杂,以至于几乎不可避免地会出现这样或那样的错误:一个原本称职的医生很容易错过一个步骤,或者忘记问一个关键问题,或者在当下的压力和压力下,无法为所有可能发生的情况做好适当的计划。葛文德随后拜访了飞行员和建造摩天大楼的人,并带着解决方案回来了。专家需要清单——字面意义上的书面指南,指导他们完成任何复杂程序的关键步骤。在本书的最后一部分,Gawande 展示了他的研究团队如何采纳这一想法,制定了一份安全的手术清单,并将其应用于世界各地,取得了惊人的成功。”
- 鉴于快速发展的以太坊基础设施(新平台、新语言、新工具和新协议)的复杂性,以及部署管理数百万美元的智能合约所带来的风险,智能合约需要做很多事情,因此很容易错过一些检查、做出错误的假设或未能考虑潜在情况。因此,智能合约专家也需要检查清单。
- 智能合约安全检查表(例如本系列中的文章)有助于引导大量需要记住和应用的关键方面。它们有助于有条不紊地逐项检查功能、概念、陷阱、最佳实践和示例,而不会遗漏任何项目。众所周知,检查表可以提高记忆力并加快回忆速度。它们还有助于引用感兴趣的特定项目,例如“安全陷阱和最佳实践 101”中的 #42 或“审计技术和工具 101”中的 #98。
-
提出概念验证漏洞:漏洞是指恶意行为者触发漏洞,滥用智能合约,导致资产被盗或冻结等事件
- 通过代码或书面描述假设场景来呈现此类漏洞的概念验证,可以说明具体的漏洞利用路径并证明调查结果的严重性,从而使审计结果更加真实可信
- 编码的漏洞应始终在测试网上,保持私密并负责任地向项目团队披露,而不会在实际系统上实际执行导致资金或访问权限的实际损失
- 描述性漏洞利用场景应该对参与者的角色/权力、其行为的实际原因以及触发漏洞的事件顺序做出现实的假设,并说明漏洞利用的路径
-
估计可能性和影响:可能性表示漏洞被恶意行为者发现并触发以成功利用潜在弱点的概率。影响表示漏洞被利用后对系统技术和业务方面的影响程度。在许多情况下,估计可能性/影响是低/中/高并非易事。
- 如果漏洞可以通过少量交易手动触发,无需太多资源/访问权限(例如非管理员)且无需假设许多条件成立,则可能性被评估为高。需要深入了解系统运作、特权角色、大量资源或多个边缘条件才能成立的漏洞被评估为中等可能性。其他需要更严格假设才能成立的漏洞,例如矿工勾结、链分叉或内部勾结,则被视为低可能性。
- 如果有任何资金损失或被锁定,则影响被评估为高。不影响资金但破坏系统正常运行的漏洞通常被评估为中等。其他任何事情的影响都为低。
- 审计和项目团队之间的许多可能性和影响评估存在争议,通常是具有安全意识的审计团队要求更高的可能性和影响力,而项目团队则淡化风险。
评估严重性:根据 OWASP,严重性是可能性和影响的结合。通过对这两者进行合理的评估,OWASP 矩阵中的严重性评估应该很简单。
-
摘要:审计是一项需要时间、资源和专业知识的工作,其中训练有素的专家使用自动和手动技术的组合来评估智能合约,以发现尽可能多的漏洞。审计可以显示漏洞的存在,但不能显示漏洞的不存在。