|【干货】Servlet内存马加载流程分析( 二 )



接下来执行createWrapper方法创建了一个wrapper 。 继续向下

接下来设置了一个ServletName和ServletClass(这里其实对应的就是web.xml中的servlet) , 继续向下

(三)addChild启动wrapper线程读取到Servlet配置之后 , 执行了addChild(wrapper)方法 , 我们跟进addChild()方法进行查看 。

我们跳到了StandardContext.addChild() , 其实servlet的添加就是在这里面进行的 。 我们继续跟进去简单看一下吧 。

我们走到了ContainerBase.addChild() , 这个类其实是一个骨架类 , 这里我们需要注意两个位置 , 一个是我们将wrapper添加到了ContainerBase的children变量中 , 另一个是我们最后执行到了child.start() , 我们继续向下查看 。

【|【干货】Servlet内存马加载流程分析】我们跳到了LifecycleBase , 这个类主要是和Tomcat的生命周期有关 , 我们跟到this. startInternal()进行查看 。

此时我们通过LifecycleBase走到了StandardWrapper.startInternal() , 查看该方法其实这里本质就是调用父类的startInternal() 线程池启动 。 我们点击去稍微看一下super.startInternal()进行查看

我们又走到了ContainerBase.startInternal() , 方法最后启动了线程 。

我们执行完addChild()方法后 , 我们回到了ContextConfig类 , 继续向下查看 , 可以看到此时执行了webxml.getServletMappings().entrySet().iterator() , 其实这里的本质是就是读取servler-mapping 。

我们跟到addServletMappingDecoded()方法 , 跳到了StandardContext. addServletMappingDecoded()方法下 , 首先将servlet-name和url-pattern添加到servletMappings下 , 然后通过findChild方法 , 找到我们之前启动的wrapper(读取之前存储到ContainerBase的children变量) , 我们跟进查看wrapper.addMapping()方法 。


我们走到了StandardWrapper.addMapping方法 。 将mapping(也就是url-pattern)添加到mappings变量下 。

二、Servlet内存马实现其实看到这里应该能明白添加servlet最关键的地方就是这个两个方法 , 所以我们接下来内存马的编写就需要一个恶意的servlet , 然后通过addChind和addServletMappingDecoded将其恶意servlet注入进去 。


最终成功实现内存马 。


结尾~~~文章里面有什么写的不对的地方 , 望师傅们多加指正 。 Servlet型内存马算是写完了 , 个人觉得Servlet内存马是这三个里面最难的 , 因为调试的时候栈里面来回的绕 , 有时候跳着跳着就乱了 , 文章里面可能有些地方有写的不对的地方 , 希望师傅们多加指正 。