如何利用CodeQL挖掘CVE-2020-10199
文章图片
前言
挖掘Java漏洞时候存在一个痛点在已知漏洞点的情况下,如何找到可控点,以及确定一条具体的数据流.
前几天看到@Alvaro Mu?oz 利用codeql挖掘到[CVE-2020-10199]Nexus Repository Manager远程代码执行漏洞.于是就对codeql产生强烈的好奇心,怼了几天codeql语法和CVE案例。抠出挖掘该CVE的Ql代码
Codeql
对Codeql具体介绍可以参考:https://help.semmle.com/
使用codeql能够很明确搜索出方法调用的数据流, QL代码编写思路相当于在一个代码数据库中利用编写的逻辑搜索出可能的调用点。重点是确定Souce和Sink搜索逻辑.
漏洞原理简要分析
该漏洞是由于未做过滤造成表达式注入,作者确定漏洞点执行函数 buildConstraintViolationWithTemplate, 其该方法中 bean.getMessage() 返回结果 message 并未使用 stripJavaEl 方法过滤造成表达式注入
文章图片
最后调用 org.hibernate.validator.internal.engine.messageinterpolation#interpolate ,执行插入操作并解析恶意字符串,造成表达式注入.
文章图片
HelperBean bean#message
编写Codeql最重要的是先确定数据流的Sink点即污染点字段.这里跟进 org.sonatype.nexus.validation.HelperBean#getMessage 方法.返回message值.该值经由HelperBean方法传入
文章图片
Ql代码
这里直接给出代码并做简单讲解:搜索出流经 HelperBean 方法中 message 字段的数据流
isSink方法搜索逻辑: 定义参数p,该参数p由被调用的 HelperBean 方法使用且该p参数名为message
isSouce方法搜索逻辑:由于不清楚哪里数据源最终经过该sink,所以直接使用source.asExpr()调用所有可能的表达式作为数据流.
import java
import semmle.code.java.dataflow.FlowSourcesclass Config extends DataFlow::Configuration{
Config(){
this = "1"
}
override predicate isSource(DataFlow::Node source){
exists(source.asExpr())
}
override predicate isSink(DataFlow::Node sink){
exists(
Parameter p | p = sink.asParameter() and p.getCallable().getName() = "HelperBean" and p.getName() = "message"
)
}}from Config config ,DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source.getNode().getLocation(),source,sink
搜索结果 Run Query
文章图片
AbstractGroupRepositoriesApiResource#validateGroupMembers 根据搜索结果,这里最可疑的 souce 就是 AbstractGroupRepositoriesApiResource:92 .点击该结果跟进,Codeql很友好对污染点respositoryName进行标记。向上溯源得到 respositoryName 值最终由 request 中获取.
文章图片
Ql代码 现在就是需要确定 AbstractGroupRepositoriesApiResource#validateGroupMembers() 方法由哪里调用.
isSink方法搜索逻辑:定义参数p,该参数p由被调用的 validateGroupMembers 方法使用且该p参数名为request
isSouce方法搜索逻辑:这里souce原本是用Codeql自带 RemoteFlowSource 获取,但是发现并没有结果。所以这里直接用souce.asExpr()搜索全局表达式。
import java
import semmle.code.java.dataflow.FlowSourcesclass Config extends DataFlow::Configuration{
Config(){
this = "1"
}
override predicate isSource(DataFlow::Node source){
exists(source.asExpr())
}
override predicate isSink(DataFlow::Node sink){
exists(
Parameter p | p = sink.asParameter() and p.getCallable().getName() = "validateGroupMembers" and p.getName() = "request")
}}
// 得到可能可控的函数
from Config config ,DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source, sink
搜索结果 Run Query
文章图片
其中 GolangGroupRepositoriesApiResource 就是该漏洞调用的可控点.
文章图片
结语
【如何利用CodeQL挖掘CVE-2020-10199】原文有误,还请师傅们斧正。希望师傅们喜欢
推荐阅读
- 如何做一家小而精致的店(//调酒师培训chris|如何做一家小而精致的店?//调酒师培训chris 董圆)
- C语言利用UDP实现群聊聊天室的示例代码
- 2026年前美国将新增1150万个就业岗位,想要留美工作的你应该如何准备!
- python证件照换底色_python利用opencv实现证件照换底
- python|利用Python制作证件照
- 投稿|五粮液:如何走出茅台“阴影”?
- 如何构建一个快速开发框架
- 我是如何甩掉那十多斤的肉的
- 机器学习系列文章|利用随机森林对特征重要性进行评估(公式原理)
- 你是如何使用社交网络的呢()