0x01 通告
2019年9月17日,泛微OA更新了一个安全问题,修复了一个远程代码执行漏洞。
泛微e-cology OA系统存在java Beanshell接口,且可被未授权访问,攻击者调用该Beanshell接口,可构造特定的HTTP请求绕过泛微本身一些安全限制进行命令执行。
从 resin.conf 的配置文件中可以看到resin关于servlet的处理
<web-app id="/" root-directory="D:/WEAVER/ecology"> <servlet-mapping url-pattern='/weaver/*' servlet-name='invoker'/> </web-app>
Web Application Server提供了一种默认的访问servlet的方式,即通过 http://www.test.com/com.xxxServlet
的方式直接访问,而不需要定义 <servlet/>和<servlet-mapping/>
,这个功能称为 invoker servlet 。
比如Tomcat在conf/web.xml里面注释掉了:
<!-- <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> -->
当然与配置文件相关的还有web.xml,可以从web.xml文件中看个例子,比如 DownloadDeptLayoutServlet 对应的class对象是 weaver.org.layout.DownloadDeptLayoutServlet 。而它对应的url路径是 /weaver/weaver.org.layout.DownloadDeptLayoutServlet 。也和resin中的默认配置其实是一致的。
<servlet> <servlet-name>DownloadDeptLayoutServlet</servlet-name> <servlet-class>weaver.org.layout.DownloadDeptLayoutServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DownloadDeptLayoutServlet</servlet-name> <url-pattern>/weaver/weaver.org.layout.DownloadDeptLayoutServlet</url-pattern> </servlet-mapping>
这个ecology中 /ecology/classbean/ 下文件均为编译后的java源码,而.jsp代码好像基本没啥可看的,所以挖洞的时候可以关注这个 classbean 下的 .class 文件,以及lib下的jar包本身的问题,还有resin下lib中的jar的问题。当然由于是servlet,所以路由寻找问题功能入口,只要关注相关java类中doget或者dopost方法是否存在漏洞。
问题出现在 resin 下 lib 中的 bsh.jar 文件里,问题类 bsh.servlet.BshServlet ,可以看到 doGet 方法从 getParameter 中接收到一些参数,然后整个Request请求会交给 evalScript 方法来进行处理。我们可以看到这个接口没有进行任何权限校验,根据上述分析的路由,这个地方可以被未授权触发
跟进 evalScript 方法,调用 localInterpreter.eval(paramString); ,而 localInterpreter 是 interpreter 实例化对象。
这里看个bsh用法的例子,下面这个例子执行结果是输出hello:
Interpreter interpreter = new Interpreter(); String s = "return /"hello/""; try { Object object=interpreter.eval(s); System.out.println(object.toString()); } catch (EvalError e) { e.printStackTrace(); }
所以我们可以知道bsh中的eval方法可以执行一些java代码
eval返回值为Object,可以通过eval()求文本表达式的值或者运行脚本; 如: interpreter.eval("import java.util.*;");//引入utilinterpreter.eval("import com.xxx.function.*;");//引入自己的function包interpreter.eval("Test.getName()");//执行Test类的getName()方法
所以到了这里实际上漏洞已经很明显了。
由于实际泛微自身有一些全局关键字的过滤,所以需要绕一下,不过绕过方法也很简单,最后可以通过这种远程代码执行。
目前泛微官网应该是有补丁了,补丁地址:https://www.weaver.com.cn/cs/securityDownload.asp
从补丁中来看,非常粗暴,删了相关 servlet 接口了。由于泛微使用 resin 来处理 servlet ,通读架构的时候其实相关 servlet 很多没有权限校验,可能回头还会有新的问题,可以关注一下~。