In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces how to bypass and analyze the history of Weblogic XML RCE bypass from CVE-2019-2725. The content is very detailed. Interested friends can use it for reference. I hope it will be helpful to you.
From CVE-2017-3506 as the starting point to the present, weblogic has revealed a large number of deserialization loopholes one after another, and a large part of these deserialization vulnerabilities are carried out around XMLDecoder patches and patches, so the author takes CVE-2017-3506 as the starting point, to the recent CVE-2019-2725 to talk about the sewing and mending of weblogic on XMLDecoder in the past two years.
Get to know XMLDecoder
First, take a look at the official documentation of XMLDecoder, as follows:
The XMLDecoder class is used to read XML documents created using XMLEncoder for a purpose similar to ObjectInputStream. For example, the user can use the following code snippet to read the first object defined in the form of an XML document (written by the XMLEncoder class):
XMLDecoder d = new XMLDecoder (new BufferedInputStream (new FileInputStream ("Test.xml"); Object result = d.readObject (); d.close ()
As a researcher of java deserialization, there should be a hint of excitement at the sight of the readObject () function, which at least means we've found the entrance.
Regardless of the use on weblogic, let's construct a special poc.xml file, let XMLDecoder parse it, and take a look at the process.
/ bin/bash-c ls
Then write a simple demo that uses XMLDecoder to parse xml files
Import java.beans.XMLDecoder;import java.io.*;public class Main {public static void main (String [] args) throws IOException, InterruptedException {File file = new File ("poc.xml"); XMLDecoder xd = null; try {xd = new XMLDecoder (new BufferedInputStream (new FileInputStream (file);} catch (Exception e) {e.printStackTrace ();} Object S2 = xd.readObject () Xd.close ();}}
Because the command execution will be triggered, first put a breakpoint on the start function of ProcessBuilder and take a look at the call stack
Our focus is on the process of instantiating the class from xml to ProcessBuilder, so to follow up on the DocumentHandler class, let's take a look at some core functions
First you see the constructor, and you see that different Handler are defined for different tags.
Let's take a look at the startElement function, which is used to instantiate the corresponding Element and set Owner and Parent to the current handler. For Owner and Parent, directly refer to the content written by @ fnmsd:
Parent
The parent of the outermost tag's ElementHandler is null, followed by the ElementHandler corresponding to the upper tag.
Owner
ElementHandler: fix owner as the DocumentHandler object to which it belongs.
DocumentHandler: owner is fixed as the XMLDecoder object to which it belongs.
Then take a look at the endElement function
He will directly call the endElement function of the corresponding ElementHandler, with the following code
After a series of getValueObject calls to Handler, we arrive at the getValueObject function of ObjectElementHandler and pass the value in our tag to the Expression class within that function
After calling the getValue method, the instance of the ProcessBuilder class is returned successfully
Then return to VoidElementHandler and pass the start function over, call the start function, and the command executes successfully.
Finally, add a flow chart of XMLDecoder parsing xml given by @ fnmsd to deepen the understanding.
CVE-2017-3506
As you can see in the previous section, XMLDecoder can cause command execution by constructing a special xml file when parsing xml. Next we can take a look at the command execution vulnerability CVE-2017-3506 caused by XMLDEcoder in the first weblogic.
Go to POC first.
/ bin/bash-c open / Applications/Calculator.app/
We only follow the call chain to XMLDecoder.readObject (), because the rest is from the previous section.
In the processRequest function, the incoming payload is split and the real xml is handed over to the readHeaderOld function for processing
The readHeaderOld function passes the real xml to XMLDecoder, and instantiates XMLDecoder to call its readObject function in a series of subsequent calls, resulting in command execution.
CVE-2017-10271
After the CVE-2017-3506 burst, let's take a look at the official patch, the code is as follows:
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);}}
The patch is very simple. Once the label is object, the system reports an error, so the second version of poc,CVE-2017-10271 is immediately released:
/ bin/bash-c open / Applications/Calculator.app/
At first glance, this poc is exactly the same as CVE-2017-3506. The only difference is
Has become
Just that the tag type of the class has changed from object to void, let's take a look at the source code of VoidElementHandler:
You can see that VoidElementHandler is a subclass of the ObjectElementHandler class, which explains why replacing object tags with Void tags can also cause command execution.
CVE-2019-2725
More than a year later, CVE-2019-2725 revealed that the loophole should be divided into two parts.
1. Newly exposed component with deserialization _ async
2. Patch of CVE-2017-10271 is bypassed
First of all, let's take a look at the first point, make a breakpoint on the start function of ProcessBuilder, and first take a look at the call chain of the async component when dealing with xml (the old rule only goes to the XMLDecoder.readObject function)
To quote the analytical thinking of Liao Dashen, the request will be processed through the 21 Handler registered by webservice. If you take a look at the HandlerIterator class, you can find the corresponding 21 Handler.
Of the 21 Handler, AsyncResponseHandler should be the one we focus on. Follow in and take a look at the handleRequest method of the source code
You can see that if you want the program to go down, you have to make sure that var2 has a value, that is, RelatesTo has a value, which is why payload has
Xx xx
The reasons for these two lines.
About the use of WS-Addressing, you can also refer to the official documentation (https://www.w3.org/Submission/ws-addressing/), which is helpful for a deep understanding.
After going through various Handler, we go to WorkAreaServerHandler, split the xml, and the next call is the same as before (xml is given to XMLDecoder, calling the readObject method)
After analyzing the async components, we come to another question: how to bypass the patch of CVE-2017-10271. Let's take a look at the patch content first.
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."); } 这次的补丁内容我们文字化一下: 1、 禁用 object、new、method 标签 2、 如果使用 void 标签,只能有 index 属性 3、 如果使用 array 标签,且标签使用的是 class 属性,则它的值只能是 byte 这次的补丁可以说是比上一次严格的多,前两点虽然很大程度上限制了我们不能随意生成对象,调用方法,但好在还有一个 class 标签可以使用,最关键的还在于第三点,它限制了我们的参数不能再是 String 类型,而只能是 byte 类型,所以我们的思路只能从这一点出发,整理一下思路,我们要寻找的是这样一个类: 1、 他的成员变量是 byte 类型 2、 在该类进行实例化的时候就能造成命令执行。 于是便有了 oracle.toplink.internal.sessions.UnitOfWorkChangeSet 来满足我们的需求。 看一下构造函数,该类会对传给它的 byte 值进行反序列化,可以看到这是一个标准的二次反序列化,于是满足二次反序列的 payload 应该都可以用,如 AbstractPlatformTransactionManager、7u21 等等。 具体 payload 如下: oracle.toplink.internal.sessions.UnitOfWorkChangeSet -84 ... ... 关于二次反序列的原理不再一一分析,大佬们早已经给出了非常详尽的解释,有兴趣可以去廖大神的博客(http://xxlegend.com)学习一下,也可以选择读一下 ysoserial 的 7u21 模块代码就 ok。 针对此次漏洞,官方给出的修复补丁处理比较简单,禁用 class 标签。 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("class")) { throw new IllegalStateException("Invalid element qName:class"); } 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 i = 0; i < attributes.getLength(); ++i) { if (!"index".equalsIgnoreCase(attributes.getQName(i))) { throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(i)); } } } if (qName.equalsIgnoreCase("array")) { String attClass = attributes.getValue("class"); if (attClass != null && !attClass.equalsIgnoreCase("byte")) { throw new IllegalStateException("The value of class attribute is not valid for array element."); } String lengthString = attributes.getValue("length"); if (lengthString != null) { try { int length = Integer.valueOf(lengthString); if (length >= WorkContextXmlInputAdapter.MAXARRAYLENGTH) {throw new IllegalStateException ("Exceed arraylength limitation");} this.overallarraylength + = length; if (this.overallarraylength > = WorkContextXmlInputAdapter.OVERALLMAXARRAYLENGTH) {throw new IllegalStateException ("Exceed overallarray limitation.");}
However, there is one thing to mention about the 7u21 module. The 7u21 module will eventually generate the _ bytecodes variable of the TemplatesImpl object into an object dynamically, so the static block and constructor of this class will be executed automatically, and this class can be constructed by the attacker at will, resulting in command execution.
Because the payload of this vulnerability is written by byte, and because the exploit class is generated dynamically, it is troublesome to analyze the attacker's code, so here is how to restore the attacker's code in payload.
1. Enable weblogic remote debugging and type the breakpoint in the start function of the ProcessBuilder class (because the attack class has been dynamically generated, but the code cannot be viewed directly in the compiler)
2. Use the jps-l command to view the pid of weblogic
3. Run the sudo java-cp $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB command to view the memory of the corresponding PID
4. Search for dynamically generated classes in memory, generate class files, decompile them, and you can see the custom classes written by attackers.
CVE-2019-2725 bypass
Recently, the poc of CVE-2019-2729 has been circulated on the Internet as follows:
Oracle.toplink.internal.sessions.UnitOfWorkChangeSet...
When I first got the poc, I took a look at the idea, because the tag was banned, so I bypassed the patch. The train of thought is relatively clear, through Class.forName (classname) to get the class we want, so as to bypass the problem that class tags are banned.
But when I first saw this poc, my first question was, can array actually use the method attribute? So I immediately took a look at the contents of the ArrayElementHandler class.
Only the length tag is supported, but it is a subclass of NewElementHandler, so take a look at NewElementHandler
The class tag is supported, but it is a subclass of ElementHandler, so take a look at ElementHandler.
It was found that it did not support the method attribute in the end.
Immediately go to my own environment to try, can not reproduce successfully, once thought that this poc is a fake, but then thought about it, my environment only 1.7and 1.8jdk, may be the jdk version is too high, immediately to 1.6 try, sure enough, reproduce successfully, it seems that 1.6 XMLDecoder code and 1.7\ 1.8 is not the same.
Follow up the XMLDecoder of jdk 1.6. according to the principle, write a simpler poc.xml, and test demo to continue to use the first chapter.
Java.lang.ProcessBuilder / bin/bash-c open / Applications/Calculator.app/
It is found that the XMLDecoder code of jdk1.6 is much simpler, there is not so much ElementHandler at all, and it is directly handled in the code of ObjectHandler.
And the treatment of the label, it can also be said to be very simple, take a look at startElement
Public void startElement (String var1, AttributeList var2) throws SAXException {. String var8 = (String) var3.get ("method"); if (var8 = = null & & var6 = = null) {var8 = "new";} var4.setMethodName (var8);. } else if (var1 = = "array") {var14 = (String) var3.get ("class"); Class var10 = var14 = = null? Object.class: this.classForName2 (var14); var11 = (String) var3.get ("length"); if (var11! = null) {var4.setTarget (Array.class); var4.addArg (var10); var4.addArg (new Integer (var11));}
I only intercept the key part of the code here, first of all, you can see that the code simply does not matter what your tag is, as long as there is a methond attribute, it will be counted as your method name, and if your tag is an array tag, and there is no class attribute, it will automatically give you a Class, which perfectly fits the needs, so you can directly get the class we need through Class.forName.
This bypasses the filtering of class tags, but can only be used in 1. 6 jdk.
Thinking and summing up
According to the sewing and patching of weblogic anti-sequence vulnerabilities caused by XMLDecoder in recent years, we can see that although bypass poc emerges one after another, the scope of utilization is getting narrower and narrower, from the beginning of all jdk common to the following 7u21 can be used successfully, and then to the recent bypass can only be successfully used in 1.6. we can see that keeping a high version of jdk version can effectively prevent java deserialization attacks. At the same time, for basically unused weblogic components, it is better to delete them if you can.
This is the history of how to bypass and analyze Weblogic XML RCE from CVE-2019-2725. I hope the above content can be helpful to you and learn more. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.