置空鉴权字段不仅仅在登录口,在查询或鉴权处也是一种经典的测试思路,例如将jwt的加密字段置空。再比如,在个人信息查询接口置空参数以回显站点全部信息。有时,最简单的思路往往能造成最致命的安全问题。
进入目标站点熟悉业务时,发现其存在注册功能,且未注册的账户在登录时会自动注册,登录与注册实际上是同一个接口(这是后续漏洞的关键点)。
使用 Burp Suite 正常抓取注册请求包,接口为/xjky-server/xjky-biz-server/app/open/sms/registerAndLogin。请求中记录了注册手机号、短信验证码以及一个未知的tenantId。当验证码正确时,服务器会返回一个Token,后续请求需携带此Token用于身份认证,这种基于令牌的身份验证机制是许多现代应用的常见做法,其安全性至关重要。
{"openId":"307332", "password":"307332", "username":"15xxxxx454", "tenantId":"0ff61e364ea44c44a9b27c9198alcdd9"}
将该请求发送到Repeater模块进行测试,尝试将验证码字段置空,发现请求同样成功并返回了token。为确认此token是否对应新输入的手机号,进一步探索业务,发现有一个接口可以通过token回显个人信息。
替换token后,响应包中返回的loginId正是尝试注册的手机号,这表明该账号已成功被系统注册。
记录好187号码所生成的token,来到登录功能点。随意输入验证码,并拦截服务器的响应包。
将响应包的内容替换为之前任意生成的token,然后放行数据包。
此时成功登录到了187账户后台,并进入了其个人信息页面。
完成任意注册测试后,注意到登录口和注册使用的是同一套接口,只是对未注册的账号会自动完成注册。
/xjky-server/xjky-biz-server/app/open/sms/registerAndLogin
既然通过置空验证码可以实现任意用户注册并生成token,那么引申思考:如果攻击者已知一个已存在的账户(手机号),在此登录口同样置空验证码,是否也会返回该账户对应的token,从而实现账户接管呢?
为模拟此场景,正常注册了一个138账户。随后在登录口,模拟攻击者不知道验证码的情况,随意输入并拦截响应包。
直接置空验证码字段,让其不做任何校验,然后放行请求。
结果与预想一致:只要置空验证码,即可绕过登录验证环节,系统会根据提交的手机号直接生成对应的token。这意味着攻击者可以无需密码或验证码,直接实现任意用户登录,完全接管目标账户。这个案例深刻地揭示了逻辑漏洞在渗透测试中的高风险性。
|