漏洞触发点
/servlet/~ic/bsh.servlet.BshServlet
漏洞利用
直接访问该可执行执行java代码执行命令
![](https://img.haomeiwen.com/i2818913/d43c8a384fa314d6.png)
漏洞分析
通过访问的页面访问的url路径在servlet下,查看web.xml其对应的servlet-name为NCInvokerServlet
![](https://img.haomeiwen.com/i2818913/cd4a6da9e3f73734.png)
对应的类为nc.bs.framework.server.InvokerServlet
![](https://img.haomeiwen.com/i2818913/288fb0c53b1e4f07.png)
跟进到该类,该类所有的get和post操作都被doAction函数处理
![](https://img.haomeiwen.com/i2818913/4d07fb3d33ead75a.png)
跟进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方法进行处理
![](https://img.haomeiwen.com/i2818913/7c8b670298596c59.png)
跟进getServiceObject方法,看下核心处理代码
![](https://img.haomeiwen.com/i2818913/62e3d1d78c3e1187.png)
来分别实例代码解释一下上面的描述,跟进serviceObjMap其为一个空map,所以其返回的结果为空
![](https://img.haomeiwen.com/i2818913/b71534e0a37be6c6.png)
通过moduleName获取Container对象,调用的是BusinessAppServer的getContainer方法,跟进该方法,该方法为重载方法,我们查看参数为String类型的,可以看到该方法是通过namedModulesMap来查找moduleName对应的值的,返回类型为Container
![](https://img.haomeiwen.com/i2818913/5c6ef1d4e9abdcbe.png)
Continer类我没找到,不知道什么情况,看倒包是没问题的,有懂的老哥DD一下(反编译不完全导致的吗?)
![](https://img.haomeiwen.com/i2818913/78565310d38414a0.png)
不过不影响审计,获取到Container后调用lookup方法查找serviceName,然后返回给retObjet,
判断retObject是否为空,不为空则将moduleName:serviceName作为key,retObject作为value并返回
![](https://img.haomeiwen.com/i2818913/42ae7d40855175e2.png)
接着往下走回到InvokerServlet,在该方法的最下方通过反射调用retObject的doAction方法,并进行了执行,至此调用就结束了
![](https://img.haomeiwen.com/i2818913/71cff64fed2894b8.png)
接下来就该看看ic,bsh.servlet.BshServlet到底是什么了
Ic为用友nc的一个module模块
![](https://img.haomeiwen.com/i2818913/ae5ef968e3894780.png)
,bsh.servlet.BshServlet位于home目录下lib包中的bsh-2.0b1.jar包中,定位到该servlet
该方法通过bsh.script传过来的值,判断传过来的值是否为空,不为空则传入evalScript
![](https://img.haomeiwen.com/i2818913/accb53f718b6132d.png)
跟进evalScript,最终调用了var8的eval方法处理了var1也就是我们传过来的命令
![](https://img.haomeiwen.com/i2818913/242ec65cb04f9884.png)
在整个的分析过程中我们可以得知moduleName参数对整个调用时没啥影响的(前提是存在的module目录),所以这里可以将ic改为任意存在的module名字,也可进行访问执行命令
例如访问一个不存在的module
http://10.211.55.15/servlet/~t00ls/bsh.servlet.BshServlet
![](https://img.haomeiwen.com/i2818913/0018ae76a9d60db5.png)
访问其他存在的module
http://10.211.55.15/servlet/~ali/bsh.servlet.BshServlet
![](https://img.haomeiwen.com/i2818913/89fd429ab428b095.png)
可用的moduleName
![](https://img.haomeiwen.com/i2818913/91f5c0ee446335ab.png)
网友评论