基于机器学习和Slither-simil的高效审计
Trail of Bits手动整理了丰富的数据——多年的安全评估报告——现在正在探索如何利用这些数据通过Slither-simil使智能合约审计过程更加高效。
基于以往审计中积累的知识,我们开始检测新客户代码库中类似的易受攻击代码片段。具体来说,我们探索了机器学习(ML)方法,以自动提高Slither(我们的Solidity静态分析器)的性能,并使审计员和客户的工作更加轻松。
Slither-simil
Slither-simil是Slither的统计补充工具,是一种代码相似性测量工具,使用最先进的机器学习技术来检测类似的Solidity函数。去年它作为一个实验开始时,代号为crytic-pred,用于将Solidity源代码片段向量化并测量它们之间的相似性。今年,我们将其提升到一个新的水平,并直接应用于易受攻击的代码。
Slither-simil目前使用自己的Solidity代码表示形式SlithIR(Slither中间表示),在函数粒度级别上对Solidity片段进行编码。我们认为函数级分析是开始研究的好地方,因为它既不太粗糙(如文件级别),也不太详细(如语句或行级别)。
在Slither-simil的流程工作流中,我们首先从以前的存档安全评估中手动收集漏洞,并将其转移到漏洞数据库中。请注意,这些是审计员在没有自动化的情况下必须发现的漏洞。
之后,我们编译了以前客户的代码库,并通过自动函数提取和规范化脚本将它们包含的函数与我们的漏洞数据库进行匹配。在此过程结束时,我们的漏洞被规范化为SlithIR令牌,作为我们ML系统的输入。
以下是我们如何使用Slither将Solidity函数转换为中间表示SlithIR,然后进一步令牌化和规范化,使其成为Slither-simil的输入:
|
|
图2:来自TurtleToken.sol合约的完整Solidity函数
|
|
图3:相同函数及其SlithIR表达式输出
首先,我们将每个语句或表达式转换为其SlithIR对应项,然后对SlithIR子表达式进行令牌化,并进一步规范化它们,以便尽管此函数的令牌与漏洞数据库之间存在表面差异,但会出现更多相似匹配。
|
|
图4:先前表达式的规范化SlithIR令牌
在获得此函数的最终令牌表示形式后,我们将其结构与漏洞数据库中易受攻击函数的结构进行比较。由于Slither-simil的模块化,我们使用各种ML架构来测量任意数量函数之间的相似性。
|
|
图5:使用Slither-simil测试智能合约函数与其他Solidity合约数组的相似性
让我们看一下ETQuality.sol智能合约中的transferFrom函数,看看它的结构如何与我们的查询函数相似:
|
|
图6:ETQuality.sol智能合约中的transferFrom函数
比较两个函数中的语句,我们可以很容易地看到它们都包含相同顺序的二进制比较操作(>=和<=)、相同类型的操作数比较,以及另一个类似的赋值操作,带有内部调用语句和返回"true"值的实例。
当相似性分数向0降低时,这类结构相似性被观察到的频率降低,而在另一个方向上;两个函数变得更加相同,因此相似性分数为1.0的两个函数彼此完全相同。
相关研究
过去两年中,Solidity中自动漏洞发现的研究已经起飞,像Vulcan和SmartEmbed这样的工具,使用ML方法来发现智能合约中的漏洞,正在显示出有希望的结果。
然而,所有当前相关方法都专注于像Slither和Mythril这样的静态分析器已经可以检测到的漏洞,而我们的实验专注于这些工具无法识别的漏洞——特别是那些未被Slither检测到的漏洞。
过去五年的许多学术研究都专注于将ML概念(通常来自自然语言处理领域)并在开发或代码分析环境中使用它们,通常称为代码智能。基于此研究领域先前相关的工作,我们旨在弥合人类审计员和ML检测系统在发现漏洞方面性能之间的语义差距,从而用自动化方法(即机器编程或MP)补充Trail of Bits人类审计员的工作。
挑战
我们仍然面临数据稀缺的挑战,涉及可用于分析的智能合约规模以及其中出现有趣漏洞的频率。我们可以专注于ML模型,因为它很吸引人,但在Solidity的情况下,即使语言本身也非常年轻,我们需要谨慎对待我们拥有的数据量,这对我们没有太大好处。
归档以前的客户数据本身就是一项工作,因为我们必须处理不同的solc版本以分别编译每个项目。对于在该领域经验有限的人来说,这是一个挑战,我在此过程中学到了很多。(我暑期实习的最重要收获是,如果你正在做机器学习,除非你必须做数据收集和清理阶段,否则你不会意识到它们是多大的瓶颈。)
饼图显示了我们调查的10次客户安全评估中89个漏洞的分布情况。我们记录了显著漏洞和那些Slither无法发现的漏洞。
Slither-simil的未来发展
今年夏天,我们恢复了Slither-simil和SlithIR的开发,有两个目标:
- 研究目的,即开发端到端相似性系统,缺乏特征工程。
- 实际目的,即增加特异性以提高精确度和召回率。
我们使用FastText实现了基于文本的基线模型,与改进的模型进行比较,结果有显著差异;例如,一个不处理软件复杂性指标,而只专注于基于图的模型,因为它们目前是最有前途的。
为此,我们提出了一系列技术在最高抽象级别(即源代码)上尝试Solidity语言。
为了开发ML模型,我们考虑了监督和无监督学习方法。首先,我们开发了一个基于令牌化源代码函数并将其嵌入欧几里得空间的无监督基线模型(图8),以测量和量化不同令牌之间的距离(即不相似性)。由于函数由令牌构成,我们只需将差异相加即可获得任何大小的任何两个不同片段之间的(不)相似性。
下图显示了一组训练Solidity数据中的SlithIR令牌在三维欧几里得空间中的球形化表示,相似令牌在向量距离上更接近。每个紫色点显示一个令牌。
我们目前正在开发一个专有数据库,包括我们以前的客户及其公开可用的易受攻击智能合约,以及论文和其他审计中的参考文献。它们将共同形成一个统一的全面Solidity漏洞数据库,用于查询、后期训练和测试新模型。
我们还在开发其他无监督和监督模型,使用由Slither和Mythril等静态分析器标记的数据。我们正在检查具有更强表达能力的深度学习模型,我们可以用它们建模源代码——特别是基于图的模型,利用抽象语法树和控制流图。
我们期待检查Slither-simil在新审计任务上的性能,看看它如何提高我们保证团队的生产力(例如,在分类和更快地找到低 hanging fruit 方面)。当它变得更加成熟和自动可扩展时,我们还将