51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

浅谈帆软在Windows下写文件RCE姿势

写在前面 {#写在前面}

之前上一篇文章中浅析帆软FineVis默认插件前台RCE提到jasper依赖没被加载,当时只是简单做了测试,没有具体看为什么jsp未被解析,只是疑惑了下tomcat下jspservlet配置明明正确配置页面却直接返回空(没有考虑到编译报错这一层问题),今天无意间看到星球有师傅分享了如何解析jsp的过程,写文章同时也顺带分享下如何实现RCE的两种姿势

当然至于为什么是windows,之前的两篇漏洞文章中都有提到过,因为linux的默认可以解析,这一点从官方文档就能知道(https://help.fanruan.com/finereport/doc-view-822.html),要求自行下载tomcat部署启动,因此在linux下也不存在这个jsp的解析问题%EF%BC%8C%E8%A6%81%E6%B1%82%E8%87%AA%E8%A1%8C%E4%B8%8B%E8%BD%BDtomcat%E9%83%A8%E7%BD%B2%E5%90%AF%E5%8A%A8%EF%BC%8C%E5%9B%A0%E6%AD%A4%E5%9C%A8linux%E4%B8%8B%E4%B9%9F%E4%B8%8D%E5%AD%98%E5%9C%A8%E8%BF%99%E4%B8%AAjsp%E7%9A%84%E8%A7%A3%E6%9E%90%E9%97%AE%E9%A2%98)

如何在Windows下完成RCE {#如何在Windows下完成RCE}

SPI {#SPI}

由于这个插件写文件比较特殊,遇到不存在的文件夹会自动创建,因此我们很容易利用Java中SPI的机制完成RCE的利用,比较简单,这里不再展开,不熟悉的可以去网上了解下以前SpringBoot FatJar的一些打法

加载JSP {#加载JSP}

比较抽象直接访问jsp能访问到但是页面为空白

image-20240814192427045

之前没细细研究,想着这里不是有对应的servlet配置吗,直到看到了别的星球发了一篇文章才发现,原来启动时使用了Tomcat().start()启动

image-20240814113439923

这和Springboot整合tomcat启动时使用的方法一致,也算学到了点新东西(之前一直以为只能通过BootStrap启动),具体可以看看这篇文章了解https://blog.csdn.net/qq_33468007/article/details/107620507

接下来调试可以看到确实触发了jsp编译的过程,但是报错了

image-20240814192049879

经过最终调试发现,报错是因为javax.servlet.jsp.JspFactory#deflt为null

image-20240814193334916

因此让jsp加载就要解决这个属性为null的问题,而这个来源于JasperInitializer初始化的过程,它是Tomcat内部的一个初始化器,本就是用于处理支持JSP页面的,在静态块中设置了这个factory,而由于启动方式的原因这个类并没有被初始化

image-20240814193839453

因此要解析jsp,就需要解决这个类初始化的问题,因此我们需要找到一个前台的类帮助我们完成任意类加载

而在com.fr.web.controller.common.FileRequestService#getFile中就存在我们需要的初始化过程

简单看看下面的代码通过PlatformScaffold.getReflectionProvider().classForName(path)完成了任意类的初始化,因此也就成功解决了javax.servlet.jsp.JspFactory#deflt为null的问题

|------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public void getFile(HttpServletRequest req, HttpServletResponse res, @RequestParam("path") String path, @RequestParam(value = "type",required = false) String type, @RequestParam(value = "parser",required = false) String parser, @RequestParam(value = "tag",required = false) String tag) throws Exception { xxxxxx省略部分代码xxxxxx } } else if (fileType == FileType.CLASS) { String charset = PlatformScaffold.getBasicConfigProvider().getServerCharset(); // 参数path可控制初始化的类 TextGenerator generator = (TextGenerator)Reflect.on(PlatformScaffold.getReflectionProvider().classForName(path)).create().get(); ((HttpServletResponse)res).setContentType(generator.mimeType() + ";charset=" + charset); String text = generator.text(req, (HttpServletResponse)res); PrintWriter writer = WebUtil.createPrintWriter((HttpServletResponse)res); writer.write(text); writer.flush(); writer.close(); } } catch (Exception var17) { FineLoggerFactory.getLogger().error(var17.getMessage(), var17); } finally { if (wrappedResponse != null) { wrappedResponse.finishResponse(); } } } else { throw new SpecialCharProhibitException(); } } |

因此只需要通过一个请求

|-----------|-------------------------------------------------------------------------------------------------------| | 1 | http://xxxx/webroot/decision/file?path=org.apache.jasper.servlet.JasperInitializer&type=class |

这一次我们的jsp成功被渲染了

image-20240814194504349

赞(1)
未经允许不得转载:工具盒子 » 浅谈帆软在Windows下写文件RCE姿势