spring部分运行机制
我们在controller处下断点

可以看到红框是涉及spring的部分,因为调用栈的帧顺序是从下往上,也就是下面的先运行,我们从下往上看。
可以看到先run运行起来,然后进入process部分,在进入service部分,进入invoke部分,进入dofilter部分,在返回到service部分,然后就进入了spring中,spring中继续请求,到doDispatch中进行请求的处理。


可以看到DispatcherServlet类中的doDispatch方法进行处理web请求。

这个方法中用handle()进行处理request和response,并且用 mappedHandler.getHandler()获取了mappedHandler的Handler。
那么老样子,我们先不看调用,先看handle()的参数中的mappedHandler.getHandler()。我们看看mappedHandler是干什么的。

这里用了getHandler(processedRequest),那么我们跳入。

可以看到这里对handlerMappings(处理器映射)进行了遍历,调用mappedHandler的getHandler()方法对processedRequest进行了遍历。
handlerMappings介绍:

接着我们继续跟进mapping.getHandler。


跟进之后是个接口,那么找其实现。

我们进入AbstractHandlerMapping。

可以看到用到了getHandlerInternal()方法。

可以看到对mappingRegistry(spring的路径注册)上了锁,acquireReadLock方法用于获取读锁,如果持有写锁的线程数量或请求读锁的线程数大于0则让线程进入等待状态,releaseReadLock方法用于释放读锁,将读锁线程数减一并唤醒其它线程,acquireWriteLock方法用于获取写锁,如果持有读锁的线程数量或持有写锁的线程数量大于0则让线程进入等待状态。releaseWriteLock方法用于释放写锁,将写锁线程数减一并唤醒其它线程。mappingRegistry中存有路由信息如下:

继续回到getHandlerInternal看看。

因为lookupHandlerMethod()涉及请求,传入的参数是lookupPath和request,那么我们看看他是干嘛的。

阅读这一块代码,这里通过mappingRegistry获得请求映射地址,如果directPathMatches不为null,则调addMatchingMappings()进行添加路由,这里可以理解成 集合中的每一个RequestMappingInfo均会和request进行匹配,匹配上的话就创建一个Match对象并加入Match对象集合。
然后就是Matches的校验了,如果为null,就用mappingRegistry.getRegistrations()注册,Match集合不为空则从Match集合中找到最匹配的Match对象,并返回该Match对象的HandlerMethod对象。
也就是说模拟注册向mappingRegistry中添加内存马路由,就能注入内存马。

在AbstractHandlerMethodMapping中就提供了MappingRegistry添加路由。但是该类为抽象类。它的子类RequestMappingHandlerMapping能进行实例化。



RequestMappingInfoHandlerMapping也是抽象类,所以只能用RequestMappingHandlerMapping的registerMapping方法去进行注册(也就是通过AbstractHandlerMethodMapping的子类,也就是实现类去进行注册)。

一个spring内存马的生成
获取webApplicationContext
之前写的tomcat内存马,也是先需要获得容器的context对象。在tomcat中获得的是standardContext,spring中获取的是WebApplicationContext。

可以看到初始化WebApplicationContext的过程,那么如何获得WebApplicationContext呢?

那么这样就可以得到WebApplicationContext对象了,当然不只这一种方法,我们先往下走。
注册Controller
有了WebApplicationContext,接下来便是注册Controller,在第一部分《spring部分运行机制》中我们说了在AbstractHandlerMethodMapping中就提供了MappingRegistry添加路由。但是该类为抽象类。它的子类RequestMappingHandlerMapping能进行实例化。

可以看到RequestMappingHandlerMapping的registerMapping有三个

文章详细阐述了SpringMVC中DispatcherServlet的doDispatch方法如何处理web请求,通过调用链分析了请求从处理到路由的全过程。然后讨论了如何利用Spring的机制在运行时动态注册Controller,生成内存马,包括获取WebApplicationContext、注册Controller和处理方法的步骤。在过程中遇到了获取WebApplicationContext的方法选择问题,最终找到了可行的解决方案。文章还提到了实战中可能遇到的问题,如Fastjson漏洞利用,并给出了相关代码示例。
最低0.47元/天 解锁文章
173万+

被折叠的 条评论
为什么被折叠?



