type
status
date
slug
summary
tags
category
icon
password
最后编辑时间
Jul 31, 2023 08:54 AM
漏洞编号
No.
同步状态
状态
Author
 

前言

用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。
用友NC6.5中的nc/bs/framework/server/InvokerServlet.class 存在未授权任意类调用漏洞,该漏洞通过构造特殊的数据包调用NC自有类可导致反序列化或命令执行。其中可利用BeanShell接口执行任意命令,漏洞编号CNVD-2021-30167

安装

windows10 x64 jdk1.7.0_21
下载nc6.5,解压后启动安装脚本 path\NC6.5\yonyou_nc\setup.bat
1、全选安装产品
notion image
2、安装完成后自动启动path\yonyou\home\bin\sysConfig.bat
1)配置服务器信息,点击读取,修改需要自定义的参数后保存
notion image
2)这里不添加任何数据源(数据库)和授权,直接 部署EJB 即可
notion image
3)运行path\yonyou\home\startServer.bat 无报错即可
notion image

准备

导出目录下所有jar包,加载到idea中,配置idea远程调试参数
notion image
在启动yonyounc时添加jdwp参数
notion image

调试

  • servlet-mapping
notion image
  • poc
notion image

moduleName

根据poc在 bsh/servlet/BshServlet.class$doGet() 方法下断点,跟进到 nc/bs/framework/server/InvokerServlet.class$doAction() 方法
关键代码
pathInfo
notion image
传参结果,moduleNamealiserviceName/bsh.servlet.BshServlet
notion image
跟进 this.getServiceObject() 方法
notion image
BusinessAppServer.getInstance().getContainer() 中,根据模块名在nameModulesMap中获取对应的容器,228个模块名可利用
notion image
初始化方法中将/home/modules目录下的所有子目录放入HashMap
notion image
notion image

ServiceName兵分两路

getServiceObject之后兵分两路,主要分为两个方法触发漏洞

Service

objBshServlet@12592
接着启动线程监控器跟踪指定线程
obj对象BshServlet继承了HttpServlet 类,重写了doGet() 方法
notion image
跟进service方法:javax/servlet/http/HttpServlet.class$service()
serlvetMappings如下
notion image
notion image
经过 org/apache/catalina/connector/RequestFacade.class$getMethod() 方法之后调用当前对象BshServletdoGet方法处理
notion image
注意,如果是POST方法,同样是传递到doGet中执行
notion image
bsh/servlet/BshServlet.class$doGet()
evalScript方法
跟进到 Interpreter.class$eval() 方法
notion image
最后调用不同参数类型的eval方法
notion image
该方法创建一些新的BeanShell解释器实例,并将输入输出流、命令空间、调用堆栈等传入,逐行读取BeanShell脚本
并调用 BSHPrimaryExpression.class$eval() 方法执行命令,最后返回执行的结果var4
notion image
BSHPrimaryExpression.class$eval()方法解析出解释器对象要执行的脚本参数,反射调用exec
notion image
bsh/Name.class$invokeMethod中调用本地方法bsh/Name.class$invokeLocalMethod ,var6获取var2的类型为String,调用getCommand 方法
notion image
var7获取到执行的脚本位置/bsh/commands/exec.bsh,通过 BshClassManager.getClassManager().getResourceAsStream() 读取到该脚本内容到InputStream,之后调用bsh/NameSpace.class$loadScriptedCommand 方法加载脚本
notion image
exec.bshRuntime.getRuntime().exec执行传入的参数
notion image
后续简单看一下调用栈
返回到invokeLoaclMethod,var10为null,进入var9.invoke
notion image
跟进bsh/BshMethod.class$invoke()
notion image
notion image
invokeImpl()
notion image
这段代码定义了一个BeanShell解释器中的类BSHMethodInvocation,用于处理方法调用的执行。
invokeImpl方法中,首先获取方法返回值和参数类型,然后判断参数个数是否匹配。如果匹配,则创建一个新的命名空间对象,并设置方法参数的值。在设置方法参数的值时,如果参数类型不为空,则调用Types.getAssignableForm方法将参数转化为可赋值的形式,并调用setTypedVariable方法设置参数的值;否则,直接调用setLocalVariable方法设置参数的值。
然后,将新的命名空间对象压入调用堆栈中,并调用方法体的eval方法计算方法体的值。在计算方法体的值时,如果方法体返回一个ReturnControl对象,则将其转化为返回值,并执行相应的控制流程(如continue和break)。如果方法返回值的类型不为空,将返回值转化为可赋值的形式,并返回该值。如果返回值的类型为空,则返回Primitive.VOID对象。
 
接着执行代码块
notion image
最后调用 BSHPrimaryInvocation.class$eval() 执行 exec.bsh 中的命令

doAction

/servlet/~ic/nc.bs.framework.mx.monitor.MonitorServlet 这个payload为例
同样在InvokerServlet.class$doAction() 中通过getServiceObject获取到obj为MonitorServlet对象
notion image
之后进入adaptor.doAction ,该方法中提供了反序列化输入流的操作readObject
notion image

Reference

 
巧用snort规则关键字,让入侵检测事半功倍MiniCMS代码执行漏洞
Loading...