代码审计之业务逻辑漏洞审计
一、业务逻辑漏洞审计思路
-
业务逻辑特点
更多依赖黑盒经验发现;白盒审计难度大,审计时间成本高【需要非常熟悉业务功能以及源码架构对应关系】,但是发现更加全面,准确性比黑盒差。
-
应用场景
系统登录后才能访问的功能;需要追踪到后端,逐层走读代码判断是否进行未授权访问;此类漏洞一般发生在比较老的技术,往往是程序员手动进行权限验证不全面或因安全意识不足导致;文件下载或数据浏览,程序员针对访问数据仅仅校验是否登录或最低权限验证,但权限因通过用户关联角色、角色关联权限控制api接口级别(有的系统甚至API权限控制不足造成越权),除此外权限未限制到某数据表中的各条数据,因此产生了数据遍历漏洞。
-
审计流程
通过后端Controller层代码或业务获取系统所有的API接口,梳理出本系统的API权限表;
需要追踪到后端,逐层走读代码判断是否进行授权访问,分析本系统的权限校验技术和逻辑;
查看字符类型以及复杂度,被遍历字段是否为整型,是否有规律的字符串【防止被遍历猜测】;
确定过滤机制是否完整,即是否存在过滤器特殊符号绕过的情况。
-
修复措施
对API全面梳理全面校验,最大限度的保证不遗漏API接口,对所有的API进行鉴权处理。
通过白名单机制,仅允许登录相关操作,例如登录前相关资源获取(常见的有验证码的获取)等,其他一律登陆之后才能访问;
字段设置一定复杂程度的随机字符串,权限控制到数据级别。
-
漏洞原理介绍
业务逻辑漏洞是一类特殊的安全漏洞,业务逻辑漏洞属于设计漏洞二非实现漏洞,是业务逻辑设计不严谨导致的漏洞。
-
常见分类
数据遍历;越权;API未授权;用户名、密码爆破;支付漏洞;验证码。
二、业务漏洞漏洞-API未授权漏洞
1.审计技巧
- 通过后端的Controller层代码或找业务获取所有的API接口,梳理出本系统的API列表。
- 分析本系统的权限校验技术和逻辑,特别是对于登录验证控制的API。
- 系统登录后才能访问的功能,进入系统首页时会看到各种功能模块的增删改查。
- 需要追踪到后端,逐层走读代码判断是否进行授权访问。
2.审计案例
分析思路:**
**
(1)先看权限控制,确定是否动态使用了5张表完成了权限与用户、角色的动态绑定。
通过查看实体类发现未采用动态权限控制,进行下一步分析后,得出该权限通过手 动的简单编码处理了权限控制。
(2)查看权限控制技术是否手动校验或者是使用了比较老的比较简单的filer。
(3)看数据是如何鉴权的,需要分析详细的API以及业务功能,看各自的数据是否合理。第一点:简单来看数据是否公开,公开就忽略;第二点:对于属于私有的数据,查看是否校验了当前用户登录身份,例如学生查询系统,能够查看学生成绩的,只有学生本人以及教师。
以学生成绩查看业务功能为例,分析:
最后确定这个接口只要传入ID,就能获取成绩,整个漏洞链都未进行合格的校验。
如果我能确定,未对当前登录用户的权限进行控制,就可以得出该代码存在着API未授权漏洞。
(4)修复方法
获取当期登录的用户ID,和查询的数据所属用户进行对比
(5)上面的修复方案还是有问题
目前除了API未授权,未通过用户的角色决定该接口是否被授权的用户访问,但也仅仅是接口的访问,如果能够控制接口的请求,这个授权就完美了。但是我们通过数据层次上控制了不同角色用户访问数 据的权限并且通过sql语句的限制条件控制了数据遍历访问的问题。所以修复到这里,也不会出现越权 问题。
三、业务逻辑漏洞审计-水平越权
1.审计技巧
- 被遍历字段变量类型为整型
- 被遍历字段变量为有规律的字符串
- 确定是否进行数据鉴权
2.应用场景
文件下载或数据浏览,程序员针对访问数据仅校验是否登录或最低权限验证,但权限一般是通过用户关联角色、角色关联权限控制到API接口级别,权限未控制到某数据表中的各条数据,因此产生了数据遍历漏洞。**
**
3.修复方案
设置具有一定复杂度的随机字符串,例如随机12位或16随机字符串(迫不得以)。
将权限控制到数据级别,也就是说访问的数据要去用户关联起来(最优解)。**
**
审计案例同上。
四、业务代码审计-垂直越权(API越权)
1.漏洞原理介绍
- 越权漏洞分类水平越权和垂直越权,同级别权限的用户之间能访问、操作范围外数据或请求接口的为水平越权,低权限账号能够访问或操作高权限数据数据或接口的为垂直越权。
- 越权漏洞主要发生在面向不同角色的用户提供不同的服务或功能的系统,列如OA、HR等应用类、管理类系统,特别是使用老技术架构的系统发生越权情况更为普遍。但是如果使用了新技术,一般会使用较为成熟的框架机制进行权限控制,从而大大减少了越权漏洞的发生。
**2.审计漏洞突破口
**
- 查看后端所使用的技术,特别是使用的权限认证技术,熟悉shiro,spring-security等框架原理
- 梳理使用的API,进行分类,追踪api请求,查看是否会进行权限验证。
- 对于较老的技术架构的系统,往往只是进行了登录验证或API仅进行了最低权限角色的认证,未全部角色和对应的API匹配起来,导致越权漏洞的产生。
3.权限控制原理
- 将后端所有被请求的API当做权限(API请求路径)存储到数据库权限表中
- 同时将角色表和权限表关联起来,将用户表和角色表关联起来。
- 用户在请求API时,权限验证会依据用户信息查询对应角色的权限,权限足够才会正常请求API,否则将会拦截。只有API未完全通过角色和用户绑定起来就会存在越权漏洞的产生。
shiro授权案例:
4、小插曲
1、在新医院管理系统中,使用普通用户(低权限)访问医院管理的功能,管理员访问系统用户耳朵功能,尝试查看是否存在垂直越权行为。**
**
这里有个小插曲,本来这个案例我只是想把
@RequiresPermissions("system:user:list")
这一行注释,达到绕过权限,使任意人都可以查看用户数据列表。
但是出现了一些问题,我们来一探究竟。
五、权限认证流程。
我们先来debug启动项目,登录superadmin最高权限账户来给用户分配权限。
登录后程序运行到用户验证的断点处,但是这不是我们这次审计的重点,我们直接跳过,来到权限认证出,比如我们来到用户管理处,查看所有系统用户。
点击用户管理,程序会先判断系统的用户权限,如果是管理员,则拥有所有的权限。
程序来到断点处,判断是否是管理员,是管理员则分配所有权限,那么这个权限是怎么分配的呢,我们来往下步过,
可以看到给管理员用户添加了":😗"的权限
这是什么意思呢,这就是前面说到的接口,也就是说管理用户可以访问任意的接口,可能还是有点懵,做个对比就好了。我们现在以普通用户登录,也点击用户管理,看看权限认证是怎么做的。同样点击用户管理。程序也同样走到断点处。
我们步过,因为他不是管理员,所以不会进入if条件中。而是来到这两行。
这两行用到的selectRoleKeys和selectPermsByUserId,一看就是要去数据库中查什么,我们全局搜索这个两个函数。没搜到第一个函数去调用数据中的操作,但是找到一个接口,就是去获取user对象中的user_id,这个user_id在用户登录时,已经在数据库中查到,封装到了user中;紧接着我们查看第二个函数。果然是去数据库中查询什么数据。
我们将查询语句复制到数据库中查询,user_id就是我们的普通账户,现在我们来看我们数据库中的表吧。最重要也就这五张表
sys_user表,记录用户的账号密码邮箱等等。
sys_role表记录了权限表,这套系统只有两种权限,管理员和普通用户
通过sys_user_role表可以看到,出来user_id为1的账户也就是管理员账号的role_id为1,其余的账号均为2,这套系统也就是通过role_id来区别管理员和普通账号。
然后我们来看sys_role_menu表,记录不同普通用户下的menu_id。
那么这些menu_id是什么意思呢。我们来最后看一张表sys_menu表
这里记录了所有能调用的api。那么到这里,对于API权限认证就清楚了,用户登录后,进行权限认证,为管理员用户的拥有所有api权限,为普通用户的去sys_role_menu表中查menu_id,通过menu_id查询到使用拥有的api接口权限。所以我们来运行上文的sql语句。user_id可以随便选,出了1之外。
回到IDEA,可以看到给用户分配的API权限已经查到了。
就在此时,小插曲来了。我本来就是想做个实验。可以看到,现在普通用户是拥有menu_id为1000的权限的,对应的api也就是用户查询system:user:list对应的url也就是/system/sys_user/list。我们现在进入超级管理员账户,来把普通用户的用户管理权限关闭。
保存后,我们再去数据中查看。可以看到数据库中sys_role_menu表已经没1000了,就是说/system/sys_user/list这个api接口普通用户已经无权访问了。
但是我们使用burp抓包,将cookie变为普通用户的cookie,发现还是能访问到这个api接口。
于是我重新调试,百思不得其解时,我重新翻权限分配,发现,这怎么还有一个system:user:list。
于是我重新执行那条数据库查询命令。还真发现了一个
马上去看其他的表,发现sys_menu表中,还有一个system:user:list
对应的sys_role_menu表中,也有2001。
我当时就666了。
删除这个权限,我们再尝试。重新启动IDEA。已经查不到system:user:list这个api了。
返回的包也出现500
六、小插曲结束
但是还是蛮有意思的,比我自己想做的那个简单把system:user:list注释学到太多。但是这个注释还得接着来。
抓到了
五、业务逻辑漏洞-字段爆破
-
常见的爆破字段有用户名、密码、验证码。
-
从白盒来讲,通过审计源代码包括字段的类型,例如整型,有规律的字符串作为数据的唯一标识。
-
此类漏洞通过黑盒直接测试比较方便,一般情况下只要使用了验证码(图形验证码、短信验证码)一般情况下不可被破解。
1、审计方法
- 追踪登录功能,查看后端源码是否在登录成功之前进行了验证码的刷新
- 在修改密码处可能不会在进行验证码设置,从而造成用户名爆破。
- 搜索是否提示用户名不存在且未关联验证码的情况。
**2、修复方案
**
- 凡是涉及到用户判断的情况反馈模糊提示信息,不得直接提示用户名不存在。
- 凡是判断用户名和密码认证情况,需要增加验证码来判断逻辑来避免爆破。
- 设置基于IP锁定和一定时间内账号错误输入次数机制,来避免爆破密码情况。
- 通过增加具有一定复杂度的验证码来防止爆破。
**
**
六、业务逻辑-支付漏洞
支付漏洞一般是程序员对异常的情况未进行安全考虑,具体包括:
- 支付、取款、转账任意金额的修改,未对正负数、原金额足额比较
- 来自前端的金额直接执行支付操作,未对前端折扣金额等于后端的金额比对,是产生支付漏洞是一种常见的现象。
如果单价,折扣,原价,积分等等的不与数据库进行比对的话,将会出现任意金额下单,购买的业务 逻辑漏洞
如果未对同一客户端IP、同一用户、同一时间段内重复下单的频率进行先限制和提醒,将会造成无限 刷单。
审计技巧:
寻找支付相关业务逻辑,确定是否对金额进行负数、原账号金额、前端支付变量与数据库 真正定价比较
七、业务逻辑-filter过滤器让
filter被称为过滤器,是Servlet2.3新增的一个特性,同时它也是 Servlet 技术中最实用的技术。开发人 员可以通过Filter技术,能够实现对所有Web资源的管理,如实现权限访问控制、过滤敏感词汇、压缩 响应信息、全局编码配置、登录认证等一些高级功能。
1、绕过原理分析
/user/loginServlet、/user/toLoginServlet开头,符合匹配的规则,而匹配上该规则后则是直接放 行,让系统认为访问路径是一个登录的路径,但在后面加入…/进行跳转到根目录,并且拼接上 indexServlet,这时候实际访问到的是http://127.0.0.1:8085/user/indexServlet
2、filter过滤器…/绕过-修复方案1
if (uri.contains("./")){ System.out.println("输入非法"); request.getRequestDispatcher("/login.jsp").forward(request, response); }
3、手动filter过滤器-;绕过
1、修复方法绕过-URL截断绕过:这也是对上一个修复方法的绕过,我们还是使用原来的靶场进行查 看。payload:/user/indexServlet;123
2、绕过原理分析:URL中有一个保留字符分号;,主要为参数进行分割使用,有时候是请求中传递的参数太多了,所以使 用分号;将参数对(key=value)连接起来作为一个请求参数进⾏传递。再来看到代码,代码中识别.do 和.action的后缀的字符,而加入;加上随便内容后,代码中就识别不到了。则会走到最下面的 chain.doFilter(request,resp);,而在后面添加;分号不会对地址的访问有任何影响。
4、手动filter过滤器-;绕过-修复
前面提到过request.getRequestURL),这些危险字符并不会自动剔除掉。可重点关注该方法。
关于手写过滤器的绕过的总结:
(1)两个场景,第一是基于…/截断,第二是基于;截断,对应通过黑名单通过相关API获取uri剔除特殊 的字符去分别防止两个场景的绕过
(2)当你遇到了手写的过滤器,要基于以上两个场景去判断是否存在该问题。
接下来我将给各位同学划分一张学习计划表!
学习计划
那么问题又来了,作为萌新小白,我应该先学什么,再学什么?
既然你都问的这么直白了,我就告诉你,零基础应该从什么开始学起:
阶段一:初级网络安全工程师
接下来我将给大家安排一个为期1个月的网络安全初级计划,当你学完后,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web渗透、安全服务、安全分析等岗位;其中,如果你等保模块学的好,还可以从事等保工程师。
综合薪资区间6k~15k
1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)
2、渗透测试基础(1周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等
3、操作系统基础(1周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)
4、计算机网络基础(1周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现
5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固
6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)
那么,到此为止,已经耗时1个月左右。你已经成功成为了一名“脚本小子”。那么你还想接着往下探索吗?
阶段二:中级or高级网络安全工程师(看自己能力)
综合薪资区间15k~30k
7、脚本编程学习(4周)
在网络安全领域。是否具备编程能力是“脚本小子”和真正网络安全工程师的本质区别。在实际的渗透测试过程中,面对复杂多变的网络环境,当常用工具不能满足实际需求的时候,往往需要对现有工具进行扩展,或者编写符合我们要求的工具、自动化脚本,这个时候就需要具备一定的编程能力。在分秒必争的CTF竞赛中,想要高效地使用自制的脚本工具来实现各种目的,更是需要拥有编程能力。
零基础入门的同学,我建议选择脚本语言Python/PHP/Go/Java中的一种,对常用库进行编程学习
搭建开发环境和选择IDE,PHP环境推荐Wamp和XAMPP,IDE强烈推荐Sublime;
Python编程学习,学习内容包含:语法、正则、文件、 网络、多线程等常用库,推荐《Python核心编程》,没必要看完
用Python编写漏洞的exp,然后写一个简单的网络爬虫
PHP基本语法学习并书写一个简单的博客系统
熟悉MVC架构,并试着学习一个PHP框架或者Python框架 (可选)
了解Bootstrap的布局或者CSS。
阶段三:顶级网络安全工程师
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!
学习资料分享
当然,只给予计划不给予学习资料的行为无异于耍流氓,这里给大家整理了一份【282G】的网络安全工程师从入门到精通的学习资料包,可点击下方二维码链接领取哦。
