漏洞介绍

Apache Flink 是一个开源的分布式流处理和批处理大数据计算引擎。

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

漏洞靶场

使用vulhub的靶场:

使用环境为flink 1.11.2

vulhub-master/flink/CVE-2020-17518/

启动靶场环境:

1
docker-compose up -d

环境启动后,访问 http://your-ip:8081 即可查看到 Apache Flink 的管理页面。

漏洞原理

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

img

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

img

发送请求

1
http://192.168.159.132:8081/jobmanager/logs/..%2f..%2f..%2f..%2fetc%2fpasswd

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\AbstractHandler.java#L163-L168

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\router\RoutedRequest.java#L48

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\router\RouteResult.java#L77-L79

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\cluster\JobManagerCustomLogHandler.java#L53-L59

读取文件内容作为响应。

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\cluster\AbstractJobManagerFileHandler.java#L59-L79

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\router\RoutedRequest.java#L48

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\router\RouterHandler.java#L73-L90

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

img

C:\Users\LENOVO.m2\repository\org\apache\flink\flink-shaded-netty\4.1.39.Final-11.0\flink-shaded-netty-4.1.39.Final-11.0.jar!\org\apache\flink\shaded\netty4\io\netty\handler\codec\http\QueryStringDecoder.class#L85-L91(需用Maven下载包)

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\router\Router.java#L228, L232

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

img

flink-1.11.2\flink-runtime\src\main\java\org\apache\flink\runtime\rest\handler\router\Router.java#L251-L267

漏洞复现

通过以下 URL 可以读取服务器上的 /etc/passwd 文件内容:

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

image-20250509211059627

poc

QmF0c3UK/CVE-2020-17519 (github.com)

1
python CVE-2020-17519.py -u http://192.168.159.132:8081 -fp /etc/passwd

image-20250509220340955

参考

https://github.com/vulhub/vulhub/blob/master/flink/CVE-2020-17519/README.zh-cn.md

Apache Flink CVE-2020-17518、17519 漏洞分析 - FreeBuf网络安全行业门户