0x01 等保测评项

GBT 22239-2019《信息安全技术 网络安全等级保护基本要求》中,8.1.4.2安全计算环境—访问控制项中要求包括:

a)应对登录的用户分配账户和权限;

b)应重命名或删除默认账户,修改默认账户的默认口令;

c)应及时删除或停用多余的、过期的账户,避免共享账户的存在;

d)应授予管理用户所需的最小权限,实现管理用户的权限分离;

e)应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;

f)访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级;

g)应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。

越权访问对应访问控制项中要求e),所以安全控制点为访问控制e


GBT 28448-2019《信息安全技术 网络安全等级保护测评要求》中,测评单元(L3-CES1-09)

该测评单元包括以下要求:

a)测评指标:应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则。

b)测评对象:终端和服务器等设备中的操作系统(包括宿主机和虚拟机操作系统)、网络设备(包括虚拟网络设备)、安全设备(包括虚拟安全设备)、移动终端、移动终端管理系统、移动终端管理客户端、业务应用系统、数据库管理系统、中间件和系统附案例软件及系统设计文档等。

c)测评实施包括以下内容:

1)应核查是否由授权主体(如管理用户)负责配置访问控制策略;

2)应核查授权主体是否一句安全策略配置了主体对客体的访问规则;

3)应测试验证用户是否由可越权访问情形。

d)单元判定:如果1)~3)均为肯定,则符合本测评单元指标要求,否则不符合或部分符合本测评单元指标要求。

越权访问漏洞属于测评单元(L3-CES1-09)中测评实施的第3项,故定测评单元为L3-CES1-09.3。


0x02 测试内容

测试系统是否存在特权等级升级到另一个特权等级或同等级其他账户的问题。


0x03 漏洞原理

原理

越权访问是Web应用程序中一种常见的漏洞,由于其存在范围广、危害大,被OWASP列为Web应用十大安全隐患的第二名。该漏洞是指应用程序在检查授权时存在纰漏,使得攻击者在获得低权限账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。

越权漏洞的成因主要是因为开发人员在后台使用了不合理的校验规则。在对数据进行增、删、改、查时对客户端请求的数据过分相信而遗漏了权限的判定, 一旦权限验证不充分,就易导致越权漏洞。这点与SQL注入漏洞、XSS等漏洞很相像,都是由开发人员对请求的数据没有做到更全的防御导致的风险问题。

一般越权漏洞容易出现在需要验证当前身份的页面,如用户登录、操作数据、提现、修改个人资料、发送私信、上传图片、上传表单、下单、充值、找回密码等处。当用户对权限页面内的信息进行这些操作时,后台需要对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞。


分类

这类漏洞往往很难通过工具进行自动化检测,属于逻辑漏洞中的一种。越权漏洞一般分为水平越权垂直越权、交叉越权

但从广义上来讲还包括一种“未授权漏洞”,这种漏洞类似于越权漏洞的垂直越权,攻击者没有获取到登录权限或未授权的情况下,不需要登录即可通过输入网站控制台地址直接访问进行操作,但此篇文章只讲水平越权与垂直越权,后续会专门写一篇未授权访问漏洞文章。

越权分类

水平越权:

又称横向越权,这是一种“基于数据的访问控制”设计缺陷引起的漏洞。由于服务器端在接收到请求数据进行操作时没有判断数据的所属人/所属部门而导致的越权数据访问漏洞,也就是相同权限的不同用户之间可以互相访问数据以及执行其他用户的功能等

水平越权


垂直越权:

又称纵向越权,这是一种“基于URL的访问控制”设计缺陷引起的漏洞,由于后台应用没有做权限控制,或仅仅在菜单、按钮上做了权限控制,导致恶意用户只要猜测其他管理页面的URL或者敏感的参数信息,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。也就是低权限用户可访问高权限用户的数据以及执行高权限用户功能等

垂直越权

交叉越权:

既可以水平越权又可以垂直越权。


0x04 代码示例

以下代码中第8行没有对传入的ID进行校验,ID代表用户,攻击者直接传入指定的ID就可以修改对应用户的个人信息。


