在白盒检测方面,我们主要基于两个自主开发的白盒引擎进行检测,一个是基于代码属性图(cpg),内部称为阿波罗,另一个是基于字节码点,内部称为冥王哈迪斯。关于冥王哈迪斯,试用版以前是开源的(https://github.com/zsdmylovee/hades),我在gitwarehouse的自述中已经详细解释过了,这里就不多介绍了。基于代码熟悉度图的漏洞检测方案相信是一些做过白盒引擎的人所熟悉的。基础理论最开始应该是witterbianYAmbluuchi在他的一篇期刊论文中提出的“用代码属性图建模和发现漏洞”,讲的是如何将源代码抽象成属性图结构,以及如何基于这个属性图挖掘漏洞。这一基础理论给了作者在白箱发动机开发上相当大的启发。难得的是,为了让外界对这个基础理论有更好的了解,它还为c/c++开辟了一个检测引擎。有兴趣可以了解一下。github地址是:https://github.com/ShiftLeftSecurity/joern.
那么如何检测基于cpg图查询方案的源代码风险呢?按照我的理解,可以分为三个阶段。第一阶段是ast信息提取。在这一部分,我们需要对第一阶段的源代码进行抽象,即将源代码抽象为ast。一般来说,这部分不需要自己实现,也不建议自己实现,找到对应的ast解析库就可以了。这里有个建议。java解析器可以用来提取Java中的单词,eclipse中的CDT库可以用来解析c/c++中的单词。
现在来说说第二阶段要怎么做。在第一阶段,我们获得了一个ast列表。基于这个ast列表,第二阶段要做的就是在每个函数的过程中构建cfg(controlflowgraph)和eog(EvaluatureOrderGraph),以及基于cfg遍历和eog遍历的dfg(dataflowgraph)。Cfg和eog很像,可以理解为程序执行路径的描述。据我所知,cfg一般是将一组执行顺序为线性的表达式组合成一个块,每个块之间通过对应的条件分支关系连接,而eog描述的是过程中每个语句和表达式之间的求值和计算关系,可以用于后续的数据流分析,但一般来说Eog更适合数据流分析,因为它直接描述了每个表达式之间的求值关系,对于cfg,我们还需要考虑块和块之间的一些数据流传递关系。当然,这只是我个人的看法。请改正任何错误。
至于数据流,如果真要扩展的话,空间很大。在这里,我将分享我在分析处理过程中遇到的一些问题,以及我的一些解决问题的思路。我们知道直接赋值肯定是数据流关系,但是在一个复杂结构的过程中,不仅仅是简单的变量被赋值,比如数组成员的访问,还有枚举器,这些也是可能影响数据流传输的中间因素。