S&P 2021 ,一篇检查API误用的工作

开源于:https://github.com/petablox/arbitrar

简介

软件的API因为他的多样性和复杂性很容易导致编程错误,而且也很难用分析工具检查出来。这类检查API误用的工具要么需要专家去设置精确的API规范,要么假设API的使用是遵守一些简单的规则,而这些规则可以自动地从代码中提取。这种方法的准确性很差。

文章提出的方法可以与用户交互来区分目标API是合法还是非法使用。具体来说是通过一种主动学习的算法来计算API使用非法的概率,从而来减少用户的负担。

实现了检查C/C++程序的API误用工具的原型ARBITRAR,并测试了21个真实程序,包括OpenSSL和内核。找到了40个新的bug,已经被修补了18个。也在APISAN benchmark里找到了所有的已知的bug,误报率为51.5%,比APISAN的87.9%要好。

引言

现代软件包含了很多API,提供了模块的接口包含丰富的语义信息,使得实际使用的过程比较复杂。根据最近的研究(19年一篇API误用综述)表明,17%的bug都是来自API误用。这些误用可能会造成很严重的安全影响。

现在有很多程序分析技术用来检查API误用。然而API误用仍然很广泛。现有的API误用检测工具可以分为两类,第一类是给定API的规范,检查有没有违反这个规范,比如IMChecker,Semmle,Sys。这些工作的有效性取决于API规范的质量。然而,编写准确的规范需要很多专家知识,对于很有经验的用户来说也不好写。而且这些规范一般都是用Domain Specific Language写的,不同的工具还不一样。

  • IMChecker用的是YAML
  • Sys用的是Lisp和LLVM IR
  • Semmle用的是CodeQL

第二类工具比如APISAN和JADET,假设API的使用是遵照一些简单的规则,而这些规则是可以自动化地从代码中挖掘出来的。具体来说,给定很多使用API的代码,大部分的使用模式都是合法使用的,和他们不同的就是非法的。这些工具的假设有两点,一个是有很大的代码语料库,另一个是大部分的使用是合法的。然而这两个假设并不总是有,尤其是那些很少使用但很重要的API。这些方法就很难获取到这些API的使用模式,而且先进的工具APISAN在有很多种合法使用模式的情况下会产生很多误报。

总的来说,检测出合法的API使用模式是很难的,尤其是在缺少足够多的样例的情况下。另一方面,开发者也不一定能够写出精确的API规范。然而,给定一条表示API使用的路径,开发者可以很容易地确定API是不是合法的。

比如下面的代码分别在第6行和第12行调用了目标API:png_destroy_write_struct。这两个调用的trace分别是1,2,3,4,6和1,2,3,4,12。当给出这两个trace的时候,对这个API:png_destroy_write_struct有了解的开发者就知道第12行的调用是非法的。

那么我们可以利用这个feedback来实现一个高效的API 误用检查器吗?总共有以下这四个挑战:

  1. 高效的路径生成:给定代码中的一个目标API,我们需要一个机制去高效地生成所有到达API调用点的路径。而且,我们需要一个方式去减少一些trace,因为并不是所有的trace都和API调用有关系。
  2. 通用的路径表示:不像其他的方法,只能适用于简单的API使用模式,我们需要找到一种通用的方法来表示trace,能够处理所有类型、不同使用方式的API
  3. 实时的用户交互:不考虑trace的长度或者API语义的复杂性,我们需要迅速从用户反馈中学习,并反馈给用户
  4. 准确的alarm识别:需要准确的识别出有问题的API误用,来让开发者很快地验证。

文章使用了最大差异的核密度估计方法,一种主动学习方法。不像现有的方法需要API规范或者大的代码语料库。文章使用无约束的符号执行生成过程内的调用点的trace。通过在API调用点处,使用后向切片来最小化trace。这个优化的trace用于转换为特征向量。然后在向量化的trace上用MD-KDE算法计算是非法使用的概率。

Motivation

方法

Trace Generation

trace generation的目的是生成所有调用API方法的路径。然而要枚举真实程序里的所有路径是不太现实的,因为会遇到路径爆炸问题、工程上的限制。这里文章对API调用的上下文做了unconstrained symbolic execution。

(1)找到执行的上下文

我们使用执行上下文s来表示under-constrained symbolic execution的入口和范围。形式化表示的话就是s=(g,φ),g是入口函数,φ={g1,g2,…,gn}是允许探索的函数。给定:

  • 目标API方法的在函数f的一个调用点k,
  • 程序的调用图
  • 上下文深度d

