【网络安全】Nacos Client Yaml反序列化漏洞分析
背景
Nacos 致力于幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實現動態服務發現、服務配置、服務元數據及流量管理。
Nacos 幫助您更敏捷和容易地構建、交付和管理微服務平臺。 Nacos 是構建以“服務”為中心的現代應用架構 (例如微服務范式、云原生范式) 的服務基礎設施。
Nacos是阿里巴巴于2018年開源的項目,目前在Github中已獲得 19.8kSt,由此可見其的使用廣泛程度。
未授權訪問漏洞
threedr3am師傅在去年十二月份的時候在Github上給Nacos項目提交了Bypass 認證的Issue,詳情可移步https://github.com/alibaba/nacos/issues/4593。在該Issue中提及了漏洞詳情,Nacos的認證過濾器中會判斷客戶端的User-Agent如果是以Constants.NACOS_SERVER_HEADER(Nacos-Server)開頭的話,則直接return返回。
對于上述的認證繞過漏洞爭議很大,Nacos官方起初并不認為這是一個安全漏洞的問題,不過還是在1.4.1版本中發布了漏洞修復補丁。在1.4.1版本中需要在 application.properties添加nacos.core.auth.enable.userAgentAuthWhite的屬性值為false,即可避免使用User-Agent繞過鑒權的問題,但這也引發了新的Bypass,具體的漏洞詳情可移步至https://github.com/alibaba/nacos/issues/4701,不再贅述。
客戶端Yaml反序列化
在Nacos的releases記錄中搜索 yaml 關鍵字不難發現其在1.4.2版本中有個PR更新了Yaml的安全解析:
而根據PR的描述內容可知實際上該漏洞只影響單獨使用 nacos-client SDK的用戶,原因在于spring cloud、springboot、dubbo等框架中并非使用的 AbstractConfigChangeListener 監聽配置,所以該漏洞只影響了使用AbstractConfigChangeListener監聽配置的客戶端。
漏洞分析
首先在Nacos服務端中添加一個用于測試監聽的配置:
使用Maven引入nacos-client依賴:
<dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.4.1</version> </dependency>以官方的監聽配置請求示例復現,需要修改serverAddr、dataId、group、Listener,如果配置了登陸還需要添加username和password。
// Client.java import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.config.ConfigChangeEvent; import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;import java.util.Properties;public class Client {public static void main(String[] args) throws Exception {String serverAddr = "{serverAddr}";String dataId = "{dataId}";String group = "{group}";Properties properties = new Properties();properties.put("serverAddr", serverAddr);properties.put("username", "nacos");properties.put("password", "nacos");ConfigService configService = NacosFactory.createConfigService(properties);String content = configService.getConfig(dataId, group, 5000);System.out.println(content);configService.addListener(dataId, group, new AbstractConfigChangeListener() {@Overridepublic void receiveConfigChange(ConfigChangeEvent configChangeEvent) {System.out.println(configChangeEvent);}});while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}} }然后在com.alibaba.nacos.client.config.impl.YmlChangeParser#doParse方法中打下斷點:
開啟Debug并在服務端中修改上述用于測試的配置內容為yaml反序列化的payload,該payload會加載遠程的jar包并運行主類的代碼。
點擊發布后即可命中斷點
再根據堆棧信息進行回溯的調試,首先在ConfigFactory#createConfigService方法中通過反射獲取com.alibaba.nacos.client.config.NacosConfigService類的實例對象并返回該對象。
在NacosConfigService的構造器中實例化ClientWorker對象
跟進ClientWorker的checkConfigInfo方法
傳入的對象為ClientWorker的內部類LongPollingRunnable對象,會調用其run方法。
而run方法就是nacos客戶端的長輪詢監聽,run方法中會循環調用cacheDatax.checkListenerMd5方法,而CacheData對象是從ClientWorker對象的cacheMap屬性中獲取的。
而cacheMap中緩存的CacheData對象是在客戶端添加監聽的時候寫入的
再回到ClientWorker.LongPollingRunnable#run方法中,前面說到其會調用checkListenerMd5方法,該方法中會調用safeNotifyListener方法,并傳入監聽配置的dataId、group、content(修改的新內容)、type、md5及CacheData.ManagerListenerWrap對象。
在safeNotifyListener方法中調用了ConfigChangeHandler#parseChangeData方法解析數據,傳入的參數listenerWrap.lastContent為修改前的內容,content為修改后的內容,type為數據類型(TEXT/JSON/XML/YAML/HTML/Properties)。
其會調用YmlChangeParser#doParse方法
YmlChangeParser#doParser方法中觸發Yaml反序列化漏洞,請求遠程的Jar包并執行。
再次聲明,該漏洞只影響使用AbstractConfigChangeListener監聽器的客戶端,原因如下:
漏洞修復
在1.4.2版本中已修復了該漏洞,修復方法為使用SnakeYaml提供的SafeConstructor解析Yaml配置。
實戰應用
在實際的滲透測試中如果獲取了Nacos Server控制臺權限的話,不妨可以嘗試修改已有的配置為Yaml Payload進行盲打客戶端的攻擊。但通常情況下的Springboot或SpringCloud都可以集成使用Nacos,所以這種場景下一般不會出現存在漏洞的情況。
最后
關注私我獲取2021最新【網絡安全學習資料·攻略】
總結
以上是生活随笔為你收集整理的【网络安全】Nacos Client Yaml反序列化漏洞分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【CTF解题】BCTF2018-hous
- 下一篇: 【网络安全】php代码审计-sql注入进