漏洞触发点
/servlet/~ic/bsh.servlet.BshServlet
漏洞利用
直接访问该可执行执行java代码执行命令

漏洞分析
通过访问的页面访问的url路径在servlet下,查看web.xml其对应的servlet-name为NCInvokerServlet

对应的类为nc.bs.framework.server.InvokerServlet

跟进到该类,该类所有的get和post操作都被doAction函数处理

跟进doAction函数进行分析,分析一下该类的主要作用获取modulName和serviceName,该方法获取这两个参数有两种方式:
-
判断传入的uri中是否以~开头,进入到该分支进行处理
图片.png
-
直接对传入的uri进行处理,将传入的uri作为serviceName,此时的module是为空的所以是查找不到该serviceName进行调用的
图片.png
问题就出在第一个分支处理处,如果传入的uri以~开头,比如上面的payload
/servlet/~ic/bsh.servlet.BshServlet
在该分支进行处理后,ic就作为了moduleName, bsh.servlet.BshServlet就作为了serviceName,传给getServiceObject方法进行处理

跟进getServiceObject方法,看下核心处理代码

来分别实例代码解释一下上面的描述,跟进serviceObjMap其为一个空map,所以其返回的结果为空

通过moduleName获取Container对象,调用的是BusinessAppServer的getContainer方法,跟进该方法,该方法为重载方法,我们查看参数为String类型的,可以看到该方法是通过namedModulesMap来查找moduleName对应的值的,返回类型为Container

Continer类我没找到,不知道什么情况,看倒包是没问题的,有懂的老哥DD一下(反编译不完全导致的吗?)

不过不影响审计,获取到Container后调用lookup方法查找serviceName,然后返回给retObjet,
判断retObject是否为空,不为空则将moduleName:serviceName作为key,retObject作为value并返回

接着往下走回到InvokerServlet,在该方法的最下方通过反射调用retObject的doAction方法,并进行了执行,至此调用就结束了

接下来就该看看ic,bsh.servlet.BshServlet到底是什么了
Ic为用友nc的一个module模块

,bsh.servlet.BshServlet位于home目录下lib包中的bsh-2.0b1.jar包中,定位到该servlet
该方法通过bsh.script传过来的值,判断传过来的值是否为空,不为空则传入evalScript

跟进evalScript,最终调用了var8的eval方法处理了var1也就是我们传过来的命令

在整个的分析过程中我们可以得知moduleName参数对整个调用时没啥影响的(前提是存在的module目录),所以这里可以将ic改为任意存在的module名字,也可进行访问执行命令
例如访问一个不存在的module
http://10.211.55.15/servlet/~t00ls/bsh.servlet.BshServlet

访问其他存在的module
http://10.211.55.15/servlet/~ali/bsh.servlet.BshServlet

可用的moduleName

网友评论