概述
teEther: Gnawing at Ethereum to Automatically Exploit Smart Contracts
论文地址
1、提供了一个基于低级EVM指令的易受攻击合约的通用定义。
2、开发了一个工具TEETHER,它仅从合约的字节码提供端到端漏洞利用。 为此,他们解决了几个特定于EVM的挑战,例如象征性地处理哈希值的新方法。
3、提供了从以太坊区块链中提取的38,757个独特合约的大规模脆弱性分析。
2、鉴定了四个关键的、低级的EVM指令,它们必须涉及到一个值传输:一个用于创建常规事务(CALL),一个用于合约终止(SELFDESTRUCT),还有两个用于代码注入(CALLCODE、DELEGATECALL)。
识别出的漏洞:
1、错误的可见性:
默认情况下,除非使用内部键字标记,否则可公开访问“可靠”函数。这可能导致意外的博览会——确定契约功能。例如,44个契约中的一个实现了一个投注功能,该功能具有处理抽签的专用功能。但是,这个函数并没有被标记为内部函数,可以直接调用来将资金转移到任意地址。
2、错误的构造函数:
在实体中,与合约本身同名的函数充当合约的构造函数。与常规函数相比,构造函数不成为契约已编译代码的一部分,在创建合约期间只执行一次。然而,由于solability没有提供一个特殊的关键字来标记构造函数,原本应该是构造函数的函数可能会因为忽略大小写敏感、拼写错误或重构操作(如重命名)过程中的疏忽而变成常规函数。所分析的契约包含两个例子,简单的错误(例如图8)和没有重命名构造函数就重命名了合约的情况(例如,使用构造函数MyContract来重命名contract MyContract v1)。
3、语义混淆:
另一类易受攻击的合约源于对Ethereum执行模型的不同误解。例如,这些合约似乎将合约的总余额(this.balance)与当前事务持有的值(msg.value)混淆了。其他情况下忽略了这样一个事实:合同的存储是公开可读的,因此不应该用来存储文件。
4、逻辑缺陷:
我们观察到的最后一类漏洞是由逻辑缺陷引起的。例如,图9中给出的摘录是一个有缺陷的纯所有者修饰符的简单实现,但是它有一个倒立的条件。与预期的行为相反,这允许除所有者之外的任何人调用所有标记的函数。
2、背景介绍
2.1交易系统
在其核心,Ethereum提供了一种名为Ether的新加密货币的公共账簿。它提供了一个由160位地址标识的帐户和帐户余额之间的映射。这个账本是由相互不信任的节点组成的网络支持的,这些节点被称为“矿工”。用户可以向网络提交事务,以便将Ether传递给其他用户或调用智能契约。采矿者随后将处理这些交易,并使用一项协商一致的协议,就交易的结果达成协议。为防止网络上的资源枯竭攻击,以及激励矿商处理尽可能多的交易,每笔交易都会向矿商支付一笔处理费。所有处理的事务都保存在一个区块链中,这是一个基于公共散列的只允许追加的日志,它允许任何人检查系统的当前状态。
2.2智能合约
2.2.1以太坊虚拟机
智能合约的代码是在一个特殊目的的虚拟机中执行的,这个虚拟机就是Ethereum虚拟机(EVM)。EVM是一个基于堆栈的虚拟机,字长为256位。除了算术和控制流指令,EVM还提供特殊指令来访问当前事务的字段,修改合约的私有存储,查询当前的区块链状态,甚至创建进一步的事务。
除了256位字栈和持久存储外,EVM还提供了一个字节可寻址的内存,作为各种指令的输入和输出缓冲区。例如,SHA3指令在可变长度数据上计算kecck -256散列,从内存中读取输入,其中通过两个堆栈参数提供输入的内存位置和长度。该内存的内容在合约执行期间不被持久化,并且在合约执行开始时内存总是被设置为零。
2.2.2solidity
2.2.3交易
交易中最重要的四个字段: to, sender, value:要转移的金额, data:数据参考, and gas.
2.3表示符
2.4攻击者模型
2.5伦理考虑
3、智能合约漏洞
3.1关键指令
3.1.1直接值传递
在Ethereum的正式规范中描述的两个EVM指令允许将值转移到给定地址:CALL and SELFDESTRUCT
CALL :执行常规交易,有如下栈参数:
如果攻击者可以控制第二个堆栈参数(to),那么当使用非零的第三个堆栈参数执行调用指令时,他们就可以导致合约将值转移到他们控制下的地址。
SELFDESTRUCT:终止合约,不再调用。
如果攻击者可以在控制栈顶元素的同时执行SELFDESTRUCT指令,那么他可以获得合约的所有资金,并导致这个合约永久拒绝服务。
3.1.2代码注入
为了方便库和代码重用,EVM提供CALLCODE和DELEGATECALL In - structions,允许在当前契约的上下文中执行第三方代码。
如果攻击者控制CALLCODE或DELEGATECALL的第二个栈元素(to),他们可以“注入”任意代码到合约中。通过代码片段()部署到一个新合约,并随后在这个脆弱的合约中发出CALLCODE或DELEGATECALL,原来的合约就可以被销毁,所有资金都转移给攻击者。
3.1.3易受攻击状态:定义了何时智能合约处于易受攻击的状态(1、危险路径;2脆弱状态)
Definition 1
根据EVM四个指令潜在的攻击风险定义了危险路径:
- 导致使用非零的第三个堆栈元素执行“CALL”指令,其中第二个堆栈参数可以由外部控制,
- 导致执行“SELFDESTRUCT”指令,其中第一个堆栈参数可以由外部控制,或者
3.导致执行“CALLCODE”或“DELEGATECALL”指令,其中第二个堆栈参数可以由外部控制。
Definition 2
易受攻击状态:
如果事务可能上述导致危险路径的执行,则合约处于脆弱状态。
通过关键指令之一利用处于脆弱状态的合同的交易称为危险交易
3.2存储
根据攻击者可以窃取以太坊的直觉,很明显处于脆弱状态的合同很容易受到攻击,但相反情况不一定成立。
允许修改存储的唯一指令是SSTORE。 因此,执行存储修改的事务始终执行SSTORE指令。 因此,我们可以定义状态改变的交易。
定义3(状态更改路径)状态更改路径是一条潜在的执行跟踪,其中至少包含一个SSTORE指令。
定义4(状态更改交易)如果事务的执行跟踪是状态更改路径,则它是状态更改。
将此与定义2结合使用,我们可以给出以下定义
定义5(脆弱)如果存在状态改变交易(可能为空)的一系列导致脆弱状态的合同,则该合同是脆弱的。
由此可以得出结论,成功的漏洞利用总是由一系列状态改变的事务和紧随其后的危险事务组成。
4、智能合约的自动开发生成
4.1概述
teether架构
第一步,CFG恢复模块反汇编EVM字节码并重建控制流图(CFG)。 接下来,扫描此CFG以获取关键指令和状态更改指令。 路径生成模块探索从CFG根目录到这些指令的路径,约束生成模块从路径中通过符号执行创建一组路径约束。 最后,漏洞利用生成模块解决了关键路径和状态更改路径的组合约束,从而产生了漏洞。
4.2CFG恢复
从EVM字节码重建控制流程图是一项艰巨的任务。 这是由于EVM仅提供带有间接跳转的控制流指令这一事实。 有条件的JUMPI和无条件的JUMP都从最顶层的堆栈元素读取跳转目标。 尽管在某些情况下可以简单地推断出跳转目标,例如PUSH2 ; JUMP,在其他情况下,它变得不那么明显。 例如,考虑图5中地址19处的JUMP指令。此处,JUMP指令的使用类似于x86的ret指令,以在函数调用之前调用方在堆栈中推入的“返回地址”处恢复执行。
4.2.1依赖边缘
4.3路径生成
使用A*搜索算法【15】,路径成本定义为该路径在CFG中经过的分支数
关键路径:仅关注关键路径,在每一步骤之后,我们检查是否仍可从当前路径到达至少一个关键切片的所有剩余指令。如果无法完全达到关键片段,则将放弃对该路径的进一步探索。
状态更改路径:检查在当前路径上是否可以达到SSTORE指令。
4.4约束生成
约束生成模块与路径生成同步运行。 一旦找到路径,路径约束生成模块将尝试象征性地执行该路径,以收集一组路径约束。
TEETHER使用基于Z3的符号执行引擎【13】。
固定大小的元素(例如call value or the caller’s address)使用固定大小的位向量表达式建模;
可变长度的元素(例如call data, the memory,)和存储使用Z3的数组表达式建模;
4.4.1不可行路径
一旦程序计数器偏离所需的路径,我们就认为该路径不可行。 为了防止由于相同的条件而无法执行的昂贵的符号化进一步路径,我们提取了一个最小的不可行子路径。 由于此类偏差只能在JUMP或JUMPI指令之后发生,因此我们考虑最后执行的指令的后向切片。 这些切片包含有助于跳转目标的所有指令,对于JUMPI而言,也包含分支条件。 然后,最小的不可行子路径是执行跟踪的子路径,该路径是从任何片中包含的第一条指令开始的。 如果路径中包含从内存或存储中加载的值,则将整个执行跟踪作为最小的不可行子路径,以保持分析的声音。 然后,将这个最小的不可行子路径传递回路径生成模块,该模块将停止探索包含该子路径的路径。
4.4.2hash计算
每当我们期望执行SHA3指令时,我们都会引入一个新的256位符号变量来对Keccak-256计算结果进行建模。 同时,我们记录了此新变量与提供给SHA3指令的输入数据之间的关系。
4.4.3符号长度内存访问
首先,每当将符号长度的数据复制到内存中时(例如,使用CALLDATACOPY时),我们都使用Z3的If表达式对条件赋值进行建模。 例如,智能合约中常见的一种模式是将整个输入数据复制到内存中。 TEETHER将使用以下形式的赋值执行此操作
为了使生成的表达式数量合理,我们仅对i进行预先配置的上限(在我们的实验中为256)。
其次,如果从存储器中读取了具有符号长度的数据,我们将返回一个新的符号读取对象。 与将Keccak-256结果映射到它们各自的输入数据类似,我们还保留了从符号读取对象到它们的地址,它们的长度以及发生读取时的存储状态的映射。 这使我们以后可以解析符号读取对象的值。
4.4.4约束结果
给定路径p的约束生成模块的最终输出是元组Rp =(μ,S,I,C,H,M),其中
μ是执行后的符号机器状态
S是合同执行后的符号存储
I是在其中执行路径p的符号环境
C是执行路径p必须满足的一组约束
H是Keccak-256结果变量到它们各自的输入数据的映射
M是符号读取对象到其地址,长度和内存状态的映射
假设在每条指令之后,μ和S也会捕获各个状态的全部历史记录。
定义由路径序列给定的组合约束结果
TEETHER尝试先尝试基于单个路径创建漏洞,然后再尝试更大的路径序列。在我们的实验中,我们探索了长度最长为三的路径序列,该路径序列最多包含两个状态改变路径和一个最终临界路径。
4.5漏洞生成
TEETHER的最后阶段是漏洞利用生成模块,该模块检查在上一步中生成的组合路径约束是否满足Keccak-256结果和符号读取对象的要求。如果找到具有可满足的组合路径约束的路径序列,则此模块将输出导致利用智能合约的交易列表。否则,将请求并测试下一个路径序列。
在检查合并结果的可满足性之前,我们首先使用其他约束对攻击者的目标进行编码。 第一个目标是将资金或代码执行转移到攻击者控制的地址a中,我们通过添加约束来实现
攻击者的第二个目标是牟取暴利。 虽然在CALLCODE,DELEGATECALL和SELFDESTRUCT的情况下这不是问题,但在这里智能合约的所有资金都可以转移给攻击者,但是如果基于CALL的利用则需要进行额外的检查。 尤其是因为某些必要的交易可能需要先将以太币转移到合同中,所以这是正确的。 因此,我们要求在最终CALL指令中传输的值必须大于发送给合同的所有值的总和。 由于值是由CALL的第三个堆栈参数指定的,因此形式上
4.5.1令人满意的赋值
组装好路径序列的组合路径约束(包括它们的状态相互依赖关系和攻击者的目标)后,下一步是找到一个令人满意的分配,这将为我们提供具体的价值,以构建成功利用所需的交易 。 我们利用约束求解器Z3。 但是,我们不能简单地按原样传递我们收集的约束集,因为约束求解器没有意识到Keccak-256结果和符号读取对象的特殊语义。
为了解决这个问题,我们应用了图7所示的迭代方法。该算法保留一组未解析的变量Q,该变量最初设置为H和M的所有元素。只要此队列为非空,我们就可以计算 不依赖于Q中任何变量的约束子集D,并使用约束求解器找到D的令人满意的变量赋值A。接下来,该算法尝试从Q解析未解析的变量。如果一个变量不依赖于其他未解析的变量,则可以解析。 为了解析Keccak-256的结果,我们首先评估赋值A中哈希的输入数据表达式(根据H)。这为我们提供了输入数据的具体值,然后我们可以在该值上计算Keccak-256哈希。 为了“修复” Keccak-256结果变量和输入数据之间的这种关系,我们添加了两个新的约束,这些约束将输入数据绑定到其当前评估值,并将Keccak-256结果变量绑定到计算的哈希值。 通过计算起始地址和长度的具体值,可以类似地解析符号存储读取对象。 解析变量后,将其从Q中删除。重复此过程,直到解析完所有变量。
此处的关键见解在于,由于映射H和M定义了H和M的元素与它们的相应表达式中涉及的变量之间的依赖关系,因此它们还隐式定义了H和M的拓扑顺序。此外,由于这些映射永远无法 定义一个循环,此顺序定义明确。
4.5.2漏洞交易
4.6实施
5、评估
5.1结果
5.2验证
5.3案例学习
6、讨论
6.1关键路径定义
6.2内部合约漏洞
6.3评估
7、相关工作
7.1智能合约分析
7.2自动开发
8、结论
最后
以上就是美丽糖豆为你收集整理的区块链论文6(teether检测智能合约漏洞并自动生成漏洞路径)2、背景介绍3、智能合约漏洞4、智能合约的自动开发生成5、评估6、讨论7、相关工作8、结论的全部内容,希望文章能够帮你解决区块链论文6(teether检测智能合约漏洞并自动生成漏洞路径)2、背景介绍3、智能合约漏洞4、智能合约的自动开发生成5、评估6、讨论7、相关工作8、结论所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复