对HTTP加密请求参数的测试
对于HTTP请求体加密,如果直接使用明文的请求参数,是无法进行正常的安全测试的。但通常还是有办法分析出加解密的策略,如果能把加解密算法还原,就可以先将安全测试的payload添加到原始明文参数,再加密发送到服务端处理(可以编写对应的burp插件实现半自动化,因为逻辑漏洞还是要人工分析),好处就是可以绕过WAF这类防护设备,WAF可能具备解码BASE64编码的能力,但对这种自定义的加密一般识别不了。比如下面的案例。
HTTP请求体中的参数是分段加密的:
接口使用了RSA和AES配合加密,每次会获得16位随机字符作为AES加密密钥。
iv为固定的字符串(该系统中iv的分析相对是困难的)。
加密模式为CBC,padding为Pkcs7,在加密入口设置断点获取某次加密的AES密钥。
使用密钥和iv解密data参数中的密文,获得明文参数,给明文参数添加安全测试的payload,再用相同的算法加密重新发包。
通过接口猜测实现越权
对于企业级系统,可用的后台服务不会是寥寥几个,通常会基于CURD组合成丰富的业务功能,用户在系统中看到的服务可能并不是该系统的全部服务。比如下面的案例。
下图是查看控制中心-用户管理的功能界面:
该功能调用了以下接口,该接口能够返回角色信息。
/detection/api/user/findRoleListByUserId/24
按照接口命名规则猜测,修改/findRoleListByUserId/为/findUserByUserId/,同时修改userid的数值为超管的userid(1),便返回了超级管理员的个人信息(如身份证、手机号、邮箱)。
模糊测试发现隐藏接口
俗话说,有毒蛇出没的地方也会有解药。同理,在有新增功能的地方,通常也有删除功能。
比如某系统查看首页-公司公告的功能:
查看其中一篇公告“集团公司公告测试”,发现可以进行评论。
添加评论,查看添加评论的接口接口如下:
/cqeip-androidapp/form/articleDiscuss/addDiscuss
尝试删除评论,但是发现没有删除评论的接口,由于添加评论的接口是/cqeip-androidapp/form/articleDiscuss/addDiscuss,于是修改接口名称addDiscuss 为deleteDiscuss,提示不支持POST请求,但说明该接口存在。
转为GET请求再尝试,提示PostgreSQL数据库执行时发生语法错误,SQL中带入括号导致SQL语法报错,排查括号来源即可定位注入点。
从代码中找到越权入口
有时候业务功能和安全防护是冲突的,即便已经有意识对不同角色的用户划分权限。在某些情况下,研发人员“业务优先”的思维会在潜意识中使安全功能滞后,导致安全和业务冲突。如下面的案例。
对于已经做了鉴权的接口,尝试修改路径变量的数字id发现服务器不予处理。
通过查看源码发现,用户级别(参数level)为3才能调用这个接口,当前用户的级别为1,所以调用api/user/userGrid/1提示未授权。
上述代码在调用接口前进行鉴权,检查用户级别可以调用的数据集。
但在最后返回的时候代码会自动增加了一个参数level是3,authSource参数为0的数据集(可能其他服务需要用户有这个level的级别)。
该接口requireLevel是3,会提取出level大于等于3的数据集。由此判断,接口/userGrid/{datasetId}中的datasetId不在level大于等于3的数据集中,而经过校验返回的数据集中刚好存在level为3,值为0的数据集,由此导致安全和业务冲突。
于是,通过请求/api/user/userGrid/0即可实现权限绕过。
绕过HTTP请求中的签名保护
经过了签名保护的HTTP请求包数据通常是明文,只是多了签名校验的参数,如果修改了参数重新发包,而对应的签名校验的参数没有正确生成,那么服务端将不会处理该请求。如下面的案例。
当前系统的账号下只有一个文件,查看这个文件的处理日志。
获取日志的接口,URI中的数字22是当前H5文件的id:
/api/h5/encrypt/lookH5InfoLog/22
修改 id 为 21,查看其他文件的加固日志,提示接口签名校验错误。
签名校验参数sign的生成是在文件/static/js/app.42706fa77f33b048ba77.js中完成(如下图),其中clientid是固定字符串“admin”,timestamp是时间戳,拼接URI和字符串“admin”和时间戳,再通过MD5进行哈希即得到签名sign。
基于上述签名的生成方式,获取一个新的时间戳
修改URI中的id为21,再拼接字符串“admin”和新时间戳再通过MD5计算,便能得到一个合法的签名sign。
替换之前请求中的时间戳和sign,再次请求就能越权查看当前账号中看不到的文件id为21的处理日志。
绕过 jsonp 跨域限制
对于使用了随机数进行请求校验的功能,最简单的方法是尝试删除随机数。
登录站点A后,选择手机号码修改业务
之后进入信息审核页面,按 F12 进入浏览器开发者模式,选择“网络”, 刷新页面,查看请求,发现在三个回调函数调用中会返回用户的敏感信息(用户名,资金账号,手机号等)
可以看到,回调函数名都是采用了长的随机数命名,这样每次调用都是一次性的,下次调用又是新的随机函数名,再次访问该jsonp接口将不会返回数据:
https://a.com/hall/biz/judge/login?callback=jQuery112406353168200498462_1596181627657&_=1596181627658
由于同源策略限制,其他站点想要获取到该站点下的这些用户敏感数据可以尝试使用jsonp进行跨域获取。
这里尝试将回调函数后面的随机数删掉,再进行跨域获取,原始回调函数调用包含蓝色标记的随机数:
https://a.com/hall/biz/judge/login?callback=jQuery112406353168200498462_1596181627657&_=1596181627658
将蓝色标记的随机数删掉,只保留“jQuery”:
https://a.com.cn/hall/biz/judge/login?callback=jQuery
jsonp跨域主要是利用<script>标签src属性可以进行跨域访问这一点,先创建一个html文件,用<script>标签的src属性去调用上面站点中返回用户敏感数据的那三个回调函数,接着在接收函数中将获取到的数据在控制台打印出来。
登录状态下在浏览器打开该页面,按F12查看控制台,发现成功在控制台中打印出了用户敏感数据,说明删掉随机数后可以正常调用jsonp接口,算是函数随机数命名的简单绕过,最后诱骗已登陆系统的用户去访问该构造好的URL即可获取对方的敏感信息(用户名,资金账号,手机号等)。
作者:RoShine
2024年2月2日
洞源实验室