内存马

前置知识

组件

  1. 根据协议、端口找到连接器(如8080找到http连接器),连接器确认Service组件,Service组件又包含一个Engine
  2. Mapper组件根据域名确认Host容器
  3. Mapper根据url路径确认context容器
  4. Mapper查询web.xml,根据Servlet映射确认具体的Wrapper和Servlet

(Context是上下文,包含servlet运行环境,wrapper是包装器,负责管理一个servlet的装载、初始化等操作)

tomcat加载

对于内存马,比较重要的是standardContext这个上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
private void configureContext(WebXml webxml) {
......

// 遍历web.xml中的Context参数,并将它们添加到Context中
Iterator var2 = webxml.getContextParams().entrySet().iterator();
for (Entry<String, String> entry : webxml.getContextParams().entrySet()) {
context.addParameter(entry.getKey(), entry.getValue());
}

......

// 添加Filter定义
for (FilterDef filter : webxml.getFilters().values()) {
if (filter.getAsyncSupported() == null) {
filter.setAsyncSupported("false");
}
context.addFilterDef(filter);
}

// 添加Filter映射
for (FilterMap filterMap : webxml.getFilterMappings()) {
context.addFilterMap(filterMap);
}

......

// 添加应用监听器
for (String listener : webxml.getListeners()) {
context.addApplicationListener(listener);
}

......

// 添加Servlet定义
for (ServletDef servlet : webxml.getServlets().values()) {
Wrapper wrapper = context.createWrapper();
// Description is ignored
// Display name is ignored
// Icons are ignored

// jsp-file gets passed to the JSP Servlet as an init-param

if (servlet.getLoadOnStartup() != null) {
wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue());
}
if (servlet.getEnabled() != null) {
wrapper.setEnabled(servlet.getEnabled().booleanValue());
}
wrapper.setName(servlet.getServletName());
Map<String,String> params = servlet.getParameterMap();
for (Entry<String, String> entry : params.entrySet()) {
wrapper.addInitParameter(entry.getKey(), entry.getValue());
}
wrapper.setRunAs(servlet.getRunAs());
Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs();
for (SecurityRoleRef roleRef : roleRefs) {
wrapper.addSecurityReference(
roleRef.getName(), roleRef.getLink());
}
wrapper.setServletClass(servlet.getServletClass());
MultipartDef multipartdef = servlet.getMultipartDef();
if (multipartdef != null) {
long maxFileSize = -1;
long maxRequestSize = -1;
int fileSizeThreshold = 0;

if(null != multipartdef.getMaxFileSize()) {
maxFileSize = Long.parseLong(multipartdef.getMaxFileSize());
}
if(null != multipartdef.getMaxRequestSize()) {
maxRequestSize = Long.parseLong(multipartdef.getMaxRequestSize());
}
if(null != multipartdef.getFileSizeThreshold()) {
fileSizeThreshold = Integer.parseInt(multipartdef.getFileSizeThreshold());
}

wrapper.setMultipartConfigElement(new MultipartConfigElement(
multipartdef.getLocation(),
maxFileSize,
maxRequestSize,
fileSizeThreshold));
}
if (servlet.getAsyncSupported() != null) {
wrapper.setAsyncSupported(
servlet.getAsyncSupported().booleanValue());
}
wrapper.setOverridable(servlet.isOverridable());
context.addChild(wrapper);
}

// 添加Servlet映射
for (Entry<String, String> entry :
webxml.getServletMappings().entrySet()) {
context.addServletMappingDecoded(entry.getKey(), entry.getValue());
}

......

}

实现

JAVA内存马系列 - cmisl_破站

GitHub - W01fh4cker/LearnJavaMemshellFromZero: 【三万字原创】完全零基础从0到1掌握Java内存马,公众号:追梦信安


内存马
http://example.com/2025/01/16/内存马/
作者
z2zQAQ
发布于
2025年1月16日
许可协议