图21-7 测试访问控制
(1)根据应用程序的核心功能,了解访问控制在垂直隔离(拥有不同权限的用户可访问不同类型的功能)与水平隔离(拥有相同权限的用户可访问不同的数据)方面的主要要求,通常,应用程序会使用两种权限隔离,例如,普通用户能够访问自己的数据,而管理员则能够访问每个人的数据。
(2)检查应用程序解析过程得到的结果,确定最可能成为权限提升攻击目标的功能区域与数据资源类型。
(3)为提高测试访问控制漏洞的效率,渗透测试员应该获得大量拥有不同垂直权限与水平权限的账户。如果应用程序允许自我注册,渗透测试员就可以直接获得大量拥有不同水平权限的账户。为获得拥有不同垂直权限的账户,需要得到应用程序所有者的帮助(或利用某个漏洞访问一个高权限账户)。如后文所述,能否获得各种不同的账户将会对能够进行的测试产生直接影响。
(1)如果应用程序实施垂直权限隔离,那么首先使用一个高权限账户确定它能访问的所有功能,然后再使用一个低权限账户尝试访问上述每一项功能。
(a)使用Burp在一个用户的权限下浏览应用程序的所有内容。
(b)复查Burp的站点地图内容,确保已确定要测试的所有功能。然后,注销应用程序并使用另一个用户账户登录;使用上下文菜单选择“比较站点地图”(compare site maps)功能,确定较低权限的用户可以访问哪些高权限请求。请参阅第8章了解这种技巧的更多详情。
(2)如果应用程序实施水平权限隔离,那么使用两个拥有相同权限的不同账户进行同等测试,尝试使用一个账户访问属于另一个账户的数据。通常,这需要替换请求中的一个标识符(如一个文档ID),以指定属于其他用户的资源。
(3)手动检查关键访问控制逻辑。
对于每个用户权限,复查用户可用的资源。尝试通过使用未授权用户的会话令牌,从未授权用户账户重新提交请求来访问这些资源。
(4)进行访问控制测试时,一定要分别测试多阶段功能的每一个步骤,确定每一个阶段是否正确实施了访问控制;或者应用程序是否认为访问后一个阶段的用户一定通过了前面阶段实施的安全检查。例如,如果一个包含表单的管理页面受到恰当保护,检查提交表单的过程中是否同样实施了合理的访问控制。
(1)如果不能优先访问不同权限的账户,或者优先访问几个能够访问不同数据的账户,那么测试不完善的访问控制机制可能相当困难。由于并不知道利用各种缺陷所需的URL名称、标识符和参数,因此许多常见的漏洞将更加难以确定。
(2)在使用低权限账户解析应用程序的过程中,渗透测试员可能已经确定了访问管理接口等特权功能的URL。如果这些功能没有得到充分保护,渗透测试员可能已经了解了这一点。
(3)反编译现有的所有已编译客户端,并提取对服务器端功能的任何引用情况。
(4)大多数受到水平访问控制保护的数据可使用一个标识符(如一个账号或订单号)访问。为了使用一个账户测试访问控制是否有效,需要尝试、猜测或发现与其他用户的数据有关的标识符。如有可能,生成一系列紧密相连的标识符(例如,通过建立几个新订单),尝试确定所有可帮助预测发布给其他用户的标识符的模式。如果无法生成新的标识符,就只能分析已经确定的标识符,并根据这些标识符猜测其他标识符。
(5)如果能够预测出发布给其他用户的标识符,使用第14章描述的技巧实施自动攻击,获取属于其他用户的有用数据。可使用Burp Intruder的Extract Grep功能从应用程序的响应中截获相关信息。
(1)一些应用程序根据请求参数以一种内在不安全的方式实施访问控制。在所有关键请求中寻找edit=false或access=read之类的参数,根据它们的主要作用修改这些参数,尝试破坏应用程序的访问控制逻辑。
(2)一些应用程序根据HTTP Referer消息头做出访问控制决策。例如,一个应用程序可能对/admin.jsp实施严格的访问控制,并接受在Referer中显示它的所有请求。为测试这种行为,尝试执行一些获得授权的特权操作,并提交一个其中缺少Referer消息头或Referer消息头被修改的请求。如果这种改变导致应用程序阻止请求,应用程序很可能以不安全的方式使用Referer消息头。尝试使用一个未通过验证的用户账户执行相同的操作,但提交原始的Referer消息头,看这时是否能够成功执行操作。
(3)如果站点允许HEAD方法,则应测试针对URL的不安全的容器托管访问控制。使用HEAD方法提出请求,确定应用程序是否允许该方法。