本帖最后由 Chrishu 于 2022-3-29 22:08 编辑
源码(局部,完整361行)
使用cpg-neo4j工具生成代码属性图,将图数据存储于neo4j数据库中代码属性图效果:
可以发现图过于庞大,冗余信息非常多,因此为便于提取关键信息,我们必须要对整图进行切片操作。此处采用neo4j功能强大的第三方插件apoc进行查询操作,生成子图效果如下:
关于查询原理:污点分析主要有三个组成要素:
污点信息产生点(source)、污点信息汇聚点(sink)和污点信息清洁点(sanitizer),它们通常需要富有经验的安全工程师手动设置。
(1)产生点(source):污点产生点往往是用户输入的数据,比如 Web 应用中读取 URL 参数的函数,顾名思义,这些函数调用后的返回值被标记为污点——攻击者可以操控的数据点。
(2)汇聚点(sink):检查点是程序的一些敏感操作,如调用数据库查询语句,或是将数据返回到网页,如果这些操作的数据是污点,那么意味着操作可被攻击者利用,即程序存在漏洞。
(3)清洁点(sanitizer):清洁点通常是对污点进行消除的一类操作,如 SQL 注入、XSS 中的过滤函数。清洁点是污点传播准确性的重要保证,不能识别清洁点即会引发污点过污染问题。
本项目采用美国国家标准与技术研究院(NIST)维护的漏洞数据集:软件保障参考数据集(software assurance reference dataset,简称 SARD),污点型漏洞在该数据集中示例如下:
[Java] 纯文本查看 复制代码 source: /* Read data using an outbound tcp connection */
socket = new Socket("host.example.org", 39544);
/* read input from socket */
readerInputStream = new InputStreamReader(socket.getInputStream(), "UTF-8");
readerBuffered = new BufferedReader(readerInputStream);
/* POTENTIAL FLAW: Read data using an outbound tcp connection */
data = readerBuffered.readLine();sink: dbConnection = IO.getDBConnection();
sqlStatement = dbConnection.createStatement();
/* POTENTIAL FLAW: data concatenated into SQL statement used in execute(), which could result in SQL Injection */
Boolean result = sqlStatement.execute("insert into users (status) values ('updated') where name='"+data+"'");
以上为未处理过的source和sink,即负样本。本项目获取切片思路:分别从source和sink点出发,根据变量的数据依赖关系遍历整图,取source与sink交集得到子图。图嵌入:代码属性图的表征精简完整,本项目目前采用方法为借助基于neo4j图数据库的强大第三方库“py2neo”进行查询,返回值为子图的列表表征,通过访问数据依赖边的起止节点实现token(关键信息表征)的获取代码如下:
此段代码最终可获取token表征形为:
[Java] 纯文本查看 复制代码 get data + executeQuery resultSet sqlStatement = getRow IO writeLine dbConnection getDBConnection createStatement
本项目使用数据集(SARD)表征形式为在一个文件中设置多个函数(bad,good source to bad sink, bad source to good sink)来保存正负样本。对于上万个源文件,获取每个文件,每个函数的source和sink,采用人工校对的方式显然不现实,本项目采用方法为括号匹配定位函数体起止行+正则匹配关键字定位source、sink点,部分代码截取如图:
最终获取六千余个数据集,使用word2vec工具进行处理后用于神经网络模型训练,最终实现95%的漏洞检测准确率
目前存在的问题:采用的数据集SARD是目前最权威最庞大的数据集(目前看到的十余篇源码漏洞挖掘研究均采用该数据集),但本身过于规范化,且漏洞表示较为直接,故本项目虽然在该数据集上取得了较好的成果,但在实际工业化应用场景下效果存疑。另外,本项目生成toke存在数据库查询动作,因此必须将代码属性图装载到neo4j数据库中,此操作占用了生成数据集99.99%的时间,导致生成6000个数据需要20个小时的时间,如果是在真实应用场景中,完成一个大项目的全部装载检验可能需要数分钟的时间,这显然是低效的。
为了解决这个问题,我们在对比查阅资料后决定在后续研究中使用另一个工具生成代码属性图(JCPG)此工具有以下优点:(1)数据表征精简:原工具cpg-neo4j生成图的json表征(单个节点):
[HTML] 纯文本查看 复制代码 [
{
"identity": 3198,
"labels": [
"DeclaredReferenceExpression",
"Expression",
"Node",
"Statement"
],
"properties": {
"endLine": 115,
"endColumn": 116,
"access": "READ",
"code": "data",
"staticAccess": false,
"startLine": 115,
"artifact": "file:///E:/Java/src/testcases/CWE89_SQL_Injection/s01/CWE89_SQL_Injection__connect_tcp_execute_01.java",
"argumentIndex": 0,
"file": "E:\Java\src\testcases\CWE89_SQL_Injection\s01\CWE89_SQL_Injection__connect_tcp_execute_01.java",
"isImplicit": false,
"startColumn": 112,
"name": "data",
"isInferred": false
}
}
JCPG的dot表征(单个节点)
[Java] 纯文本查看 复制代码 v48 [label="58:statementExpression:data = readerBuffered.readLine()";]
可以发现基于JCPG的表征简介明了得多,这得益于其在构建节点间边关系的高效处理。
JCPG概览(局部):
截取区域为source区域,高亮(黄色)为source点。
本项目数据集:https://samate.nist.gov/SRD/testsuite.php
Ps:这段是之前写的项目中期答辩PPT的参考文档,没有很注意规范,各位大佬将就着看一下 |