通过算法1去计算执行环境的上下文。首先使用逆向的BFS从函数f开始遍历调用图,来找到距离为d的函数。然后对于每个函数g,使用bfs找到2*d距离的φ函数。然后从φg中移除目标k。因为关注的是API如何使用的,而不是API如何实现的。

(2)Under-constrained Symbolic Execution

给定调用点k的执行上下文,我们从入口函数开始符号执行,使用符号化变量作为函数的参数。遇到函数调用时,如果是在φ里的函数,就跳进那个函数里。反之,就忽视call指令,并且生成一个符号值作为调用的返回值。(感觉可能会出现很多符号值)

内存模型:使用简单的哈希表来作为内存模型,地址作为key来进行映射。使用符号化变量来初始化内存的每个字节。内存模型和17年的两篇工作一样。

循环和递归的处理:将循环展开一次,并且不会跳进递归函数调用来避免状态爆炸。因为一次循环就能获取到API的使用情况。但是,我们也记录循环的入口和出口,因为他们可以用来降低误报。

生成的trace长这样:

Trace Encoding

trace编码的目的是将程序的trace转化为固定维度的特征向量,然后用在后面的主动学习算法里。基于API 误用的bug,我们定义了一些特征。这些特征基本覆盖了大部分API使用的行为。这个工具使用datalog规则来提供了一个统一可扩展的接口来定义特征。

特征主要分为四类:

  • return value:返回值特征表示返回值是如何使用的。如果目标函数有返回值,就生成这个特征。
  • argument:包括餐宿的类型,前置条件和后置条件。
  • causality relation:这个出现在API方法属于一组需要同时调用的情况下。比如lock/unlock,fopen/fclose。具体来说,作者弄了个字典,key是API,值是和这个API一起出现次数top k个的函数。
  • 控制流:这类特征和API没啥关系,主要是这个特征能够描述trace的结构,并且能够降低误报。

主动学习和用户交互

这部分提出了一个新的主动学习方法来处理API误用检测问题。首先,将问题定义为机器学习的异常检测问题,目标是能够通过人类专家的交互来识别出异常。然后我们提出了MD-KDE算法,最大差异的核密度估计算法,能够学习人类专家的反馈,然后在几次迭代中精确地识别可疑数据。

交互式异常检测问题:传统的异常检测方法在很大量级的代码上训练,但这个方法存在一个问题,就是正负样本差很多,因此这些方法通常需要额外的假设。比如one-class假设。然而这种假设在我们的例子中是不现实的,因为每个API使用模式都是不同的。为了解决这个问题,我们通过让人类专家和结果进行交互,来给机器学习算法提供更多的信息。

给定一个n个数据点的数据集,一个专家将数据映射为正常或者异常。学习器可以在每轮使用一个数据点来查询f,总共查询T轮。交互式异常检测问题的目的是最大化识别出的异常的总数。

具体来说,学习器从数据集挑一个没打标签的数据给专家,专家给出反馈。最后的准确率是T次查询中,是API误用的情况所占的百分比。

基于主动学习算法的核密度估计

在每个轮次,给定当前有标签的数据集,学习器为每个没打标签的数据点计算分数,分数越高最有可能是异常,然后让专家评估分数最高的数据。

算法的核心就是要找到离bug最近的,离非bug最远的没打标签的trace。

MD-KDE 的有效性

一开始给出一个没打标签的trace,然后用户如果将这个标签设置为正样本,就会变成中间的样子。如果设置为负样本,就会变成右边图的样子。

实现

3.5k的Rust代码和2K的Python代码。

trace生成和under-constrained symbolic execution都是基于rust代码实现。

主动学习框架是基于python实现。

结果

Effectiveness:和APISAN相比的有效性

Impact:能够找到未知的API误用bug吗?

Scalability:能够扩展到真实的大型程序里吗?并且呢个够快速学习反馈给用户?

Extensibility:应用到其他场景的扩展性?

数据集:2个API误用的benchmark 和 21个真实程序包括内核

有效性

传统的漏洞检测的评估都是用漏报,误报来衡量的。但这个工具不好用这个来衡量,因为这个工具一开始对漏洞一无所知,需要用户给他打标签。所有这个技术的有效性,就需要工具能够快速从用户反馈中学习,并且提供给用户较少的没有漏洞的trace。

