用友NC6.5未授权命令执行漏洞分析(CNVD-2021-30167)

漏洞触发点

/servlet/~ic/bsh.servlet.BshServlet

漏洞利用

直接访问该可执行执行java代码执行命令


图片.png

漏洞分析

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


图片.png

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


图片.png

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

跟进doAction函数进行分析,分析一下该类的主要作用获取modulName和serviceName,该方法获取这两个参数有两种方式:

  1. 判断传入的uri中是否以~开头,进入到该分支进行处理


    图片.png
  2. 直接对传入的uri进行处理,将传入的uri作为serviceName,此时的module是为空的所以是查找不到该serviceName进行调用的


    图片.png

    问题就出在第一个分支处理处,如果传入的uri以~开头,比如上面的payload

/servlet/~ic/bsh.servlet.BshServlet

在该分支进行处理后,ic就作为了moduleName, bsh.servlet.BshServlet就作为了serviceName,传给getServiceObject方法进行处理

图片.png

跟进getServiceObject方法,看下核心处理代码
图片.png

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

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

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

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

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

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

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

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

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

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

可用的moduleName
图片.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容