【代码审计】常见漏洞专项审计-业务逻辑漏洞审计
❤️博客主页: iknow181
🔥系列专栏: 网络安全、 Python、JavaSE、JavaWeb、CCNP
🎉欢迎大家点赞👍收藏⭐评论✍
0x01 漏洞介绍
1、 原理
业务逻辑漏洞是一类特殊的安全漏洞,业务逻辑漏洞属于设计漏洞而非实现漏洞,是业务逻辑设计不严谨导致的漏洞。大多数业务逻辑漏洞没有明显的攻击特征,难以通过漏洞扫描的方式发现,也难以通过安全设备来防护。
2、 特点
- 更多依据黑盒经验发现,无法通过工具检测
- 白盒发现难度大,审计时间成本高【需要非常熟悉业务功能及源码架构对应关系】,但是发现更加全
面,准确性相比黑盒差
3、应用场景
- 系统登录后才能访问功能,进入系统首页时会看到各种功能模块的增删改查(往往首页面会进行登录验
证) - 需要追踪到后端,逐层走读代码判断是否进行授权访问
- 此类漏洞一般发生在比较老的技术,往往是程序员手动进行权限验证不全面或因安全意识不足导致。
- 文件下载或数据浏览(查看),程序员针对访问数据仅校验是否登录或最低权限验证,但权限应通过用
户关联角色、角色关联权限控制到API接口级别(有的系统甚至API权限控制不全面造成越权),除此外
权限未控制到某数据表中的各条数据,因此产生了数据遍历漏洞。
4、审计流程
- 通过后端controller层代码或找业务获取系统的所有API接口,梳理出本系统的API列表。
- 需要追踪到后端,逐层走读代码判断是否进行授权访问分析本系统的权限校验技术和逻辑,特别是对于
登录验证控制的API,寻找遗漏点。 - 查看字符类型以及复杂度,被遍历字段是否为整形,是否为有规律的字符串【防止被猜测遍历】,但需
要确定是否进行数据鉴权 - 确定过滤器机制是否完整,即是否存在过滤器特殊符号绕过的情况
5、修复措施
- 对API全面梳理全面校验,最大限度的保证不遗漏API接口,对所有的API进行鉴权处理。【防接口越
权】 - 通过白名单机制,仅允许登录相关操作,例如登录前相关资源获取(常见的有验证码的获取)等,其他
一律都必须登录之后才能访问,如确实业务需要登录之前可访问,需要配置到白名单中。【防接口越
权】 - 字段设置一定复杂度的随机字符串,权限控制到数据级别,也就是说访问的数据要去用户关联起来。
【防数据越层次越权】
0x02 常见的分类
- 数据可遍历
- 越权
- API未授权
- 用户名、密码爆破【登录认证问题】
- 支付漏洞
- 验证码问题【验证码不失效、一码多用、可被识别、可被猜测、可被绕过】
0x03 业务逻辑漏洞-API未授权漏洞【接口越权】
1、审计技巧
- 通过后端controller层代码或找业务获取系统的所有API接口,梳理出本系统的API列表。系统的API列表。
- 分析本系统的权限校验技术和逻辑,特别是对于登录验证控制的API,寻找遗漏点。
- 系统登录后才能访问功能,进入系统首页时会看到各种功能模块的增删盖查(往往首页面会进行登录验证)需要追踪到后端,逐层走读代码判断是否进行授权访问。
- 此类漏洞一般发生在比较老的技术,往往是程序员手动进行权限验证不全面或因安全意识不足导致。
- 常见的验证技术shiro、Spring Security等成熟而又完善的权限验证框架大大减少了漏洞的产生。
2、修复方案
- 对API全面梳理全面校验,最大限度的保证不遗漏API接口,对所有的API进行鉴权处理。
- 通过白名单机制,仅允许登录相关操作,例如登录前相关资源获取(常见的有验证码的获取)等,其他一律都必
- 须登录之后才能访问,如确实业务需要登录之前可访问,需要配置到白名单中。
3、审计案例
分析思路:
(1)先看权限控制(如何解决AP未授权的问题),确定是否动态使用了5张表完成了权限与用户、角
色的动态绑定
通过查看实体类发现未采用动态权限控制。进行下一步分析后,得出该权限通过手动的简单编码处理了权限控制。
(2)看权限控制的技术(如何解决API未授权的问题)是否是手动校验或者是使用了比较的老的比较
简单的filer
发现未使用成熟的权限框架校验技术,未使用手动编写filter过滤器,其实就是我们加大未业务逻辑漏洞审
计的决心。
(3)看数据是如何鉴权的,需要分析详细的API及业务系统功能,看各自的数据获取是否合理。
第一点,简单来说看数据是否公开,公开就忽略
第二次,对于属于私有的数据,查看是否校验了当前用户登录的身份(登录用户本人或管理员)
例如学生成绩查询系统,能够查看学生成绩的,只有学生本人以及你的教师。
以学生成绩查看业务功能为例,分析:
最后确定这个接口只要传入ID,就能够获取当成绩,追溯整个的漏洞链中未发现进行了合格的校验
如果我能确定,未对当前登录用户的权限进行控制,就可以得出该代码存在着API未授权漏洞。
1、通过通读源码,发现考试系统未使用任何安全框架,未使用Filter过滤器进行登录验证,通过手写
登录方法对用户是否存在,密码是否正确以及登录身份判断后分别跳转到对应页面(学生、教师、管
理员),未真正进行API与用户、角色的绑定校验权限,全局存在API未授权问题。
2、对梳理的API列表逐一按照参数要求在不登录的情况下访问后成功获取对应数据,其他不在一一列
举。
总结:需要对登录身份进行权限控制,简单的说就是验证查询的学生成绩的id是不是登录用户的ID,
校验手动参考如下:
关于水平越权的修复的问题:
1、数据层次导致的越权原因,直接通过sid查询了某条数据,未对当前登录的用户进行校验:
2、如何鉴权,应该获取到当前登录用户的 ID,和查询的数据所属用户进行比对
除了API未授权,未通过用户的角色决定该接口是否被授权的用户访问,仅仅是接口的访问,如果能够控制接口的请求,这个授权就完美了。但是我们通过数据层次上控制了不同角色用户访问数据的权限并且通过sql语句的限制条件控制了数据遍历访问的问题。所以修复到这里,也不会出现越权问题。
0x04 shiro框架介绍
Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比Spring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的 Shiro 。
Shiro 简化开发应用,能够完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。
- Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;
- Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
- Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;
- Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
- Web Support:Web 支持,可以非常容易的集成到 Web 环境;
- Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;
- Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过
去; - Testing:提供测试支持;
- Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
- Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
0x05 业务逻辑漏洞审计-水平越权【简单】案例
1、审计技巧
- 被遍历字段变量类型为整型
- 被遍历字段变量为有规律的字符串
- 确定是否进行数据鉴权
相同角色的用户才会考虑水平越权的问题(如果用户的角色不一样,那低权限的账号根本就没有机会访问到高权限账号的接口),也就是说两个用户一定能够同时访问这个API,才会继续往下考虑水平越权的问题。
2、应用场景
文件下载或数据浏览(查看),程序员针对访问数据仅校验是否登录或最低权限验证,但权限一般是通过用户关联角色、角色关联权限控制到AP接口级别(有的系统甚至AP权限控制不全面造成越权),权限未控制到某数据表中的各条数据,因此产生了数据遍历漏洞。
3、修复方案
- 设置具有一定复杂度的随机字符串,例如随机12位或16随机字符串(迫不得以)。
- 将权限控制到数据级别,也就是说访问的数据要去用户关联起来(最优解)。
4、审计案例
1、以考试系统为例,查看李丽学生的成绩,请求student/showScore?sid=1
2、确定sid表示查询的李丽的成绩,根据审计技巧猜测sid是否是一个可遍历的字段且在数据级别未进
行校验,因此进入后端参数追踪,发现sid为一个整数易被遍历且查询数据前未进行任何权限和校验,从
而造成了登录李丽账号后可遍历其他任意学生的成绩信息。
3、利用黑盒遍历sid可随意查看其他同学的成绩
0x06 业务逻辑漏洞-垂直越权
1、漏洞原理介绍
- 越权漏洞分类水平越权和垂直越权,同级别权限的用户之间能访问、操作范围外数据或请求接口的为水平越权,低权限账号能够访问或操作高权限数据或请求接口的为垂直越权。
- 越权漏洞主要发生在面向不同角色的用户提供不同服务或功能的系统,例如OA、HR等应用类、管理类系统,特别是使用老技术架构的系统发生越权情况更为普遍。但如果使用了新技术,一般会使用较为成熟的框架机制进行权限控制,从而大大觉少了越权漏洞的发生。
2、审计漏洞突破口
- 查看后端索使用的技术,特别是使用的权限认证技术,熟悉shiro,spring-security等框架的鉴权原理
- 梳理所有的API,进行分类,追踪api请求,查看是否会进行权限验证。
- 对于较老技术架构的系统,往往只是进行了登录验证或API仅进行了最低权限角色的认证,未全部将角色和对应的API匹配起来,导致了越权漏洞的产生
3、权限控制原理
- 将后端所有被请求的API均当做权限(API请求路径)存储到数据库权限表中
- 同时将角色表和权限表关联起来,将用户表和角色表管理起来
- 用户在请求API时,权限验证框架会依据用户信息查询对应角色所用户的权限,权限足够才会正常请求API,否则将会拦截。只要API未完全通过角色和用户绑定起来就会存在越权漏洞的产生。
登录认证案例:
4、审计案例-1
1、在新医院管理系统中,使用普通用户(低权限)访问医院管理的功能,管理员(高权限)访问系统
用户的功能,尝试查看是否存在垂直越权行为
2、分别发送请求后抓包发现存在医院管理员能够查看系统用户的信息(此API越权)
3、首先设置管理员和普通用户的角色,不允许低权限用户操作系统管理功能模块
4、登录低权限账号后发现页面确实不能访问系统管理功能
5、随后经过梳理该系统使用Shiro框架权限验证,简单来讲就是框架自动将请求的API接口和我们数据
库权限表关联起来,用户登录-获取用户Id-查询所属角色-查询权限列表-shiro框架会比对待请求的用
户接口路径是否在范围内,如果在就放行,不在就拦截。此次能越权是因为确实在列表内:
6、因此接口能否越权的关键看权限列表控制的是否合理,也就是所看API是否完全和用户、角色关联
起来是关键,部分API关联不合理成为了漏网之鱼,数据越权需要看当前数据是否和给用户授权(通过
白名单存储所有能访问用户的标识与登录用户进行比对,如果在范围内允许访问,否则不允许访问)
0x07 业务逻辑漏洞-字段爆破
- 常见的爆破字段有用户名、密码、验证码(黑盒)
- 从白盒来讲,通过审计源代码包括字段的类型,例如整形,有规律的字符串作为数据的唯一标识
- 此类漏洞通过黑盒直接测试比较方便,一般情况下只有使用了验证码(图形验证码、短信验证码)一般情况下不可被破解。
1、审计方法
- 追踪登录功能,查看后端源码是否在登录成功前进行了验证码的刷新(防失效)。
- 在修改密码处可能不会再进行验证码设置,从而造成用户名爆破。
- 搜索是否提示用户名不存在且在未关联验证码的情况。
2、修复方案
- 凡是在涉及到用户名判断的情况反馈模糊提示信息,不得直接提示用户名不存在。
- 凡是判断用户名和密码的认证情况,需要增加验证码判断逻辑来避免爆破。
- 设置基于IP锁定和一定时间内账号错误输入次数机制,来避免爆破密码的情况。
- 通过增加具有一定复杂度的验证码来方爆破
0x08 业务逻辑漏洞-支付漏洞
支付漏洞一般是程序员对异常的情况未进行安全考虑,具体包括:
- 支付、取款、转账任意金额的修改,未对正负数、原金额足额比较
- 来自前端的金额直接执行支付操作,未对前端折扣金额等于后端的金额比对,是产生支付漏洞是一种常见的现
象。
如果单价,折扣,原价,积分等等的不与数据库进行比对的话,将会出现任意金额下单,购买的业务
逻辑漏洞
如果未对同一客户端IP、同一用户、同一时间段内重复下单的频率进行先限制和提醒,将会造成无限
刷单。
审计技巧:寻找支付相关业务逻辑,确定是否对金额进行负数、原账号金额、前端支付变量与数据库
真正定价比较。
0x09 业务逻辑-filter 过滤器绕过
filter被称为过滤器,是Servlet2.3新增的一个特性,同时它也是Servlet技术中最实用的技术。开发人员可以通过Filterj技术,能够实现对所有Wb资源的管理,如实现权限访问控制、过滤敏感词汇、压缩响应信息、全局编码配置、登录认证等一些高级功能。
1、filter 过滤器../绕过
1. 绕过原理分析
/user/loginServlet、/user/toLoginServlet开头,符合匹配的规则,而匹配上该规则后则是直接放
行,让系统认为访问路径是一个登录的路径,但在后面加入../进行跳转到根目录,并且拼接上
indexServlet,这时候实际访问到的是http://127.0.0.1:8082/user/indexServlet
2. 修复方案
String uri = request.getRequestURI();
if(uri.contains("./")){resp.getwriter().write("error");return;}
2、手动filter过滤器-;绕过
1. 绕过原理分析
URL中有一个保留字符分号;,主要为参数进行分割使用,有时候是请求中传递的参数太多了,所以使
用分号;将参数对(key=value)连接起来作为一个请求参数进行传递。再来看到代码,代码中识别.do
和.action的后缀的字符,而加入;加上随便内容后,代码中就识别不到了。则会走到最下面的
chain.doFilter(request,resp);,而在后面添加;分号不会对地址的访问有任何影响。
2. 修复方案
3、 总结
前面提到过request.getRequestURL(),这些危险字符并不会自动剔除掉。可重点关注该方法。
关于手写过滤器的绕过的总结:
(1)两个场景,第一是基于../截断,第二是基于;截断,对应通过黑名单通过相关API获取uri剔除特殊
的字符去分别防止两个场景的绕过
(2)当你遇到了手写的过滤器,要基于以上两个场景去判断是否存在该问题