首页 > 编程知识 正文

越权漏洞挖掘总结,越权漏洞 扫描

时间:2023-05-03 07:29:18 阅读:9529 作者:2773

这几年,开发人员的安全意识与安全开发水平都有了很大程度的提高。像文件上传、SQL注入漏洞,在网络安全比较受重视的企业,差不多都已经杜绝了,即便有出现,也是凤毛菱角了。目前,部分企业网络安全目前面临的另一大挑战就是越权漏洞,特别是大型系统,功能模块接口特别多,如果未对权限进行全局校验,则难免会有所遗漏,最终出现越权漏洞。

一、越权漏洞定义及分类越权,从字面上容易理解,主要有以下可能性:

1、非法访问:本来没有账户(即没有某个功能权限),但通过越权操作取得了某个功能权限

2、等级越权)本来有账户(即只能操作自己的数据),但通过新增、删除、修改等越权操作,可以操作其他同等权限账户的数据。

3、垂直越权(虽然有只有小权限的账号,但通过越权操作获得了大权限。

3358 www.Sina.com/http://www.Sina.com /最简单直接的测试方法是直接访问要测试的功能模块,而无需登录用户帐户。 通常需要登录才能访问。 如果能正常访问,就说明存在漏洞。

修改返回包测试方法:在日常测试中,一些开发人员可以在前端检查带有返回包的参数的值,返回包具有类似status=false的值,并将更改为status=true (可能遇到代码=-1,也可能更改为代码=0或1。 )遇到最奇怪的事情是,在不登录帐户的情况下直接访问该系统的后台首页index.html时,返回软件包主体,在js脚本中,通过script和location登录页面登录在burpsuite中阻止响应表,并使用用于跳转页面的js脚本删除该段,即可进入后台。 (修改这种返回包的方式并没有最后登录帐户,但进入后台后,您可以访问一些内部公共敏感功能模块和信息。)

在某些系统上,用户信息并未从sessionid获取登录帐户,而是在cookie中添加一个类似userid的密钥-值对,以从中标识用户。 请用cookie伪造的方法测试一下。

二、测试方法越级权常见于业务系统,对用户信息或订单信息进行增删修改操作时,用户号或订单号可以有规律地遵循(例如

2.1、未授权访问在日常安全测试中,经常是非法访问和级别越权。 我曾经将cookie的isadmin=0更改为isadmin=1,并获得过管理员权限。 黔驴技穷,幸运有一天灵光一闪,想测试任意文件的上传和下载漏洞时,可以用…/和…/绕过。 垂直越权的时候,也试着用…/和…/绕过去吧。 最终发现了新大陆。 最后经过反复测试,发现了以下几种垂直越权测试方法。

http://www.xxxx.com/admin//admin.do http://www.xxxx.com/js/./admin

EMC建议创建一个过滤器,以全局验证2.2、水平越权访问权限。 每次调用接口时,都可以验证访问权限。 大致流程为:第一步清洗URL地址,提取Api接口名称; 从步骤session中提取当前登录的用户的userid; 步骤3提取当前用户的角色id的步骤4 (检查垂直越权,确定与当前用户相对应的角色是否可以访问当前Api接口); 最后,确定当前登录的用户是否对目标对象具有操作权限(级别越权检查)。

首先,获取URL地址中的Api接口名称。 这里把URL地址解码了一次。 或者,如果是用户#,可能会绕过,因此有绕过的风险。

publicstaticstringgetapiname (string URL ) throws exception (stringdecodeurl=URL decoder.decode ) URL,' UTF-8 ' ); URL URL=newurl (解码URL; String ApiUrl=url.getPath (; if(APIURL!=null ) { string [ ] API path=API URL.split ('/' ); string apiname=API path [ API path.length-1 ]; 返回apiname; }返回空值; }获取userid时,建议您从session获取,而不是在cookie中创建用于标识用户id的新userid字段。

htpsessionsession=servletactioncontext.getrequest ().getSession ); string userid=session.getattribute (userid ); */s开始

ession中提取userid后,就要查询与之对应的角色id

//UserId为用户id,RoleId为角色ID,通过UserId获取roleidpublic static int GetRoleId(int UserId){Connection conn = Connect();PreparedStatement st = null;ResultSet rs = null;int RoleId = 0;try {// 查询接口访问的角色id,roleid为权限表里的角色ID字段,apiname为权限表里的API接口名称IDString sql = "select roleid from usertable where userid = ?";st = conn.prepareStatement(sql);// 这里使用PreparedStatementst.setInt(1, UserId);rs = st.executeQuery(); if(rs.next()){RoleId = rs.getInt("roleid");return RoleId; }}catch (Exception e) {e.printStackTrace();throw new RuntimeException("查询失败!"); }return RoleId;}

校验垂直越权时,判断当前用户是否对指定的接口有访问权限,U_RoleId为用户名对应的角色id,A_RoleId为Api接口对应的角色id,Api_Name为用户尝试访问的API接口名称(这里在系统架构评审,安全设计阶段,就要检查数据库的权限表设置时,Api接口是否有指定对应的角色id)

public static boolean CheckUpPrivilege(int UserId,String Api_Name) {Connection conn = Connect();PreparedStatement st = null;ResultSet rs = null;int U_RoleId = GetRoleId(UserId);int A_RoleId = 0;try {String sql = "select roleid from user_role where apiname = ?";st = conn.prepareStatement(sql);// 这里使用PreparedStatementst.setString(1, Api_Name);// 执行sql命令roleid和Role_Id,判断用户是否有权限访问对应的接口地址rs = st.executeQuery();if(rs.next()) {A_RoleId = rs.getInt("roleid");// 通过比较,当用户角色id大于等于接口指定的角色id是,可以访问,部分特定接口只有指定的角色才能访问,可直接限定if (U_RoleId >= A_RoleId) {return true;} else {return false; } }
} catch (Exception e) {e.printStackTrace();throw new RuntimeException("查询失败!");}return false;}

最后再判断一下是否是水平越权,S_UserId为当前登录用户的userid,P_UserId为目标对象对应的userid,比如对订单信息进行操作时,可以先通过订单号提取与之对应的userid,再进行判断(当然,订单表,在系统架构评审,安全设计阶段,就要检查订单号是否有指定对应的用户id)。

public static boolean CheckLevelPrivilege(int S_UserId, int P_UserId) {if(S_UserId == P_UserId){return true;}else{return false;}
}

四、最后

类似订单号这种参数,生成时要无规律可循,可以通过hash算法进行加密;或者请求的数据包额外附带一个参数,比如token,从而防止重放和遍历订单号这类攻击(篡改订单号)。

原文来源: FreeBuf.COM ,作者:freebuf01

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。