记一次获取网站鉴权的实践操作
在移动端平台(就先简称PF平台)上新应用,一般会经过安全校验。所以每一个应用都会采取一些攻击策略手段来保障应用的安全稳定。一般是 xss 攻击,不过针对今天举例的系统(就先简称为BCP)他做的还是很棒的。还有就是鉴权登录,这也是主要能攻破BCP系统的关键点。
另外本文只分析破解过程,对于原理和一些名词不做过多解释。
工具
fillder(抓包工具,这个其实有没有都行,主要是爬取接口的时候,可以比较直观的。)
谷歌浏览器
PostMan(用户发送接口请求)
过程分析
xss 诱导攻击
BCP系统这方面考虑的比较全面,暂且不分析了。
最高鉴权获取
这也是本篇文章要重点分析的部分。
起因
打开PF平台上的 BCP 系统,在网络请求中发现,这样一个接口:
url:
jtsi/UserLogin/login
method:POST
作用:用户登录,返回用户登录信息
参数字段:
字段 取值(爬取发现) 类型 是否必填 说明 deviceType D string 是 判断设备类型,貌似没啥用,不断啥就用D这个值就行 domain BCPWx string 否 用来判断是否是在 移动端 ,移动端就是 BCPWx,PC端啥也不写 timestamp 1595656277 number 是 时间戳,应该是为了标识当前调用的事件 login_type login_user string 是 用户登录类型,用 login_user 这个就行 passwd BcpWx%3c6****efbe84%3E string 是 用户的密码(为了安全,我进行了脱密处理),下文会重点分析,这个字符串,关键突破点 t 1595656277720 number 是 又来一个时间戳,不过这个是 毫秒 的,上面的 timestamp 是秒的。 返回参数:
{ "Result": true, "ReturnCode": "000", "ReturnMessage": { "orgName": "******团队", "roleIds": ["-1"], "statusMsg": "登录成功", "domain": "", "sessionId": "5d1116fb-****-****-94ac-96fa19c75d30", "userName": "***", "userId": "********", "orgId": "**********", "depts": { "num": "1", "**********": "****团队" }, "status": 1, "token": "5d1116fb-****-****-94ac-96fa19c75d30" } }
从上面的请求参数开始分析:
第一步:
BCP 系统的致命漏洞,也是出现在此。用户在经过 PF 平台的 Oauth2 授权后,竟然没有直接返回 token 值,而是在Oauth2 授权拿到 用户id 后,神奇的是又去请求 BCP 系统自带的登录接口(UserLogin/login),那么他就需要账号密码。
第二步:
通过第一步发现,系统在登陆前,肯定会有一次获取用户密码的请求,果不其然,在进一步抓包处理后(由于只是在手机端简单的注入了一些检测脚本,所以并没有拿到返回密码的接口,或者说在我注入脚本之前,系统就已经完成了获取密码操作,所以我一开始没有拿到这个接口),发现了一个返回用户密码的接口,这个稍后再分析。
第三步:
第二步说到:会有一个返回密码的接口,那么我们要想获取到最高权限(系统管理员)的密码,就必然得知道管理员(当然我是知道,该系统的管理员的用户id,不知道也没关系,下文会讲解怎么拿)的账号密码。
获取管理员账号1
上文说到,我已经知道管理员的帐号了,因为就是系统负责人,我肯定是知道的,假如说我不知道,怎么办?
大家知道,在公司内部一般的员工编号都是数字或者有规律的,最主要的就是可以根据自己的账号去推演,毕竟破解最多的就是穷举法。
为了更好的解释怎么获取管理员账号,我在下文会提到根据什么原理拿到管理员账号,此处假设我们知道管理员的账号了。
寻求加密突破点
我们再一次回到,在移动端发现的登录接口,分析一下,此处的请求参数:passwd,为了解释简单,我们假设一个账号:12345678,他的密码(当然我是根据他的规律来生成的)是:BcpWx%3c25d55ad283aa400af464c76d713c07ad%3e,根据经验(也是常识),在接口传参数的时候我们不会有%号的出,也是我们是通过抓包拿到的字符串,肯定也会经过URL编码,那么我们反编码一下:BcpWx<25d55ad283aa400af464c76d713c07ad>,这个规律就有了,密码应该是加密过的,加密过后应该是:25d55ad283aa400af464c76d713c07ad,然后开发者又在密码前后分别加了 “BcpWx<” 和 “>”,当然如果你经验够足的话,一眼就能判断 “>” 的url 编码 为 %3c, “< “的编码为 %3e。那么就只剩下 25d55ad283aa400af464c76d713c07ad ,咋一看,这咋解密,无从下手,上文说到,破解、攻击等手段常用的就是穷举法(没想到第一个 BCP 就中了),最常用的就是 md5 加密,不管三七二十一,先来一波md5加密:
字符串 | 12345678 |
---|---|
16位 小写 | 83aa400af464c76d |
16位 大写 | 83AA400AF464C76D |
32位 小写 | 25d55ad283aa400af464c76d713c07ad |
32位 大写 | 25D55AD283AA400AF464C76D713C07AD |
注:因为我知道我得账号是多少,所以我是拿自己的 userid,通过md5 去比对的。
到此返现了惊喜,md5 加密的 32位 小写 结果不就是,我们在接口中发现的字符串吗?其实到这里就已经攻破了,当前这是后来分析,才知道的。假设不知道的时候,我们就需要进一步发现。因为这个只是在移动端登录的接口,即使知道了,操作起来不太方便。接下来我们登录 PC 端看看会有怎样的发现。
获取管理员账号 2
接上上小结的内容,假设你不知道管理员账号怎么办?PC 端登录,是用的公司统一认证平台,当登录到,总共请求了 3(有一个接口请求了两次,重复的,阿西吧) 接口:/jtsi/UserLogin/getHeadImg
、/jtsi/JTApplicationService/getApplications
和/jtsi/JTApplicationService/getApplicationMenu
第一个顾名思义,请求头像的不用管,重点部分是后边两个接口,超管也顾名思义,啥都管,那么他的应用和菜单树肯定是最多的,只要根据公司的员工编号,写个批量小脚本,哪个员工的菜单树最多,他肯定就是超管了就没跑了。也有的是 admin 这种。
接口小技巧
根据pc端的接口请求可以看出,BCP 系统鉴权使用的 token (移动端)和 sessionId (PC端),这也就不难理解,为啥在 jtsi/UserLogin/login
的返回结果中,为啥既有 token 还有 sessionId 了,但是他忽略了一点,也是 BCP 系统最致命的。从返回结果我们可以得出两个结论:
- 后台生成 token 和 sessionId 的机制一样,只是换了个名称而已
- 我们可以利用移动端生成的密码,去获取 token,而此处的 token也即 PC端的 sessionId
为什么要用移动端的接口去生成 token(sessionId ) 呢,上文说到,PC端登录和移动端登录时,是通过 domain 参数来判断的,加入我们不填 domain 参数,你会发现,用 md5 生成的密码对 PC 端的登录接口没用的,这也引发了我继续探寻下去的兴趣。