Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998

昨天 Apache Flink 出的两个漏洞(CVE-2020-17518/CVE-2020-17519),比较类似,原理也很简单,这里简单分析一下。

环境

已有漏洞环境的盆友可越过这节,直接看漏洞部分。

JDK装好图片[1]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

Flink安装包地址:https://archive.apache.org/dist/flink/flink-1.11.2/

为同时满足两个漏洞环境,这里安装1.11.2版本

图片[2]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

解压缩

# tar -zxvf flink-1.11.2-bin-scala_2.11.tgz

图片[3]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

修改配置文件conf/flink-conf.yaml,中jobmanager.rpc.address参数为本地服务器IP地址

jobmanager.rpc.address: 192.168.18.169

添加远程调试参数

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

启动Flink服务

# cd bin
# ./start-cluster.sh

图片[4]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

看看开放了哪些端口:5005、5006是配置的debug端口,8081是webUI访问端口,6123是JobMamanger进行RPC通信的端口

图片[5]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

访问服务

图片[6]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

停止Flink服务

flink启动会把启动的进程的ID存到一个文件中,相关配置在bin/config.sh 文件中,默认是“/tmp”,由于是临时目录,会被系统清理,存放的进程ID就找不到了,也就没法关闭集群了。

直接执行关闭指令,会发现关闭不了

图片[7]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

怎么做?

新建一个目录 /usr/local/flink-1.11.2/tmp 来存放启动的进程的ID

修改 bin/config.sh 文件,为DEFAULT_ENV_PID_DIR 参数指定为新建的路径

DEFAULT_ENV_PID_DIR="/usr/local/flink-1.11.2/tmp" 

图片[8]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

重新执行关闭指令:

# ./stop-cluster.sh 

图片[9]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

远程调试

上文远程Flink服务的配置文件 flink-conf.yaml 中已经配好了远程调试参数,开启了5005、5006调试端口。

图片[10]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

本地IDEA打开目标版本源码,这里是1.11.2,创建Remote配置,指定Host和Port,这里调试 jobmanager,选择对应的端口。

图片[11]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

开启远程调试

图片[12]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

CVE-2020-17518

Flink 在 1.5.1 版本中引入了一个 REST handler,这允许攻击者将已上传的文件写入本地任意位置的文件中,并且可通过一个恶意修改的 HTTP 头将这些文件写入到 Flink 1.5.1 可以访问的任意位置。

影响范围:1.5.1 <= Apache Flink  <= 1.11.2

快速复现

  1. 利用一:文件上传

编辑请求数据包,上传 /tmp/veraxy 文件

POST /jars/upload HTTP/1.1
Host: 192.168.18.169:8081
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------13247690941547071692111317477
Content-Length: 248
Origin: http://192.168.18.169:8081
Connection: close
Referer: http://192.168.18.169:8081/


-----------------------------13247690941547071692111317477
Content-Disposition: form-data; name="jarfile"; filename="../../../../../../tmp/veraxy"
Content-Type: text/plain


Veraxy!!!
-----------------------------13247690941547071692111317477-

图片[13]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

图片[14]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

2. 利用二:文件覆盖

若上传路径已有文件,将覆盖其内容。

图片[15]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

图片[16]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

分析

查看该漏洞相关邮件,已经指出commit地址

图片[17]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

移步commit,提出是上传功能的校验问题,并指出这里会提供两个测试案例

图片[18]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

测试代码再次给出提示,修改文件名添加 ../

图片[19]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

我们找到系统的上传功能

图片[20]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

传个测试文件,是 /jars/upload 接口

图片[21]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

官方文档对该接口的使用说明

图片[22]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

在处理上传路径的地方打断点

图片[23]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

获取filename

图片[24]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

resolve()解析方法接收filename,与系统路径拼接

图片[25]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

dest存储拼接后上传路径,传给 fileUpload.renameTo()方法

图片[26]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

上传文件,并重命名保存至另一个路径以做缓存

图片[27]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

缓存文件存在时间很短,只有30s

图片[28]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

此时系统已按目标路径写入文件

图片[29]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

新版本修复

对上传路径做了处理

图片[30]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

org.apache.flink.runtime.rest.FileUploadHandler#channelRead0() 对传入的filename进行截断,只取末尾的文件名,传递的../ 和目录名 均被忽略

图片[31]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

resolve()方法接收到的文件名只有结尾部分,与系统路径拼接后返回

图片[32]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

赋值给dest路径变量,执行重命名缓存行为并上传文件

图片[33]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

CVE-2020-17519

Apache Flink 1.11.0中引入的更改(包括1.11.1和1.11.2)允许攻击者通过JobManager进程的REST接口读取JobManager本地文件系统上的任何文件。

影响范围:Apache Flink 1.11.0、1.11.1、1.11.2

快速复现

遍历文件 /etc/passwd

http://192.168.18.171:8081/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd

图片[34]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

分析

查看该漏洞相关邮件,同样指出commit地址

图片[35]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

移步commit,细节描述的很清晰了,指出通过二次编码后的 ‘..%252f’ 来替换 ‘../’ 可以遍历logs文件夹的目录结构,比如:”/jobmanager/logs/..%252f/README.txt” 将返回README.txt的内容

图片[36]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

文档找一下/jobmanager/logs 接口说明

图片[37]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

发送请求

http://192.168.18.169:8081/jobmanager/logs/..%252f..%252f..%252f..%252fetc%252fpasswd

系统接收请求,对request进行解析,初始化HandlerRequest对象

图片[38]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

routedRequest.getRouteResult()获取result,decodedPath为一次解码后,pathParams存放二次解码后结果

图片[39]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

图片[40]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

将HandlerRequest传递给org.apache.flink.runtime.rest.handler.cluster.JobManagerCustomLogHandler#getFile,获取pathParams中存放的filename,拼接logDir返回路径。

图片[41]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

读取文件内容作为响应。

图片[42]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

不懂就问

routedRequest.getRouteResult()获取的result是如何初始化的?包括其中的解码流程。

图片[43]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

回溯到org.apache.flink.runtime.rest.handler.router.RouterHandler#channelRead0(),这里routeResult为后面routedRequest中this.result原型,看routeResult如何初始化

图片[44]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

url一次解码的地方,赋值给this.path返回

图片[45]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

将method、path、queryParameters传送给router.route()方法来初始化一个routeResult对象

图片[46]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

其中decodePathTokens(path)将path进行了二次解码,与此同时会判断路径中的“/”并截断,我们传入“/”的编码形式免于拦截,随后的for循环中再次进行解码,成功返回一个正常路径。

图片[47]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

新版本修复

跟17518修复方式一致,通过 File.getName()只取末尾文件名

图片[48]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

org.apache.flink.runtime.rest.handler.cluster.JobManagerCustomLogHandler#getFile方法,

路径中的 ../和目录名都被忽略,filename只剩下了文件名

图片[49]-Apache Flink CVE-2020-17518、17519 漏洞分析 – 作者:18334650998-安全小百科

总结

Apache Flink 服务大多开放在内网,漏洞影响面不算太大,但大数据时代随着该应用的使用量日益增多,其漏洞还是值得重视的。

来源:freebuf.com 2021-01-10 17:06:21 by: 18334650998

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论