长亭百川云 - 文章详情

漏洞复现|Apache Flink(CVE-2020-17519)漏洞分析

小陈的Life

80

2024-07-13

戳上面的蓝字关注我们哦!


01 漏洞简介

在昨日(2021/1/5),Apache Flink发布安全更新,修复了由蚂蚁安全非攻实验室发现的2个高危漏洞:

CVE-2020-17518:通过构造恶意的http header可实现远程文件写入。

CVE-2020-17519:攻击者可通过REST API使用../跳目录实现任意文件读取。

02影响范围

CVE-2020-17518:

Apache Flink 1.5.1-1.11.2

CVE-2020-17519:

Apache Flink 1.11.0,1.11.1,1.11.2

03 CVE-2020-17519漏洞复现

漏洞路径

/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd

04 CVE-2020-17519漏洞分析

漏洞出现在Jobmanager的REST API上

经过错误定位后发现调用栈是在

org.apache.flink.runtime.rest.handler.util.HandlerUtils#transferFile

方法。

于是从网上下载相关二进制和源码程序到本地:

下载路径:https://archive.apache.org/dist/flink/flink-1.11.2/

在Linux上搭建web环境,本机Win10通过IDEA远程Debug。

只需修改远程Flink的conf/flink-conf.yaml文件,添加如下内容:

`# jobmanager debug port``env.java.opts.jobmanager: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5006"``# taskmanager debug port``env.java.opts.taskmanager: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005"`

随后在本机的IDEA上添加一个Remote容器,参数如下图所示:

因为这里只需要jobmanager,只需attach相关端口即可。

并在transferFile函数上下断点,并访问漏洞poc。

我查看调用栈发现上层函数是

org.apache.flink.runtime.rest.handler.cluster.AbstractJobManagerFileHandler#respondToRequest

函数第一行

File file = getFile(handlerRequest);

就组合路径,跟进getFile查看

org.apache.flink.runtime.rest.handler.cluster.JobManagerCustomLogHandler#getFile

获取到的filename正好是可以跨级读取文件的恶意payload

回到刚才的HandlerUtils类

定义了HttpResponse类**,并设置text/plain**等信息

继续跟进发现if分支

`ctx.write(`            `new DefaultFileRegion(fileChannel, 0, fileLength), ctx.newProgressivePromise())`            `.addListener(completionListener);`

这里的逻辑是先判断是否启用SSL,这里走到if分支中,可以看到这里是通过Netty的零拷贝技术来写入ctx中的。简单过一下零拷贝过程。

核心内容是Netty的零拷贝技术:
1.第一步是通过RandomAccessFile以r的方式打开一个文件, 然后可以通过RandomAccessFile.getChannel()来获取一个FileChannel对象。

2.有了FileChannel对象,即可以使用DefaultFileRegion来封装这个FileChannel,即:

new DefaultFileRegion(fileChannel, 0, fileLength)

可以直接将内容拷贝到jvm中,再到最后ctx.writeAndFlush刷新输出到页面。

至此便是整个CVE-2020-14519任意文件读取漏洞的流程。

最后写下Netty整个http返回报文的执行流程

`HttpResponse response = new DefaultHttpResponse(msg.getProtocolVersion(), HttpResponseStatus.OK);``response.headers().set(HttpHeaders.Names.CONTENT_TYPE,"text/html; charset=UTF-8");``//添加头部信息``ctx.write(response);``//添加正文信息``ctx.write(Unpooled.copiedBuffer("This is response", CharsetUtil.UTF_8));``//最后记得flush``ChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);``//关闭连接``future.addListener(ChannelFutureListener.CLOSE);`

整体漏洞定位不难,就是对Netty不太熟悉,还需要多实操分析。


相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2