所以ARBITRAR的误报指的是提供给用户不是bug的trace。同时也定义了反馈容忍度,就是没有bug的trace的上界。从而让我们能够策略误报。

比如 容忍度为2表示,用户只能容忍两条没有bug的trace。因此,在两次交互中没有找到的bug,就属于漏报。如果容忍度为无穷大,用户就可以检查所有的trace,也就是漏报为0,如果容忍度为0,则就不会找到bug,因为这个工具需要初始数据来进行学习。如果用户分析了n条trace,其中容忍度为k,那么意味着至少有n-k个trace是真实的bug。

和APISAN工具进行了对比,虽然二者的误报并不是一种方法计算的。作者工具的误报加上了主动学习引入的成本,仍然要比APISAN的误报要低。并且在同一个benchmark上的漏报率也要低于APISAN.

同时还设置了一下容忍度对于检测API误用的影响。实验结果表明,大部分API 误用bug都可以在3次迭代内找到。

Impact

找到了40个真实的漏洞,也提交了补丁被开发者验证通过。first bug warning这一列表示找到第一个bug中间遇见了多少个误报。

Scalability

不管有多少条trace,MD-KDE算法都可以很快地和用户进行交互。下面的图说明了他们创新的MD-KDE算法要比传统的KDE算法要快很多。

Extensibility

为了说明这个MD-KDE算法的创新性,他们还做了一个实验来回答一个这样的问题:已知一个bug,能否用工具更快地找到剩下的所有的bug。xf表示找到第一个真的bug需要的迭代次数。xl表示找完剩下所有的bug的迭代次数。

选择这几个API的标准是有两个:一是API有多个bug,二是找bug还有提升的空间。

局限

需要提供API方法:需要事先提供API方法。作者也提供了一种方法来枚举所有的API调用点,以及这些API的出现次数,因此可以根据API次数来选择要测试的API。

生成的trace不完整:只考虑了直接调用。没有考虑函数指针的情况,作者认为补充下指向分析可以解决。

离散的用户反馈:主动学习算法只需要用户反馈的一个位,yes or no。然而实际上用户可能要提供各种各样的反馈,比如80%的概率是yes,现有的设计不支持这种反馈。不过像ALPF这种技术可以用来处理这种反馈。

对用户反馈敏感:主动学习算法的前提是信任用户的反馈,然而一个用户可能会出错。当给出一个错误的反馈时,模型能够在几个正确的回答后,自动修正。然而,这种方法可能没有办法扩展到所有的API,因为模型是建立在API的复杂性之上。需要更多的研究来精确的处理模型对于用户反馈的敏感性问题。

未来工作

模型可解释性和迁移学习:作者相信他们的算法学习的模型是具有可解释性的,并且是可迁移的。比如对malloc建立的模型,同样也可以迁移到realloc和calloc。下一步计划将迁移学习应用到其他相关的API方法上。同时也计划为每个trace生成一个描述来解释哪个特征决定了选择哪个trace。

确定高危险漏洞的优先级:确定高危险API 误用bug的优先级是很重要的。比如,可能会导致内存泄露或者代码嗅探的API误用bug要比会导致内存损坏的bug优先级要低。为了解决这个,我们计划让用户提供bug类型的回馈。然后利用bug类型的反馈去训练漏洞类型的检测模型,从而能够确定漏洞的优先级。

总结

实验做的很完整。

引入用户交互,对文章的实验设计都有很大的影响。文章中处理的很好。一直在强调工具的误报和传统的漏洞检测不一样。

开源于:https://github.com/petablox/arbitrar

