1.本发明涉及一种基于预训练模型的以太坊智能合约漏洞检测方法及系统,属于区块链安全保障和深度学习领域。
背景技术:2.智能合约作为区块链技术最成功的应用之一,已经吸引了学术界和工业界的目光。智能合约是一段运行在区块链平台上的计算机程序,通常由图灵完备的高级编程语言solidity编写。以太坊作为一个开源的公共区块链平台,也是目前为止智能合约数量部署最多的区块链平台。智能合约的安全性通常是由区块链,以太坊,以及自身编程语言solidity共同决定的。过去,智能合约的安全问题已经造成了重大的经济损失。
3.智能合约极易受到攻击,合约之所以受到攻击者攻击,主要有以下三方面的原因:(1)智能合约通常处理和操纵与加密数字货币相关的交易,对智能合约进行攻击可以为攻击者带来更多的经济效益;(2)智能合约的应用场景复杂且多变,当前智能合约的编程语言仍然是新颖且粗糙的。在实际场景下,合约的开发者可能很难去测试,从而造成智能合约的资产安全问题;(3)与传统语言不同的是,智能合约一旦部署就无法进行修改。而智能合约安全漏洞的存在会使得合约产生非预期的行为,从而违背了创建公平、可信赖的合约的初衷。
4.智能合约漏洞检测是智能合约安全研究的一个重要话题。首先由于以太坊链上的安全性和隐私保护性,98%的智能合约都是不开放源代码的。至今为止,在智能合约漏洞检测方面,缺乏一个开放的,足够规模的漏洞数据集,这为使用源代码进行漏洞检测带来阻碍。
5.目前针对漏洞检测,大部分的研究工作都使用传统的方式,即根据已有的漏洞特点,依靠人类专家手动定义、总结漏洞规则去匹配待测合约,从而进行合约漏洞的检测。智能合约漏洞传统检测主要有如下两方面的限制:(1)传统漏洞分析场景的研究往往由专家们或一些自动化算法来生成漏洞规则。虽然传统方法在检测漏洞上取得一定的效果,但仍存在较低的准确率和较高的漏报率、误报率。且有些检测工具检测时间偏长,检测效果不能令人满意。(2)每年部署在以太坊平台上的智能合约数量在不断增大,人工检测漏洞的成本在增大。
6.与传统的智能合约漏洞检测方法相比,基于深度学习的智能合约漏洞检测拥有更高的准确率和完备性。相关基于深度学习的检测方法研究主要使用深度学习的方法对代码的词法,语法,控制流和数据流等信息进行学习和分析。通常情况下,不同的代码中间表征有着不同的表征效果。但是,现在的研究通常是基于单一的代码中间表征形式,如代码tokens、抽象语法树、控制流图等,这可能导致在漏洞检测过程中,没有包含足够丰富的代码漏洞语法或者语义信息。
技术实现要素:7.发明目的:针对现有技术的存在的问题,本发明目的在于提供一种基于预训练模型的以太坊智能合约漏洞检测方法及系统,通过提取智能合约漏洞切片信息和ast结构化信息,并采用预训练模型进行特征融合,最终达到对当前以太坊智能合约环境下危害等级严重的合约漏洞的检测。
8.技术方案:为实现上述发明目的,本发明提供一种基于预训练模型的以太坊智能合约漏洞检测方法,包括如下步骤:
9.步骤1:收集智能合约数据集,根据漏洞合约的标准特征,提取智能合约中的目标函数片段,将智能合约的目标函数片段集合以及合约漏洞标签组成样本集;所述目标函数片段集合中包括一个或多个目标函数片段;
10.步骤2:根据漏洞标准,找到智能合约目标函数片段集合中相关的变量或者语句,经过数据流和控制流分析后,获取智能合约程序切片信息集合;
11.步骤3:调用语法解析器编译智能合约目标函数片段集合中各目标函数片段,并遍历生成的各目标函数片段的ast,获取智能合约ast结构化信息集合;
12.步骤4:对智能合约程序切片信息集合和ast结构化信息集合进行规范化、分词和编码;
13.步骤5:采用两个网络模型进行两种代码表征信息的训练,并采用预训练模型codebert拼接不同的代码表征,基于融合的特征实现智能合约漏洞的检测。
14.作为优选,所述步骤1中提取智能合约中目标函数片段的方法,包括如下步骤:
15.步骤11:根据智能合约源代码中原始合约版本,调用相应的编译器solc版本进行合约的编译;
16.步骤12:对于solc编译成功的合约,生成相应的合约抽象语法树文件;
17.步骤13:利用slither生成函数全局调用图,根据合约全局函数调用路径,获得全局的函数调用关系;
18.步骤14:利用slither生成单个函数内部的控制流图,获取函数内部变量的控制依赖关系和数据依赖关系;
19.步骤15:根据步骤13和步骤14,拼接组成合约的全局控制流图,获取一个合约完整的控制流和数据流信息;
20.步骤16:在步骤15全局控制流图的基础上,对于智能合约数据集,根据漏洞类型的标准和模式,分析变量关系,提取相应的函数片段。
21.作为优选,所述步骤2中获取智能合约程序切片信息集合的方法,包括如下步骤:
22.步骤21:根据漏洞分类框架或者漏洞准则,对于智能合约目标函数片段集合中的一个或者多个目标函数,确定相关的变量集合或语句集合;
23.步骤22:根据全局控制流图,进行变量或者语句的数据依赖分析,把所有相关数据依赖的变量或者语句全部提取出来,生成目标函数片段集合的候选数据依赖集;
24.步骤23:根据全局控制流图,进行变量或者语句的控制依赖分析,把所有相关的控制依赖的变量或者语句全部提取出来,生成目标函数片段集合的候选控制依赖集;
25.步骤24:按照原始合约中代码的顺序,合并所有候选数据依赖集和候选控制依赖集,生成智能合约程序切片信息集合。
26.作为优选,所述步骤3中获取智能合约ast结构化信息集合的方法,包括如下步骤:
27.步骤31:使用语法解析器antlr编译目标函数片段集合中各目标函数片段,生成编译的ast片段集合;
28.步骤32:采用深度优先遍历的方式,遍历编译的ast片段集合,生成ast 结构化信息集合。
29.作为优选,所述步骤4中包括如下步骤:
30.步骤41:规范化漏洞信息:使用fun{#}替换合约中的目标函数名称,其中 #表示数字,根据目标函数的前后位置取值;去除停用词和标点符号;将单字符变量和常量替换为约定的固定字符串;拆分驼峰命名变量中的单词。
31.步骤42:分词:将程序切片信息集合和ast结构化信息集合中所有文本进行分词,并生成dic词典和inv_dic词典,用word表示词典中的单词,idx表示单词word在词典中的位置,则dic词典的键值对格式为“word:idx”,inv_dic 词典的键值对格式为“idx:word”;
32.步骤43:编码:利用word2vec模型将数据集中的单词进行向量化表示,并最终形成词嵌入矩阵。
33.作为优选,所述步骤5中包括如下步骤:
34.步骤51:分别采用程序切片模型和ast结构化信息模型训练两种不同的代码表征;
35.步骤52:采用预训练模型codebert作为融合模型,融合模型的输入为程序切片模型和ast结构化信息模型输出代码表征的拼接,按照预训练模型codebert 的结构处理输入,输入序列i被转成输入向量x0,transformer层生成上下文表示 xn=transformern(x
n-1
),n∈[1,n],n为transformer层数,最后添加线性分类器并使用输出预测概率的softmax函数来预测。
[0036]
步骤53:基于训练集对模型进行寻参调优后,保存表现最优的模型的参数。
[0037]
作为优选,所述程序切片模型和ast结构化信息模型均采用blstm模型。
[0038]
基于相同的发明构思,本发明提供的一种基于预训练模型的以太坊智能合约漏洞检测系统,包括:
[0039]
目标函数提取模块,用于收集智能合约数据集,根据漏洞合约的标准特征,提取智能合约中的目标函数片段,将智能合约的目标函数片段集合以及合约漏洞标签组成样本集;所述目标函数片段集合中包括一个或多个目标函数片段;
[0040]
程序切片信息获取模块,用于根据漏洞标准,找到智能合约目标函数片段集合中相关的变量或者语句,经过数据流和控制流分析后,获取智能合约程序切片信息集合;
[0041]
ast结构化信息获取模块,用于调用语法解析器编译智能合约目标函数片段集合中各目标函数片段,并遍历生成的各目标函数片段的ast,获取智能合约ast结构化信息集合;
[0042]
预处理模块,用于对智能合约程序切片信息集合和ast结构化信息集合进行规范化、分词和编码;
[0043]
以及漏洞检测模块,用于采用两个网络模型进行两种代码表征信息的训练,并采用预训练模型codebert拼接不同的代码表征,基于融合的特征实现智能合约漏洞的检测。
[0044]
基于相同的发明构思,本发明提供的一种计算机系统,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述计算机程序被加载至处理器时实现所
述的基于预训练模型的以太坊智能合约漏洞检测方法。
[0045]
基于相同的发明构思,本发明提供的一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现所述的基于预训练模型的以太坊智能合约漏洞检测方法。
[0046]
有益效果:本发明提供的一种基于预训练模型的以太坊智能合约漏洞检测方法及系统,根据漏洞合约的标准特征,提取智能合约中的目标函数片段,在函数水平提取智能合约漏洞相关信息;在提取漏洞程序切片信息部分,分析合约数据流和控制流信息,提取目标程序代码,组成切片;在提取漏洞ast结构化信息部分,基于函数水平,使用语法解析器编译合约,然后使用自定义遍历方式遍历 ast生成对应的ast结构化信息。在模型的训练和检测部分,采用预训练 codebert模型融合两种信息,实现特征的融合、训练和漏洞的检测。本发明充分利用了智能合约代码漏洞语法或者语义信息,同时引入预训练模型进行信息融合,能够缓和数据难收集、数据量少的问题,达到漏洞检测效果最大化的目标。
附图说明
[0047]
图1为本发明实施例的整体步骤图;
[0048]
图2为本发明一具体示例的方法流程图。
具体实施方式
[0049]
下面结合具体实施例,进一步阐明本发明,应理解这些实施例仅用于说明本发明而不用于限制本发明的范围,在阅读了本发明之后,本领域技术人员对本发明的各种等价形式的修改均落于本技术所附权利要求所限定的范围。
[0050]
如图1所示,本发明实施例公开的一种基于预训练模型的以太坊智能合约漏洞检测方法,主要包括如下步骤:
[0051]
收集智能合约数据集,根据漏洞合约的标准特征,提取智能合约中的目标函数片段,将智能合约的目标函数片段集合以及合约漏洞标签组成样本集;所述目标函数片段集合中包括一个或多个目标函数片段;
[0052]
根据漏洞标准,找到智能合约目标函数片段集合中相关的变量或者语句,经过数据流和控制流分析后,获取智能合约程序切片信息集合;
[0053]
调用语法解析器编译智能合约目标函数片段集合中各目标函数片段,并遍历生成的各目标函数片段的ast,获取智能合约ast结构化信息集合;
[0054]
对智能合约程序切片信息集合和ast结构化信息集合进行规范化、分词和编码;
[0055]
采用两个网络模型进行两种代码表征信息的训练,并采用预训练模型 codebert拼接不同的代码表征,基于融合的特征实现智能合约漏洞的检测。
[0056]
如图2所示,以智能合约中的重入漏洞的检测为例,说明本发明实施例公开的一种基于预训练模型的以太坊智能合约漏洞检测方法的详细步骤,具体如下:
[0057]
步骤1:收集一定数量和种类的智能合约数据集(包括漏洞合约与非漏洞合约),根据漏洞合约的标准特征,提取智能合约中的目标函数片段,将智能合约的目标函数片段集合以及合约漏洞标签组成样本集。种类是指当前以太坊环境下危害等级较为严重或者最严重的漏洞类型,本实施例中以重入漏洞为例进行详细说明。
[0058]
数据集收集的主要包括两个方面:
[0059]
a、数据集爬取和采集。在github上使用关键词搜索(smartcontractvulnerability,re-entrancyvulnerability)和使用kral(https://github.com/cleanunicorn//karl)进行以太坊实时监控;
[0060]
b、数据标注。对收集的数据采用传统工具辅助标注和人工审计的方式,最终形成一个有标签的重入漏洞数据集scr={scr1,scr2,scr3,
…
,scrn},其中,n是数据集中合约的数量。
[0061]
根据重入漏洞标准获取智能合约的目标函数片段集合,具体过程如下:
[0062]
步骤11:根据合约源代码中原始合约版本,调用相应的编译器solc版本进行合约的编译;
[0063]
步骤12:对于solc编译成功的合约,生成相应的合约抽象语法树ast_json文件。
[0064]
步骤13:利用slither生成函数全局调用图,根据合约全局函数调用路径,获得全局的函数调用关系。
[0065]
步骤14:利用slither生成单个函数内部的控制流图,获取函数内部变量的控制依赖关系和数据依赖关系。
[0066]
步骤15:根据步骤13和步骤14,拼接组成合约全局的控制流图,获取一个合约完整的控制流和数据流信息。
[0067]
步骤16:在步骤15全局控制流图的基础上,对于漏洞数据集scr,根据漏洞类型的标准和模式,分析变量关系,提取相应的函数片段。对于数据集中第k个合约scrk,针对重入漏洞,分析全局控制流图来定位包含call-statement的函数路径,然后根据路径提取相应的函数,以此组成该合约的目标函数片段集合其中n是一个合约scrk中目标函数片段数量,。
[0068]
步骤2:根据对应的重入漏洞标准,找到相关的变量(如address类型)或者语句(如call-statement语句),经过数据流和控制流分析后,获取智能合约程序切片信息集合,具体步骤如下:
[0069]
步骤21:确定目标集合。根据漏洞分类框架或者重入漏洞准则,对于合约目标函数片段集合sfrk,确定该函数片段集合中相关的变量集合确定该函数片段集合中相关的变量集合(如address类型的变量)或语句集合address类型的变量)或语句集合(如call-statement语句);其中m是目标函数片段集合sfrk中变量的数量,l是目标函数片段集合sfrk中语句的数量;
[0070]
步骤22:数据流分析。根据步骤15生成的全局控制流图,进行变量或者语句的数据依赖分析,把所有相关数据依赖的变量或者语句全部提取出来,生成目标函数片段集合sfrk的候选数据依赖集其中p是目标函数片段集合sfrk中数据依赖语句的数量;
[0071]
步骤23:控制流分析。根据步骤15生成的全局控制流图,进行变量或者语句的控制依赖分析,把所有相关的控制依赖的变量或者语句全部提取出来,生成目标函数片段集合sfrk的候选控制依赖集其中q是目标函数片段集合sfrk中控制依赖语句的数量;
[0072]
步骤24:程序切片获取。对于合约scrk,按照原始合约中代码的顺序,合并数据依赖和控制依赖集合,生成程序切片信息集合(假设q≤p)
[0073][0074]
步骤3:是给定一个重入漏洞合约,采用语法解析器编译合约ast,获得 ast结构化信息集合,具体步骤为:
[0075]
步骤31:编译目标函数片段。根据步骤16生成的目标函数片段集合sfrk,使用语法解析器antlr编译函数片段,生成编译的ast片段集合生成编译的ast片段集合
[0076]
步骤32:自定义遍历序列。采用深度优先遍历的方式,遍历步骤41编译的 ast片段集合astsfk,生成ast结构化信息集合生成ast结构化信息集合
[0077]
步骤4:对程序切片信息和ast结构化信息进行预处理,以去除与漏洞信息无关的信息,具体步骤如下:
[0078]
步骤41:合约规范化。使用fun{#}(其中,#可取1,2,3
…
)等替换合约中的函数,比如根据漏洞规则,一个合约中可以提取到3个目标函数与重入漏洞相关,根据函数出现的前后位置,将函数名称变成fun1,fun2,fun3。其余规范化操作包括停用词去除;单字符变量,例如“a”、“b”、“i”、“j”、“k”等我们用“simplevar”代替;标点符号去除(例如“,”、“;”等);常量替换(根据常数的类型,我们将它们统一为“stringliteral”,“decimalnumber”,“hexnumber”和“hexliteral”);驼峰命名变量拆分(“mycontractvalue”变成“my”,“contract”,“value”等);
[0079]
步骤42:合约分词。将程序切片信息集合psrk和ast结构化信息集合asirk中所有文本进行分词,并生成dic词典和inv_dic词典,用word表示词典中的单词,idx表示单词word在词典中的位置,则dic词典的键值对格式为“word:idx”, inv_dic词典的键值对格式为“idx:word”。
[0080]
步骤43:合约词向量编码。利用word2vec模型将上述数据集中的单词进行向量化表示,并最终形成词嵌入矩阵。
[0081]
步骤5:根据输入设计模型进行两种代码表征信息的训练,并设计预训练模型,用以拼接不同的代码表征,具体步骤如下:
[0082]
步骤51:经过以上步骤,漏洞数据集scr={scr1,scr2,scr3,
…
,scrn} 中每个智能合约提取到两种信息集合,即程序切片信息集合 psr={psr1,psr2,psr3,
…
,psrn}和ast结构化信息集合 asir={asir1,asir2,asir3,
…
,asirn},分别采用程序切片模型和ast结构化信息模型训练两种信息,这两种模型使用rnns家族模型(比如blstm),模型的结构采用标准的blstm实现。两个模型是拥有相同层数的模型结构,模型训练过程中,由于每个合约可以提取一个或者多个目标函数,导致一个合约对应的序列长度不一。这里,我们统计每个合约中目标函数片段的分词数量,取平均,多余截取,不足补0,保证输入序列的长度一致,然后分别以两种信息编码好的词向量矩阵作为输入。这里我们把两个模型作为特征提取器,模型真实输出和期望输出计算损失进行反向更新参数,这两个模型某i层的输出mpsri和masiri作为学习到的漏洞特征表示。
[0083]
步骤52:设置融合模型的输入。模型的输入i设置为两分段数据的拼接,即 i=
{[cls],mpsr,[sep],masir},其中[cls]是起始位置的特殊标记,[sep]是分割程序切片集mpsr={mpsr1,mpsr2,mpsr3,
…
,mpsrm)和ast结构化信息集masir={masir1,masir2,masir3,
…
,masirm)的特殊符号;其中,m是定义的模型的层数。
[0084]
步骤53:搭建模型结构。按照预训练模型codebert的结构处理输入,输入序列i被转成输入向量x0,transformer层生成上下文表示xn=transformern(x
n-1
), n∈[1,n]。最后添加线性分类器并使用输出预测概率的softmax函数来预测。
[0085]
步骤54:模型调优和保存。基于训练集进行适当的寻参调优后,反向更新参数,保存表现最优的模型的参数。
[0086]
本领域技术人员可以理解的是上面具体实施过程以重入漏洞的检测为例,但本发明方案不仅适用于该特定类型的漏洞检测,可以适用于当前已知其他漏洞类型的检测,或者同时对多种漏洞类型进行检测。对于一个合约,可以根据不同类型的漏洞的标准特征提取到对应的目标函数片段集合,该目标函数片段集合及相应的漏洞类型标签即可构成一个学习样本。
[0087]
基于相同的发明构思,本发明实施例提供的一种基于预训练模型的以太坊智能合约漏洞检测系统,包括:目标函数提取模块,用于收集智能合约数据集,根据漏洞合约的标准特征,提取智能合约中的目标函数片段,将智能合约的目标函数片段集合以及合约漏洞标签组成样本集;所述目标函数片段集合中包括一个或多个目标函数片段;程序切片信息获取模块,用于根据漏洞标准,找到智能合约目标函数片段集合中相关的变量或者语句,经过数据流和控制流分析后,获取智能合约程序切片信息集合;ast结构化信息获取模块,用于调用语法解析器编译智能合约目标函数片段集合中各目标函数片段,并遍历生成的各目标函数片段的ast,获取智能合约ast结构化信息集合;预处理模块,用于对智能合约程序切片信息集合和ast结构化信息集合进行规范化、分词和编码;以及漏洞检测模块,用于采用两个网络模型进行两种代码表征信息的训练,并采用预训练模型codebert拼接不同的代码表征,基于融合的特征实现智能合约漏洞的检测。
[0088]
基于相同的发明构思,本发明实施例提供的一种计算机系统,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述计算机程序被加载至处理器时实现所述的基于预训练模型的以太坊智能合约漏洞检测方法。
[0089]
基于相同的发明构思,本发明实施例提供的一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现所述的基于预训练模型的以太坊智能合约漏洞检测方法。