本文涉及到三种越权思路,每种方式分别对应了一个实际的案例分享。这是自己在平时的测试中积累并值得分享的一些测试经验,可能不能将问题探究到多深入,希望文中的思路能有所用。
0x01 修改返回包的越权 前情提要“修改返回包”这个越权的应用场景是一个请求使用加密算法加密请求的应用系统,测试过程中几乎所有的请求均加密,返回包为明文,此处可以使用如下案例中的方式进行越权测试。
案例分享功能“我的账户”处可以查看当前账户下挂的所有账户对应的信息,同时通过卡片详情可以查看卡片的“账户详情”,以及之后的明细交易,余额等多个功能点。此处以“账户详情”功能为例。
首先需要选择“我的账户”,该系统每个POST请求,格式都是同样的加密方式进行,如下所示,参数也只有RSA。
POST /users/cardcenter.do HTTP/1.1 HOST: 1.1.1.1 RSA=WEFGH%^UYBF&HF)WHG($@hh9h9HG)FKJHSKGBGIEBUGIBG(&S(GHEW(*GHHG)))但是请求返回的信息是明文返回,因为前端展示需要从上一个请求的json数据中提取有效信息,用于其中。
此处问题也就出在这里,下一步的“账户详情”的请求,直接使用前端标签中的value卡号进行查询相关数据,那么,通过修改上一请求的返回包内容,即可为下一请求的水平越权做铺垫。
”我的账户“原请求为:
POST /users/cardcenter.do HTTP/1.1 HOST: 1.1.1.1 RSA=ERfiegiue478y784goehghoHIGUIUUg*^&^(*^%fdfgsg)”我的账户“原返回为:
{"body":{"Name":"王刚","cardNO":"12345678","value":"24.33","Address":"北京市朝阳区亮马桥","tel":"13333333333"}} 将返回包中的cardNO参数“12345678”修改为其他账号“62308452”,则在前端显示修改后的账号。再次选择“我的账户”子功能“账户详情”,请求为加密,从返回包的内容可以看出水平越权成功:
{"body":{"Name":"郭德岗","cardNO":"222222","Type":"CNY","calType":"001","bankAddr":"2334","cardValue":"24.33","Address":"北京市朝阳区亮马桥","tel":"13333333333"}{"sublist":"2222220102","cardValue":"1000.00"}此处案例中上面所述内容的危害为水平越权查询信息,通过上述的方式可以查询他人卡号、证件号、手机号。
但同时在案例其他功能的某一处可以以此方式使用他人银行卡进行缴费。(PS: 找不到截图了,无法拼凑了。em……)
0x02 寻找一个解密接口 前情提要此案例的应用不同于上一案例,请求不进行加密, POST请求参数不经过任何加密混淆,返回数据的格式统一,并且参数对应值是经过加密处理的,即返回数据中,如果前端需要用到的参数,则返回为解密后的明文,其他参数为密文显示 .
案例分享
某应用的忘记密码处,存在这样一个流程,当你将自己的登录名(证件号或登录名)发送请求之后,会返回你的部分信息。
证件号找回密码
尝试使用证件号作为登陆名进行验证找回密码,通过返回包中可以看到返回了“姓名”和“联系方式”的明文,其他字段为空,如下:
用户名找回密码
尝试使用用户名作为登录名进行验证找回密码,通过翻译包可以看到返回的信息和证件号找回密码一样,包括“姓名”、“电话”、“证件号”,但是登录名的组合要比证件号利用程度更加容易,有很多常用的top500,top100等常见登录名,所以进行爆破的话可以获取大量信息。
问题-如何解密
但是可能注意到了,返回信息中的信息全是经过混淆加密的,那么如何对加密数据进行解密?这是个问题。
但是下一个请求“验证身份”之后要验证手机短信的时候,请求中将上一个请求查询到的所有密文提交验证了, 然后然后竟然在返回包的js代码里找到了“手机号码”参数的明文信息,那么试试别的参数放到这个位置,Bingo!!!
如下所示,将姓名参数的明文进行请求,获取了明文密码。
综上所述,可以首先对忘记密码处进行暴力破解,搜集所有的返回的信息密文,之后在验证信息时,对参数进行暴力破解,即可获取所有密文对应的明文信息。此处可以将所有用户的“证件号”、“手机号”、“姓名”、“用户名”进行完整搜集。
同类似,如果遇到一个可以获取加密消息为请求密文的接口,上面的情况也有可能是适用的。 0x04 给加密的请求制造点错误 案例有些系统测试的时候,请求数据格式为json,并且参数基本固定格式为如下示例所示,同时基本请求数据均在data部分进行加密混淆。
POST /hello.do HTTP/1.1 Host: 127.0.0.1 {"_zh":"1324","data":"QWERT+YHFGGi+fgfyefgyef+6/"} 尝试思路 是否可以像“案例一”一样,有一个解密的接口,将密文转换为明文,但是此处场景无法获取整个请求的参数提交格式,所以思路不可行; 第二种方法,是否可以构造畸形data参数,从报错异常中构造处完整请求; 思路二的尝试
找到其他查询信息的接口,将任意接口的请求用来替换请求,因为请求接口不同,所以会出现报错信息,观察返回包是否可以解析或者产生什么报错?
首先,该功能接口正常请求和返回信息如下图所示:
当使用其他功能请求中的datas部分替换该请求的datas部分后,返回信息得到了满意的结果,如下所示:
对上面的截图分析:
原密文datas的明文可能为: {"name":"test1","ID":"123456","phone":"13333333333"} 畸形密文请求可能为: {"token":"234567890"} 后者的json中参数名不满足此处接口所需的参数和数据,后端无法进行查询,直接返回报错信息为参数缺失,并且给出了具体的参数名,这样的结果就是获取到了此处请求的json中必须包含哪些参数,可以直接构造一个完全符合正常请求的明文请求。根据实际情况,构造出的明文json请求如下,后端是否会解析呢?
结果也很明显,后端接收并解析明文json的请求方式:
明文请求 加密请求 思路梳理此场景几点总结如下两点:
是否可以明文请求以及明文返回,避免明文请求之后依然是密文返回; 是否可以从报错信息中直观获取有效参数名信息,这样可以减少构造参数名时需要大量的猜测过程; 0x05 总结以上是自己平时测试遇到的情况梳理,希望有可取之处。