// @Tags SysUser// @Summary 设置用户信息// @Security ApiKeyAuth// @accept application/json// @Produce application/json// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"// @Router /user/setUserInfo [put]func (b *BaseApi) SetUserInfo(c *gin.Context) {  var user system.SysUser  _ = c.ShouldBindJSON(&user)  if err := utils.Verify(user, utils.IdVerify); err != nil {    response.FailWithMessage(err.Error(), c)    return  }  if err, ReqUser := userService.SetUserInfo(user); err != nil {    global.GVA_LOG.Error("设置失败!", zap.Error(err))    response.FailWithMessage("设置失败", c)  } else {    response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c)  }}

0x05 测试过程

常用测试思路:

  • 密码重置中如果有不需要输入原密码就能修改密码时,在修改密码处抓包,修改数据包中的用户名或用户ID等,测试是否能修改其他用户的密码;


  • 修改用户资料时修改用户ID,测试是否能修改其他用户资料;


  • 查看订单时,遍历订单ID ,测试能否查看其他用户订单;


  • 攻击者越过中间校验步骤直接进行后续操作,导致中间校验等步骤失效,对于这样的流程越过漏洞通常的测试思路是,首先完成正常的业务逻辑步骤,获取每一个步骤的请求,再绕过中间步骤直接访问最后一个或几个的验证请求,测试是否能成功访问。流程越过在密码修改、密码重置、购买商品处出现的可能性较大,这些测试点可着重留意。


  • 当对一个有注册功能或是存在身份认证的站点,可以申请两个同级的账户进行水平越权测试。不过最好是让客户提供一个管理员用户、两个同级账户,完成水平越权、垂直越权测试。就可以替换账号的token进行测试。分析每个参数的功能,尽可能的多去尝试修改,比如,任意加减参数值或将false修改为true、success,看看会有什么变化,执行某一操作的时候删除cookie、token后有什么变化。


测试案例1


在页面上使用普通账户操作请求。登录用户A时,正常更改或者查看用户A信息,抓取数据包,将传参ID或其他参数修改为其他用户,如果能成功查看或修改了同权限的其他用户信息,就属于水平越权,如果影响到的是高权限用户,就是垂直越权。测试案例1通过身份信息伪造进行水平越权。


  1. test登录成功后的请求包中card_id与响应包中card_id、页面中“会员号:20128880322”一致,响应包返回test用户的用户名以及md5加密后的密码。猜测card_id为身份控制参数,尝试是否可以通过修改card_id获取其他用户的用户名、密码。



  1. 回到登录页面,页面底部有其他用户账号头像,响应包中列出这些头像的文件名,按照顺序马春生的应该是第一个20128880316,这个编号与test用户card_id相似,猜测是否就是马春生的card_id。



  1. 将test登录成功的请求包中的card_id值更改为20128880316,得到用户名m233241和md5加密的密码,将密码解密后成功登录马春生账号。


还有种情况是身份控制参数直接出现在URL中,对此就可直接遍历URL中的参数值获取其他用户的信息。



修复:

身份信息必须进行加密传输,要采取标准的加密方式进行加密,并保存好密码,尽量不要使用base64编码等非强加密算法,即使使用base64传输,也需要加入脏数据进行混淆,增加破解难度。


测试案例2


  1. 登录lili账号可以查看到lili的个人信息,URL中出现username参数username=lili,猜测可能是通过此参数控制身份信息。



  1. 直接修改URL中username的值,改为lucy,成功查看到lucy个人信息,这是一个水平越权漏洞。



出现此漏洞的原因是,源码中没有判断用户身份,需要添加一段判断get请求是否来自lili(也就是当前登录的用户)的代码,拒绝越权的尝试。