【论文分享】ARBITRAR: User-Guided API Misuse Detection相关推荐

  1. 2021-05-28 2021年ICSE中与Android相关的论文分享

    2021年ICSE中与Android相关的论文分享 关于2021 ICSE 文章1:Too Quiet in the Library: An Empirical Study of Security U ...

  2. 预告 | 4月22日,CVPR 2021论文分享会详细介绍,学术新星云集!

    国际计算机视觉与模式识别会议(CVPR)是人工智能领域最有学术影响力的顶级会议之一.根据 CVPR 2021 官方公布的论文收录结果,今年一共有 1663 篇论文被接收,接收率为 23.7%,相较于去 ...

  3. 论文分享 | Yann LeCun 联合发布、工程师都在读的自监督学习论文

    文章导读 本期文章中,我们为大家带来了 3 篇自监督学习的相关论文,其中两篇是由卷积网络之父 Yann LeCun 参与发布. 对于大型机器视觉训练任务而言,自监督学习 (Self-supervise ...

  4. 【论文分享】基于微信小程序的快递取寄系统设计与实现

    [论文分享]基于微信小程序的快递取寄系统设计与实现 免责声明:本文章已收录至<电脑知识与技术>,仅供参考学习,切勿抄袭或他用,搬运请注明来源,谢谢各位小伙伴的配合. 文章编号:1009-3 ...

  5. 谣言检测论文分享(三)

    论文分享之 Rumor Detection on Twitter with Tree-structured Recursive Neural Networks Jing Ma , Wei Gao , ...

  6. 【微软亚洲研究院】CVPR2020 论文分享会,他们带着论文来了!

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 国际计算机视觉与模式识别会议(CVPR)是人工智能领域最有学术影响力的顶级会议之一 ...

  7. CVPR 2021论文分享会日程公布!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale学术 活动:CVPR 2021论文分享会 随着人工智能的火热,AAAI.Neu ...

  8. CVPR 2020最佳学生论文分享回顾:通过二叉空间分割(BSP)生成紧凑3D网格

    机器之心发布 机器之心编辑部 在近日举行的 CVPR 2020 大会上,最佳论文.最佳学生论文等奖项悉数公布.加拿大西蒙弗雷泽大学陈之钦(Zhiqin Chen )等人的「BSP-Net」相关研究获得 ...

  9. 【建站系列教程】2.3、分享一些小说的api接口

    [建站系列教程]2.3.分享一些小说的api接口 一.追书神器api 二.资源二api 三.宜搜api 四.结语 写在前面:大家好,我是热爱编程的小泽. [建站系列教程]是我的亲身建站经历写给广大建站 ...

  10. 4个Keynote、12篇论文分享、40个Poster,CVPR 2021论文分享会全日程公布

    随着人工智能的火热,AAAI.NeurIPS.CVPR 等顶级学术会议的影响力也愈来越大,每年接收论文.参会人数的数量连创新高.但受疫情影响,近两年国外举办的学术会议都转为了线上,无法满足学者们现场交 ...

最新文章

  1. datax安装+配置+使用文档
  2. 关于如何参与到开源项目中《How To Succeed In Open Source ( In Ways You Haven't Considered Yet )》...
  3. 线程池是如何执行的?拒绝策略有哪些?
  4. mac磨皮插件_Adobe Pr 黑科技插件合集,一键安装,Mac+Win
  5. 一台mysql数据库服务器_在一台服务器安装多个MySQL数据库
  6. 【程序猿】2016年自己的十年计划篇
  7. 利用DMRMAN备份时出现“管道连接失败”的错误信息的解决方法
  8. editText属性
  9. 哔哩哔哩轻视频怎么去水印
  10. “守法规知礼让、安全文明出行”背后需要良好的交通环境支撑 | 聚焦守法知礼...
  11. Alibaba Cloud Linux 3 正式发布!新特性来了!
  12. 巡逻机器人(Patrol Robot, Uva1600)
  13. 罗升阳对安卓2.3系统的总结
  14. Event Trigger 使用方法
  15. ILRuntime学习(之一)
  16. 搜狗输入法弹窗搜狐新闻的处理
  17. ArcGIS Runtime SDK for Android100.9语音路径导航
  18. 常见退信原因及解决方法
  19. linux停止tomcat 8005,严重:无法联系localhost:8005.关闭tomcat服务器时,Tomcat可能没有运行错误....
  20. 百度商业系统大规模微服务分布式监控实践

热门文章

  1. 棋牌游戏判断牌型算法---适合所有的棋牌游戏
  2. 实现multi()函数,参数个数不限,返回所有参数的乘积
  3. 京东商品详情查询接口V1新版接口
  4. 浅谈,如何获取MTK CPU信息 请看我是如何做的。一步步来吧
  5. 高通烧录报ufs需要重新provision
  6. ps证件照白底换蓝底_【插件】PS插件证件照V2.0一键裁剪排版磨皮换装换底色软件2020Mac/Win完整版...
  7. 胡晓曼:MindSpore 开源运营与治理 | DEV. Together 2021 中国开发者生态峰会
  8. 【专栏】核心篇07| Redis “jio”美的集群模式
  9. java中的nio是啥,java中的NIO
  10. 02_基于西门子CM1241的ModbusRTU串口通讯实现