前言
该文章是对SySeVR框架进行复现,环境搭建可以看以下文章,复现的过程笔者会尽量详细一些,但可能难免包含一些错误,仅供大家参考。
环境:joern 0.3.1(jdk 1.7)、neo4j 2.1.5、python 3.6、tensorflow 1.6、gensim 3.4
以下有几点说明
实验用到的数据集是我只从NVD数据集里面挑选的一些,然后在桌面新建一个文件夹NVD,把挑选好的数据放到里面,另外还要把NVD_diff解压到桌面,这个可以不用筛选github上面的代码有点错误,改正的代码除了最后的神经网络训练部分是自己改的,其他都是参考这个博主的
在运行过程中要注意路径、文件夹建立的问题最后的结果笔者也不能保证是对的,一来没有调参数、二来数据量可能比较少,并且准确率虽然可观,但是精确率却很低,不知道是啥原因,找到原因的希望能够告知。
笔者也写了自己的切片代码,供大家参考,如下所示。
https://github.com/glkfc/gen_slicehttps://github.com/glkfc/gen_slice
一、生成切片(即 SeVC)
1、使用joern解析源代码:输入是源代码文件,输出是名为.joernIndex的文件。
删除.joernIndex(这个文件是导入数据时创建的,先关闭neo4j再删除文件,不然会出现问题) 导入代码
3. 打开数据库
2、get_cfg_relation.py:该文件用于使用 joern 工具获取函数的 CFG 图。输入是第一步的输出,输出与cfg_db中的文件夹一起存储。
mkdir cfg_db
2.运行get_cfg_relation.py
3、Complete_PDG.py:该文件用于获取函数的PDG图。输入是 cfg_db 中的文件,输出与 pdg_db 中的文件夹一起存储。(如果数据量太大,这一步要花费好长时间,NVD的整个数据4个小时没跑完)
1.mkdir pdg_db
2.运行complete_PDG.py
4、access_db_operate.py:该文件用于获取函数的调用图。输入是 pdg_db 中的文件,输出与 dict_call2cfgNodeID_funcID 中的文件夹一起存储
1.mkdir dict_call2cfgNodeID_funcID
2.运行access_db_operate.py
5、point_get.py:该文件用于获取四种SyVC。输入是dict_call2cfgNodeID_funcID中的文件,输出是四种SyVC。
1.运行point_get.py
6、extract_df.py:该文件用于提取切片。输入是由points_get.py生成的文件,输出是切片文件。
1.mkdir -pv C/test_data/4
2.python2 extract_df.py
生成四种漏洞类型对应的SeVCs
获得未加标签的程序切片
查看相对应的文件,下面是snprintf相对应的切片,其中snprintf后面的30指的是这个函数位于源程序的第几行,这个表示在后面程序中会用到
7、dealfile.py:该文件用于获取nvd数据集中存在漏洞的行的行号。输入是源代码文件或func文件和diff文件。
1. python2 dealfile.py (运行之前要将里面的路径改一下)
运行之后获得了一个vul_context_fun.pkl文件
打开文件,可以看到是每一个文件中被修改的代码的行数
8、make_label_sard.py:该文件用于获取sard切片的标签(没用到)
9、make_label_nvd.py:该文件用于获取nvd切片的标签。
1.python2 make_label_nvd.py,运行前先改一下路径
运行,运行之前先创建label_data文件夹
查看标签文件
10、data_preprocess.py:该文件用于将标签写入切片文件。
1.修改文件
2.创建文件节夹,运行程序
3.查看文件
到了这边,程序切片和标签标记都已经完成了
步骤2:数据预处理
1、create_hash.py:该文件用于获取切片的哈希值。输入是extract_df.py生成的切片文件,输出是切片的哈希列表。
1.调整路径
2.运行程序,每一个切片都对应着一个hash,以便于把数据集中重复的元素去除(能看到相关的值是因为我在程序中输出了hash)
2、delete_list.py:该文件用于获取需要删除的切片的索引。输入是create_hash.py生成的hashlist,输出是list_delete。
1.调整路径
2.在当前路径下创建delete_slices文件夹,运行程序
3.查看pkl文件,文件中存储的是重复切片的编号,比如3号切片可能与某个切片重复了
3、process_dataflow_func.py:该文件用于对切片进行处理,包括读取pkl文件以及将代码拆分到语料库中。输入是由 extract_df.py 和 make_label_sard.py(make_label_nvd.py) 生成的切片文件和标签文件,输出是以测试用例 id 命名的语料库文件。
1、修改路径,四个路径分别为没有标签的切片路径、标签路径、重复的切片路径、要保存文件的路径
2、运行程序
4、create_w2vmodel.py:该文件用于训练word2vec模型。输入是语料库文件,输出是 word2vec 模型。到这一步就是用pyhton3运行了
1.修改路径,将model.txt保存在桌面上(随便哪都行)
2.运行程序,因为要用到gensim3.4库,记得用python3安装一下
5、get_dl_input.py:该文件用于通过训练好的word2vec模型将语料库文件中切片的标记转换为向量。输入是训练好的word2vec模型和语料库文件,输出是向量文件。
1.修改路径
2.运行程序
6、dealrawdata.py:该文件用于将get_dl_input.py生成的向量定长。
1.修改路径
2.运行程序
3.查看生成的数据,下图是训练数据
到此数据预处理完成!!!
第三步:深度学习模型
1、bgru.py:该文件用于训练BGRU模型并获得测试结果。输入是由dealrawdata.py生成的向量文件,输出是训练模型和测试结果。 运行该程序的时候,我用的是python 3.6、tensorflow 1.6,可以用conda创建虚拟环境,代码用的是github上面的代码,但是有一个测试数据和训练数据路径的问题,注意甄别,可以和其他博主的代码比对一下
训练过程