3.4 逻辑漏洞
逻辑漏洞是指在程序开发过程中,由于对程序处理逻辑未进行严密的考虑,导致在到达分支逻辑功能时,不能进行正常的处理或导致某些错误,进而产生危害。
一般而言,功能越复杂的应用,权限认证和业务处理流程越复杂,开发人员要考虑的内容会大幅增加,因此对于功能越复杂的应用,开发人员出现疏忽的可能性就越大,当这些出现疏忽的点会造成业务功能的异常执行时,逻辑漏洞便形成了。由于逻辑漏洞实际依托于正常的业务功能存在,因此业务功能的不同直接导致每个逻辑漏洞的利用都不相同,也就无法像SQL注入漏洞总结出一个通用的利用流程或绕过方法,而这对于测试人员在业务逻辑梳理方面便有着更高的要求。
与前面的SQL注入、文件上传等传统漏洞不同,如果仅从代码层面分析,逻辑漏洞通常是难以发现的。因此,传统的基于“输入异常数据—得到异常响应”的漏洞扫描器对于逻辑漏洞的发现通常也是无力的。目前,对于逻辑漏洞的挖掘方法仍以手工测试为主,并且由于与业务功能密切相关,也就与测试人员的经验密切相关。
3.4.1 常见的逻辑漏洞
由于逻辑漏洞实际依托于正常的业务功能存在,无法总结出一个对所有逻辑漏洞行之有效的利用方法,但是对于这些逻辑漏洞而言,导致其发生的原因存在一定共性,凭此可以将这些逻辑漏洞进行一个粗略的分类,归结为两种:权限问题、数据问题。
1.与权限相关的逻辑漏洞
我们先了解什么是权限相关的逻辑漏洞。在正常的业务场景中,绝大多数操作需要对应的权限才能进行。而常见的用户权限如匿名访客、普通登录用户、会员用户、管理员等,都拥有其各自所特有的权限操作。匿名访客权限可执行的操作如浏览信息、搜索特定内容等,而登录权限则可以确认订单支付,会员权限可以提前预约等,这些操作与用户所拥有的权限息息相关。
当权限的分配、确认、使用这些过程出现了问题,导致某些用户可执行他本身权限所不支持的特权操作,此时便可称为发生了与权限相关的逻辑漏洞。
权限逻辑漏洞中常见的分类为未授权访问、越权访问、用户验证缺陷。
未授权访问是指用户在未经过授权过程时,能直接获取原本需要经过授权才能获取的文本内容或页面等信息。其实质是由于在进行部分功能开发时,未添加用户身份校验步骤,导致在未授权用户访问相应功能时,没有进行有效的身份校验,从而浏览了他原有权限不支持查看的内容,也就是导致了未授权访问(见图3-4-1)。
越权访问主要为横向越权和纵向越权。横向越权漏洞指的是权限同级的用户之间发生的越权行为,在这个过程中,权限始终限制在同一个级别中,因此被称为横向。与之相对,纵向越权漏洞则指在权限不同级的用户之间发生了越权行为,并且通常是用来描述低级权限用户向高级权限用户的越权行为。
图3-4-1
假设存在两个用户A和B,各自拥有3种行为的权限,见图3-4-2。
图3-4-2
横向越权即用户A与用户B之间的越权,如用户A可查看用户B的历史订单信息,其中权限变更过程为“普通用户 → 普通用户”(见图3-4-3),本质的权限等级未变化。
图3-4-3
纵向越权则会涉及管理员与用户之间的权限变更,如用户A通过越权行为可对首页广告进行编辑,那么权限变更过程为“普通用户 → 高级权限用户”,本质的权限等级发生了变化。
用户验证缺陷通常会涉及多个部分,包括登录体系安全、密码找回体系、用户身份认证体系等。通常而言,最终目的都是获取用户的相应权限。以登录体系为例,一个完整的体系中至少包括:用户名密码一致校验,验证码防护,Cookie(Session)身份校验,密码找回。例如,Cookie(Session)身份校验,当用户通过一个配对的用户名与密码登录至业务系统后,会被分配一个Cookie(Session)值,通常表现为唯一的字符串,服务端系统通过Cookie(Session)实现对用户身份的判断,见图3-4-4。
图3-4-4
打开浏览器的控制台,通过JavaScript可以查看当前页面拥有的Cookie,见图3-4-5。或者在网络请求部分也可以查看当前页面Cookie,见图3-4-6。
图3-4-5
图3-4-6
Cookie数据以键值对的形式展现,修改数值后,对应Cookie键的内容便同时被修改。若Cookie中用于验证身份的键值对在传输过程中未经过有效保护,则可能被攻击者篡改,进而服务端将攻击者识别为正常用户。假设用于验证身份的Cookie键值对为“auth_priv=guest”,当攻击者将其修改为“auth_priv=admin”时,服务端会将攻击者的身份识别为admin用户,而不是正常的guest,此时便在Cookie验证身份环节产生了一个Cookie仿冒的逻辑漏洞。
对于Session机制而言,由于Session存储于服务端,攻击者利用的角度会发生些许变化。与Cookie校验不同的是,当使用Session校验时,用户打开网页后便会被分配一个Session ID,通常为由字母和数字组成的字符串。用户登录后,对应的Session ID会记录对应的权限。其验证流程见图3-4-7。
Session验证的关键点在于“通过Session ID识别用户身份”,在该关键点上对应存在一个Session会话固定攻击,其攻击流程见图3-4-8。
图3-4-7
图3-4-8
简单而言,其攻击流程如下:攻击者打开页面,获得一个Session ID,我们将其称为S;攻击者发送一个链接给受害者,使得受害者使用S进行登录操作,如http://session.demo.com/login.php?sessionId=xxxx;受害者B执行登录后,S对应的Session ID将包含用户B的身份识别信息,攻击者同样可以通过S获得受害者B的账号权限。
2.与数据相关的逻辑漏洞
现实中,对于业务功能交织的购物系统,正常的业务功能会涉及多种场景,如商品余额、金钱花费、商品归属判定、订单修改、代金券的使用等。以其中的购买功能为例,购买过程中会涉及商户商品余额变化、买方金额的消费、服务端的交易历史记录等数据,由于涉及的数据种类较多,因此在实际开发过程中,对于部分数据的类型校验便存在考虑不周的可能,如花费金额的正负判定、数额是否可更改等问题。这些问题往往都不是由代码层面的漏洞直接导致,而是由于业务处理逻辑的部分判断缺失导致的。
与数据相关的逻辑漏洞通常将关注点放在业务数据篡改、重放等方面。
业务数据篡改包含了前文提到的诸多问题,与开发人员对正常业务所做的合法规定密切相关,如限购行为中,对于最大购买量的突破也是作为业务数据篡改来看待。除此之外,在购买场景下常见的几个业务数据篡改可包括:金额数据篡改,商品数量篡改,限购最大数修改,优惠券ID可篡改。不同场景下,可篡改的数据存在差异,需要针对实际情况具体分析,因此上面4类数据也只是针对购买场景而言。
攻击者通过篡改业务数据可以修改原定计划执行的任务,如消费金额的篡改,若某支付链接为http://demo.meizj.com/pay.php?money=1000&purchaser=jack&productid=1001&seller=john。其中,各参数含义如下:money代表本次购买所花费的金额,purchaser代表购买者的用户名,productid代表购买的商品信息,seller代表售卖者用户名。
若后台的购买功能是通过这个URL来实现的,那么业务逻辑可以描述为“purchaser花费了money向seller购买了productid商品”。当交易正常完成时,purchaser的余额会扣除money对应的份额,但是当服务端扣费仅依据URL中的money参数时,攻击者可以轻易篡改money参数来改变自己的实际消费金额。例如,篡改后的URL为http://demo.meizj.com/pay.php?money=1&purchaser=jack&productid=1001&seller=john。此时,攻击者仅通过1元便完成了购买流程。这本质上是因为后端对于数据的类型、格式没有进行有效校验,导致了意外情况的产生。
所以,在笔者看来,数据相关的逻辑漏洞基本均为对数据的校验存在错漏所导致。
3.4.2 CTF中的逻辑漏洞
相较于Web安全的其他漏洞,逻辑漏洞通常需要多个业务功能漏洞的组合利用,因此往往存在业务体系复杂的环境中,部署成本颇大,在CTF比赛中出现的频率较低。
2018年,X-NUCA中有一道名为“blog”的Web题目,实现了一个小型的OAuth 2.0认证系统,选手需要找出其中的漏洞,以登录管理员账号,并在登录后的后台页面获得flag。
OAuth 2.0是一个行业的标准授权协议,目的是为第三方应用颁发具有时效性的Token,使得第三方应用可以通过Token获取相关资源。常见的场景为需要登录某网站时,用户未拥有该网站账号,但该网站接入了QQ、微信等快捷登录接口,用户在进行快捷登录时使用的便是OAuth 2.0。
OAuth 2.0的认证流程见图3-4-9,具体为:客户端页面向用户请求授权许可→客户端页面获得用户授权许可→客户端页面向授权服务器(如微信)请求发放Token→授权服务器确认授权有效,发放Token至客户端页面→客户端页面携带Token请求资源服务器→资源服务器验证Token有效后,返回资源。
这个题目中存在以下功能:普通用户的注册登录功能;OAuth网站的用户注册登录功能;将普通用户与OAuth网站账号绑定;发送一个链接至管理员,管理员自动访问,链接必须为题目网址开头;任意地址跳转漏洞。
在进行普通用户与OAuth的账号绑定时,先返回一个Token,随后页面携带Token进行跳转,完成OAuth账号与普通用户的绑定。携带Token进行账号绑定的链接形式为:http://oauth.demo.com/main/oauth/?state=******。访问链接后,将自动完成OAuth账号与普通账号的绑定。
图3-4-9
此时攻击点出现了,关键在于普通用户访问携带了Token的链接便能完成普通账号与OAuth账号的绑定;同理,管理员访问该链接同样可以完成账号的绑定。此处可以利用任意地址跳转漏洞,在远程服务器上部署一个地址跳转的页面,跳转地址便是携带Token进行绑定的链接。当管理员访问提交的链接时,先被重定向至远程服务器,继续被重定向至绑定页面,从而完成OAuth账号与管理员账号的绑定。至此,使用OAuth账号快捷登录,便可登录管理员账号。
3.4.3 逻辑漏洞小结
相较于前面提到的各种Web漏洞,逻辑漏洞没有一种固定的格式来呈现。要进行逻辑漏洞的挖掘,需要参赛者对业务流程做到心中有数。现实环境下的逻辑漏洞挖掘还需要考虑多种认证方式及不同的业务线,这里不再讨论,读者可以在日常工作生活中发现其中的乐趣。