测试案例3


  1. 使用管理员登录,管理员有创建用户的权限,添加用户,抓取添加用户的数据包



  1. 发送至Repeater模块,Go一下,顺利创建新用户。



  1. 退出admin用户,再次提交添加用户POST请求。再次登录admin用户,发现并没有新用户被创建。



  1. 登录用户pikachu,只有查看权限。



  1. 复制pikachu用户的Cookie,与之前admin用户登录时添加用户的POST请求中的cookie进行替换,更改username的值,再次发送数据包,试试能否创建用户。再刷新网页,能看到test123123已经添加成功。说明后台没有对当前登录账号的操作进行正确的权限认证,存在垂直越权漏洞。



修复:

在每个步骤的session都应该添加标识位,并将session与用户的身份进行强绑定,并在新步骤显示之前必须要检测之前每一步的session标志位。

关于密码修改的地方还可以使用一次性填写所有的校验信息,例如原始密码、新密码等信息后再提交/重置密码请求。


0x06 检测工具

  1. Authz插件:


下载地址:https://github.com/portswigger/authz使用方法:https://gh0st.cn/archives/2019-06-27/1?hmsr=toutiao.io&utm_campaign=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

平时做测试发现越权漏洞大多是基于修改ID的方式:将A用户的ID改成B的ID,然后进行请求查看是否可以越权获取到信息,或当ID的规律已知情况下基于Burp Intruder模块直接去遍历ID。

基于Authz的检测是不一样的,它是将用户认证的HTTP请求头进行修改(Cookie之类的),然后通过响应长度、响应状态码判断是否存在越权;

从本质上来讲没有任何区别,只是换了一个角度,但这样的好处是一定程度上的减少了测试的时间(例如:一个商城的业务系统,你有A、B账户,A账户买了个商品获得一个订单信息请求,当你想测试是否能越权获取B账户订单时就需要使用B账户去再购买,然后判断测试。)


优点:使用简单、省时省力;

缺点:只适用于检测越权读取类的操作,删除编辑类操作还需要人工判断。



  1. secscan-authcheck

下载地址:https://github.com/ztosec/secscan-authcheck

secscan-authcheck工具比较强大,安装也比较麻烦,需要搭建自己的服务器,将工具安装在服务器上,然后需要在浏览器安装插件,将浏览器访问流量导入自己的服务器上,使用该工具检测是否有越权漏洞。


0x07 风险分析

用户可以操作比自己高权限用户操作范围的数据(如管理员账号),具体危害与对应业务的重要性相关。

不同的用户应该拥有不同的权限去做增删改查等操作,恶意攻击者可利用该漏洞去越权查看、修改其他用户的敏感信息,对账户安全造成威胁


0x08 加固建议

越权漏洞的本质就是访问到当前用户本不该访问的页面、执行不该执行的操作,所以对用户的权限验证尤为重要。

1. 完善安全架构、用户权限体系。知道哪些数据对应哪些用户,哪些数据不应该由哪些用户操作;

2. 鉴权,服务端对请求的数据和当前用户身份做校验;

3. 不要直接使用对象的实名或关键字,例如订单ID使用随机数;

4. 对于用户访问角色的权限进行严格的检查及限制,前后端同时对用户输入信息进行校验,双重验证机制;

5. 在一些操作时可以使用session对用户的身份进行判断和控制;

6. 调用功能前验证用户是否有权限调用相关功能;

7. 执行关键操作前必须验证用户身份,验证用户是否具备操作数据的权限;

8. 直接引用对象的加密资源ID,防止攻击者枚举ID,敏感数据特殊化处理;

9. 永远不要相信来自用户的输入,对于可控参数进行严格的检查与过滤;

  1. 订单号此类参数,以随机方式生成,再进行算法加密,或者请求的数据包额外附带一个参数,比如token,从而防止重放和遍历订单号这类攻击;
  2. 前后端同时对用户输入信息进行校验,双重验证机制;
  3. 做过滤器,对权限进行全局校验(每次调用某个接口时,可先对权限进行校验)第一步清洗URL地址,并提取API接口名称,第二步从session中提取当前登录用户的userid,第三步,提取当前用户的角色ID,第四步,判断当前用户对应的角色是否有权限访问当前API接口(检查垂直越权),最后判断当前登录用户是否对目标对象有操作权限(检查水平越权)。