漏洞复现|Apache Flink(CVE-2020-17519)漏洞分析
2021-1-6 18:14:8 Author: mp.weixin.qq.com(查看原文) 阅读量:4 收藏

上面的蓝字关注我们哦!


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 portenv.java.opts.jobmanager: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5006"# taskmanager debug portenv.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));//最后记得flushChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);//关闭连接future.addListener(ChannelFutureListener.CLOSE);

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



文章来源: https://mp.weixin.qq.com/s?__biz=MzAxNDk0MDU2MA==&mid=2247483994&idx=1&sn=4e788ca1c02564e88f8b74f33773c7e0&chksm=9b8ae2a5acfd6bb3bd3b85e834dffb38a4490c40f17772b081818dff02b607d1b5407c121725&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh