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

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

缺陷编号:wooyun-2015-0153650

漏洞标题:Inwatch-InHealth客户端接口若干安全bug打包(任意手机号抢占/重置任意用户密码/手机号改绑/短信轰炸等)

相关厂商:Inwatch-InHealth

漏洞作者: kevinchowsec

提交时间:2015-11-27 09:44

修复时间:2016-01-11 15:32

公开时间:2016-01-11 15:32

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:19

漏洞状态:未联系到厂商或者厂商积极忽略

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-11-27: 积极联系厂商并且等待厂商认领中,细节不对外公开
2016-01-11: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

Inwatch-InHealth客户端版本:2.4.2

详细说明:

话不多说,buglist:
1、短信验证码泄露(任意手机号抢占+任意手机号重置密码)
2、验证不严谨+重放攻击(重置任意手机号密码)
3、未限制用户批量发送数据(短信轰炸)
4、验证不严前端欺骗登录(任意用户登录+劫持任意用户手机绑定号)

漏洞证明:

1、短信验证码泄露(任意手机号抢占+任意手机号重置密码)
http://common.api.inwatch.cc/sms/checkcode
“/sms/checkcode”接口请求服务端,服务端会返回明文短信验证码。
无论注册手机号,改绑手机号、重置密码等需要用到短信验证码的功能都用到这个接口,高危。

短信验证码泄露1.png


短信验证码泄露2.png


下面是重置某用户密码成功截图:

S51107-180658.jpg


2、验证不严谨+重放攻击(任何时候重置任意手机号密码)
找回密码功能,输入要重置密码的手机号,输入任意短信验证码,提交请求,服务端返回错误数据,拦截该返回数据并修改其中false为true,放行给客户端,客户端欺骗绕过短信验证码验证。

验证不严谨+重放攻击1.png


验证不严谨+重放攻击2.png


验证不严谨+重放攻击3.png


来到重置顺利来到重置密码界面:

S51109-130802.jpg


输入新密码,改密码完成:

验证不严谨+重放攻击4.png


PS:值得一提的是,服务端没有及时失效上述该密码修改请求数据↑,导致重放攻击,任何时候恶意攻击者只需要提交该请求即可重置该手机用户的账户密码。
3、未限制用户批量发送数据(短信轰炸)
未限制用户批量发送数据,发送短信接口可通过脚本或工具批量提交,导致目标手机遭短信验证码短信的骚扰。

未限制用户批量发送数据1.png


4、验证不严前端欺骗登录(任意用户登录+劫持任意用户手机绑定号)
其实和第3点是一样的性质。
客户端登录界面随意输入账号密码,按登录发起请求。
服务端返回错误消息,不存在的用户或者是密码错误。
拦截服务端返回消息,并修改其中user_id为任意用户ID,这里以ID为1的用户来做例子。
将修改后的返回数据放行给客户端,客户端被欺骗,通过认证,成功进入ID为1的账户。

前端欺骗登录1.png


前端欺骗登录2.png


前端欺骗登录3.png


接下来就是利用客户端发起对ID为1的用户的操作(让客户端算sign),如存储用户基本资料。

前端欺骗登录4.png


修改ID为1的用户的头像,用户名等等信息。

前端欺骗登录5-篡改用户资料.png


修改成功:

前端欺骗登录5-篡改用户资料2.png


S51109-123242.jpg


接下来还可以改绑用户手机号,以ID为52509的用户为例子。

前端欺骗登录5-重置任意用户手机号1.png


改绑用户手机号成功,完全夺取该账户的使用权(最终用13777777779又改绑了一次)。

前端欺骗登录5-重置任意用户手机号2.png


S51109-135946.jpg


检测匆忙,没有尽全,手上没有实体智能手表,无法深挖其他与手表手环相关的接口。

