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很多没有权限校验,可能回头还会有新的问题,可以关注一下~。