雖然不是什麼新東西,但覺得有點有趣所以筆記一篇
Supervisord
Supervisord 是一個使用 Python 寫的 C/S 架構的行程管控系統,由 supervisorctl 當 CLI 界面、supervisord 當伺服端,並使用XML-RPC
來通訊,預設情況下 supervisord 監聽的是 unix socket,也可以將 listen port 改成 TCP,改成TCP後的預設 port 是 9001。
分析
先用 vulhub 將弱點環境架起來,完成後進到容器裡查看一下當前運行的行程
可以發現使用 python 執行了 /usr/local/bin/supervidord
該檔案內容為
#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from supervisor.supervisord import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())
查看 supervisord.py
的 main
function
看到 361 行執行 go
function 將設定檔帶入 class Supervisor
中,並呼叫 main
function
最後呼叫了 self.run
92 行呼叫了 options
的 openhttpservers
前往 options.py
呼叫了 make_http_servers
function 是從 http.py 來的,前往 http.py
可以看到主要處理 xml rpc 的是 supervisor_xmlrpc_handler
,前往 xmlrpc.py
處理呼叫使用 traverse
function,其中
- ob 為在哪個 namespace 中找尋
- method 為欲找尋的方法
- params 為該方法的參數
一開始的 namespace 就是 supervisord 內部 scope,也就是說只能呼叫自己的東西
傳入 rpc 呼叫的內容長的像這樣 a.b.c.d
,解析步驟為
- 將 method 用
.
拆分 - 檢查是否以
_
開頭,是則報錯 - 取得當前 namespace 的 method,不存在則預設為 None
- method 為 None 則報錯
透過 for
迴圈遞迴的取得目標 function
最後 460 行執行最終 function 並代上參數
利用
看完流程後可以知道,透過 a.b.c.d
的方式可呼叫 python runtime 的 function
-
依照CVE發現者給的 PoC 使用的是
supervisor.supervisord.options.execve
在
options.py
中有直接呼叫os.execve
的 function但使用
execve
會取代原本的 python 行程,導致程式結束若目標環境在容器中就整個都不見了
-
phiton 大神提出了兩個可能解法
os.fork
supervisord 也同樣實做的直接呼叫 os.fork 的 function,可以先 Fork 在進行其他操作,但這個方法一樣會影響容器環境warnings.linecache
另外一個可利用的 functionsupervisor.supervisord.options.warnings.linecache.os.system
options.py
使用了warnings
而裡面用到os
,如此便可直接呼叫到system
function
-
Ricter 大神補充
可以使用 supervisord 自帶的
readLog
將執行結果讀出來,用在無法 bind shell 與 reverse shell 的情況,這裡有 PoC
結論
弱點要素
- Supervisord 為存在弱點版本(3.1.2 <= Supervisord <= 3.3.2)
- 可以碰到 Supervisord 的 listen port (TCP or Unix socket)
- 帳號密碼已知或預設(預設為兩者皆空)
弱點修補
- 更新 Supervisord
- 針對 listen port 執行控管
- 複雜的帳號密碼
參考
- https://www.cvedetails.com/cve/CVE-2017-11610/
- https://www.leavesongs.com/PENETRATION/supervisord-RCE-CVE-2017-11610.html
- http://blog.nsfocus.net/supervisord-cve-2017-11610/
- http://blog.51cto.com/eth10/1955450