通过Sanitizer让CodeQL查询到正确的path
一、问题描述
大家在使用CodeQL复现历史漏洞时,可能经常会碰到查询出来的Path和实际执行的不一致的问题,例如:
在复现Log4j2 RCE漏洞时,我们debug实际执行的路径是这样的:
但是在CodeQL查询出这样一条Path
实际执行时调用的是DefaultReliabilityStrategy
类的log
方法,但是查询结果中却是AwaitCompletionReliabilityStrategy
类的
二、问题分析
通过观察源码
我们发现这两个类都实现了LocationAwareReliabilityStrategy
接口
所以在分析以下代码时:
1 | ((LocationAwareReliabilityStrategy) strategy).log(this, getName(), fqcn, location, marker, level, message, throwable) |
CodeQL不能确定此处实际使用的是哪个实现了LocationAwareReliabilityStrategy
接口的实现类,所以数据流会传播到LocationAwareReliabilityStrategy
接口的每一个实现类,这样会造成一个时间的问题。CodeQL对此做了一些优化,通过降低精度来提升了速度。
详细的原因在大佬在这篇文章中说明:CodeQL能找到log4shell(CVE-2021-44228)漏洞吗? - 跳跳糖 (tttang.com)
但是大佬没说怎么解决
三、问题解决
经过探究,我认为既然已经知道实际执行不到这些类,我们可以写一个清洗器(Sanitizer),将实际执行不到的清洗掉。
例如,针对以上问题,我们可以写下面这样的清洗器:
1 | override predicate isSanitizer(DataFlow::Node node) { |
这样,我们就能清洗掉实际执行不到的类
另外,在查找解决问题的资料时发现一个CodeQL团队的回答,也对我们有些帮助
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 少年锦时!
评论