环境配置
l 系统:Winserver2008
l 数据库:Oracle
l JDK:java 1.7
l 复现版本:yonyouNC6.5
源码分析
漏洞触发的路径为:
/servlet/~ic/bsh.servlet.BshServlet
根据漏洞的url路径,查找对应的映射
下图所示:Servlet路径下对应的servlet-name
为NCInvokerServlet
(可以看到,service和servlet下的路径都路由到了NCInvokerServlet)
NCInvokerServlet对应的servlet-class为
nc.bs.framework.server.InvokerServlet
追踪到InvokerServlet中
如下图,看到其中doPostdoGet方法
都交给了doAction处理
追踪到doAction方法:
看到获取了token、userCode两个参数并判断其是否为空
然后获取pathInfo路径信息
然后下图进入try分支,if判断pathInfo是否以”/~”开头,
moduleNmae从第三位截取pathInfo字符串,beginIndex获取moduleNmae中 “/” 的位置。
if语句判断beginIndex是否大于0,ServiceName从beginIndex的位置开始截取字符串moduleName;moduleName截取自己从0到beginIndex的长度。
所以try语句的作用就是获取
ServiceName和moduleName的值
下图判断获取的serviceName是否为空;116行serviceName中”/”的位置赋值给beginIndex
将获取的参数moduleName,serviceName调用getServiceObject方法赋值给obj
追踪到getServiceObject()方法,下图
分析getServiceObject()方法:
该方法先判断moduleName不为null进入else分支
307行serviceObjMap获取的是一个空的map,此时retObject为null
retObject为null进入if语句
309行通过getContainer方法,getContainer()通过返回一个Container类型的值
312行lookup()查找serviceName
返回retObject,if语句判断retObject是否为空,
不为空则将键值对(moduleName:serviceName)为Key,retObject为value返回retObject,将返回的赋值给obj
回到InvokerServlet类中
接下来就是if语句判断参数obj的类型,这里判断的obj有三种类型
obj为Servlet
obj为IHttpServletAdaptor
obj为剩余类型,此时我们传入的obj进入了else语句(代码下图)
obj不为空,获取了obj的class对象,进入182行的try语句
183行获取当前类的所有方法给method
method不为空,进入194行的try语句
通过反射invoke()调用了obj的执行方法
反射调用的我们URL里的方法BshServlet
BshServlet.class类中,doPost()传进的参数都去了doGet()方法中
看doGet()方法
Var3获取了用户输入的参数bsh.script,判断var3是否为空,不为空进入if语句,62行evalScript()方法处理var3参数
追入evalScript()方法,var1是我们写的参数命令,203行调用了eval()方法,执行了用户输入的命令
由于没有对用户输入的参数做过滤判断,并且使用了危险函数导致远程命令执行漏洞。
漏洞复现
访问/servlet/~ic/bsh.servlet.BshServlet
我们在script里输入别的命令语句发现他被执行了
公众号:
刑天攻防实验室
扫码关注 了解更多内容
原文始发于微信公众号(刑天攻防实验室):用友Yonyou NC6.5 远程命令执行漏洞分析复现
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论