public class HttpManager
{
public static String API_VERSION = "1.0.0";
public static String APP_KEY = "299829742";
public static final String APP_KEY_INTERNATIONAL = "867628694";
public static final String APP_KEY_LOCAL = "299829742";
public static String APP_SECRT = "c433fe38f5c431fe2b540ad483cddb23";
public static final String APP_SECRT_INTERNATIONAL = "cf4a32ef7e675f363651f7142c233c1d";
public static final String APP_SECRT_LOCAL = "c433fe38f5c431fe2b540ad483cddb23";
public static final String COMMON_API_INTERNATIONAL = "http://in.common.api.inwatch.cc/";
public static final String COMMON_API_LOCAL = "http://common.api.inwatch.cc";
public static final String SHOUHUAN_API_INTERNATIONAL = "http://in.shouhuan.api.inwatch.cc/";
public static final String SHOUHUAN_API_LOCAL = "http://shouhuan.api.inwatch.cc";
public static String kCommonApi = "http://common.api.inwatch.cc";
public static String kPassportApi = "http://passport.api.inwatch.cc";
public static String kShouhuanApi = "http://shouhuan.api.inwatch.cc";
public static TreeMap<String, String> sign;

static
{
kGetAccessToken = "/grant/token?format=json";
kRefreshAccessToken = "/grant/refeshtoken?format=json";
kGetTokenInfo = "/grant/get_token_info?format=json";
kUpdateAppVersion = "/app/version?format=json";
kUpdateRomVersion = "/firmware/version?format=json";
kGetMobileCheckCode = "/sms/checkcode?format=json";
kCheckCodeExist = "/sms/checkcodeexist?format=json";
kRegister = "/user/mobileregister?format=json";
kAppKey = "/user/apps?format=json";
kCheckUserExist = "/user/exist?format=json";
kModifyPassword = "/user/password?format=json";
kModifyCellPhone = "/user/mobile?format=json";
kFindBackPassword = "/user/getpassword?format=json";
kCheckIsFirstLogin = "/user/login?format=json";
kThirdFirstSet = "/user/mobilepassword?format=json";
kUpdataInfo = "mapi/update_user_info/";
kUserThirdPartLogin = "/user/oauth?format=json";
kUserThirdPartBind = "/user/sharebind?format=json";
kUserLogout = "/userdevice/create";
kBindList = "/user/bindlsit?format=json";
kBindThird = "/user/loginbind?format=json";
kRemoveBindThird = "/user/removebind?format=json";
kHaveBoundThird = "/user/exist/thirdlogin?format=json";
kDeepRepor = "/report/index";
ktrend = "/trend/index";
kcheckTrend = "/trend/check";
kUploadUserInfo = "/user-info/create";
kUpdateUserInfo = "/user-info/update";
kGetUserInfo = "/user-info";
kUpdateBindStatus2 = "/device-bind/bind-watch";
kUnbindBindStatus = "/device-bind/unbind";
kGetSolution = "/solution";
kGetNewHealthPlan = "/health-plan/get-newest-by-uid";
kHealthPlanCreate = "/health-plan/create";
kHealthPlanDetailCreate = "/health-plan-detail/create";
kHealthPlanDetailCustomTarget = "/health-plan-detail/custom-target";
kGetHealthActionCat = "/health-action-cat";
kGetFoodList = "/food";
kGetFoodCombo = "/food-combo";
kGetFoodComboDetail = "/food-combo-detail";
kGetSuggestion = "/food-suggestion";
kGetSportList = "/sport";
kUploadSleepLog = "/sleep-log/create";
kUploadSportLog = "/sport-log/create";
kUploadDietLog = "/diet-log/create";
kUploadDietLogDetail = "/diet-log/create";
kUploadDietStat = "/diet-stat/create";
kUploadSportStat = "/sport-stat/create";
kUploadSleepStat = "/sleep-stat/create";
kUploadEventLog = "/user-event-log/update";
kUploadEventLogList = "/user-event-log/create-list";
kGetEventLog = "/user-event-log";
kGetStatLog = "/user-stat-log";
kUploadStatLog = "/user-stat-log/update";
kUploadUserSetting = "/user-setting/update";
kGetUserSetting = "/user-setting";
kParameterError = 400;
kTokenIllegal = 4031;
kOverMaxNumberOfRequests = 4032;
kRequestSeqNumberIllegal = 4033;
kLackBusParameters = 301;
kParameterFormatError = 303;
kLackSystemParameters = 302;
kOperationFailed = 500;
kPasswordError = 631;
kUserLocked = 632;
kUserNotActivated = 633;
kSuccessExecution = 0;
}

修复方案:

1、不要返回短信验证码给客户端;
2、加了sign就不能保证安全,所有接口还要加身份认证(token);
3、主要请求增加业务流水号,及时失效请求,防止重放攻击;

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


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