您好,登錄后才能下訂單哦!
SaltStack遠程執行代碼多個高危漏洞的示例分析,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
在對CVE-2020-17490和CVE-2020-16846進行分析后,發現CVE-2020-17490的補丁存在未修補完全的情況,導致wheel_async仍然存在未授權訪問,可以調用wheel模塊中的方法,基于此對SaltStack的wheel模塊中的方法進行分析,最終發現加載配置模塊存在模板注入,可以實現未授權遠程代碼執行。
SaltStack是VMware子公司,其產品用于運維管理,能夠支持數萬臺服務器,主要功能是配置文件管理和遠程執行命令,十分易用且強大,在github有11.4k star。
SaltStack只用python開發,采用C/S架構,其中Server被稱為Master,Client被稱為Minion,即一個Master能夠向多個Minion下發配置文件,遠程執行命令。SlatStack是系統總稱,主要有salt、salt-master、salt-minion、salt-api等程序組成,其中salt-master和salt-minion的功能為從指定路徑讀取配置文件并啟動。salt-master監聽4505和4506端口,分別用于發布消息和接受監控數據。
salt程序可以調用大量函數,并可以指定minion或指定一組minion作為目標。salt-api可以使用cherrypy或tornado來對外提供REST接口,默認使用cherrypy。
本文主要對salt-master和salt-api展開討論。
文中指定代碼位置采用以下約定:FileLocation:Classname.method()或FileLocation:Method()
通過分析CVE-2020-25592的
https://gitlab.com/saltstack/open/salt-patches/-/blob/master/patches/2020/09/25/3002.patch
可以發現 ,補丁通過調用認證模塊對SSH方法進行權限認證,而salt/salt/netapi/init.py:NetapiClient.run()方法通過getattr動態調用NetapiClient類中的方法,并將args和kwargs作為參數傳入。
該類中可調用的方法有
- local- local_async- local_batch- local_subset- runner- runner_async- ssh- wheel- wheel_async
經過分析,其中,wheel_async方法存在未授權調用,其他方法(除去SSH)均為生成一個job到zeromq,其后進行消費者再進行認證,而wheel_async異步調用wheel包中的方法。
調用鏈如下:
salt/salt/netapi/init.py:NetapiClient.run() ? salt/salt/netapi/init.py:NetapiClient.wheel_async() ? salt/salt/wheel/init.py:WheelClient.cmd_async() ? salt/salt/client/mixins.py:AsyncClientMixin.asynchronous()
salt/salt/client/mixins.py:AsyncClientMixin.asynchronous()
這里的目標函數是self._proc_function,low參數為POST可控參數,fun參數的值在salt/salt/wheel/init.py:WheelClient.cmd_async()方法中通過low參數的fun鍵獲取。
這里通過salt/salt/client/mixins.py:AsyncClientMixin._proc_function()函數調用salt/salt/client/mixins.py:SyncClientMixin.low(),并通過該函數使用args參數和kwargs參數動態調用wheel包中的方法。
salt/salt/client/mixins.py:SyncClientMixin.low()
可調用的方法如下:
config.applyconfig.update_configconfig.valueserror.errorfile_roots.findfile_roots.list_envfile_roots.list_rootsfile_roots.readfile_roots.writekey.acceptkey.accept_dictkey.deletekey.delete_dictkey.fingerkey.finger_masterkey.genkey.gen_acceptkey.gen_keyskey.gen_signaturekey.get_keykey.printkey.listkey.list_allkey.master_key_strkey.name_matchkey.rejectkey.reject_dictminions.connectedpillar_roots.findpillar_roots.list_envpillar_roots.list_rootspillar_roots.readpillar_roots.write
其中salt/salt/wheel/pillar_roots.py:write()方法存在任意寫入文件漏洞,不過需要__opts__["pillar_roots"]中的路徑存在。
這里的讀文件是沒有辦法利用的,由于是異步調用,所以返回的是jid和tag,通過jid和tag去查詢任務執行的結果時是有認證的。
salt/salt/wheel/pillar_roots.py:write()
通過—log-level=debug參數開啟debug模式,定位到了master自動加載的邏輯。
salt/salt/master.py:Maintenance.run()
從代碼中可以看出,每一個self.loop_interval將循環一次,loop_interval在配置文件中可以配置,默認為60s。通過debug發現在salt.daemons.masterapi.clean_old_jobs中讀取minion配置文件。
調用棧如下:
salt/salt/daemons/masterapi.py:clean_old_jobs() ? salt/salt/minion.py:MasterMinion.init() ? salt/salt/config/init.py:minion_config()
在 salt/salt/minion.py:MasterMinion.init()中發現,自動加載值加載grains相關的參數,grains為saltstack收取各個minion中系統信息的功能。
salt/salt/minion.py:MasterMinion.init()
salt/salt/config/init.py:minion_config()
可以看到minio在加載配置文件的時候調用了一個很誘人的方法apply_sdb(),這個方法解析配置中以sdb://開頭的字符串。
salt/salt/config/init.py:apply_sdb()
salt/salt/utils/sdb.py:sdb_get()
在這個函數中sdb://aaaa/bbbb字符串,saltstack將會在配置文件中找aaaa這個配置項,并讀取其中driver字段,賦值給fun變量,經bbbb賦值給query參數。最后的salt.loader.sdb(opts, fun, utils=utils)是一個動態調用,通過LazyLoader加載fun變量值對應的方法,并調用,其中LazyLoader將加載salt.sdb包下的所有文件,并調用其中的get方法。
經過查找,最終定位到salt/salt/sdb/rest.py文件。
salt/salt/sdb/rest.py:query()
在這里,key為上述字符串中bbbb的值,可以看到這里還接收形如bbbb?ccc=ddd的參數,并且通過**key_vars傳遞到compile_template方法中。
這里的render使用的是jinja,眾所周知,jinja是可以進行模板注入的,也就是說,在模板可控的情況下,如果不存在過濾,將可以執行任意代碼,并且這里傳入的參數是profile[key]['url'],也就是配置文件中aaaa配置項中bbbb字典url的值。compile_template函數詳情如下:
salt/salt/template.py:compile_template()
這里的render調用的是salt/salt/renderers/jinja.py中的render方法,調用鏈如下:
salt/salt/template.py:compile_template() ? salt/salt/utils/templates.py:JINJA() ? salt/salt/utils/templates.py:wrap_tmpl_func() ? salt/salt/utils/templates.py:render_jinja_tmpl()
最后調用到render_jinja_tmpl中的template.render()方法,在此處渲染模板,此中并未對傳入的參數進行過濾,可以進行模板注入。
但自動加載的邏輯中未加載master的配置文件,但經過翻找,發現某個方法調用了master_config方法,master_config和minion_config一樣,都調用了apply_sdb()方法,從而能夠實現未授權RCE。
盡快更新官方補丁。
如果沒有用到wheel_async模塊,可以在salt/netapi/init.py中將其入口刪除。
關于SaltStack遠程執行代碼多個高危漏洞的示例分析問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。