原文链接: https://dl.acm.org/doi/pdf/10.1145/2660267.2660337

本文发表在USENIX Security’14,第一作者是来自威斯康星大学麦迪逊分校的Maliheh Monshizadeh

1

作者在Web应用程序安全方面发布了不少的论文,在2016年,该作者还发布了一篇给Web应用程序逻辑漏洞打patch的文章。

背景知识

现代的Web应用程序通常会有用户角色划分,如游客、普通用户和管理员等。对于网站上的各种资源,不同的用户角色有不同的访问权限,所以网站通常会实现访问权限策略(access control policy)。但是如果开发者在实现这些访问控制权限设计时就存在缺陷,那么攻击者就可以访问到一些超出本身权限的资源和功能,这就是越权(Privilege Escalation)漏洞。

越权漏洞分为两种:

  1. 垂直越权漏洞 Vertical Privilege Escalation:权限低的攻击者可以访问高权限用户可访问的资源和功能。
  2. 水平越权漏洞 Horizontal Privilege Escalation:攻击者可以访问与之同级别的用户的资源和功能。

pe

举一个简单的例子:

2

上面这三段代码,Listing 1中定义了用户验证函数verifyUser,在Listing 2Listing 3中需要插入post或是删除post都需要先对用户进行session验证来确保用户已经登录,并且会对用户的权限的进行check,比如插入post,需要$permission['canWrite']true,方可进行后续的数据库敏感操作。

但是在有一些时候,开发者可能在用户的权限检查方面并没有严格的实现,就可能会造成一些越权操作的行为,从而对站点造成未知的伤害。比如下面的这几个不安全的delete操作。

3

Listing 4中,在进行删除操作之前并没有对用户的session进行验证,这其实是一种未认证账户无需认证可访问功能的垂直越权漏洞

4

Listing 5中虽然确保了当前用户已经登录,但是并没有对用户的操作权限进行检查就允许用户进行删除操作。

5

Listing 6中,虽然对用户的session和操作权限进行了检查,但是并没有检查用户是否能够进行deleteAll操作,只有管理员用户才能进行该操作。属于垂直越权漏洞

6

这段代码的问题在于程序没有检查请求删除的用户是否是文章的所有者,这是一个平行越权漏洞

上面这4个例子中的越权漏洞其实可以分成这么几种情况:

  1. the absence of any authorization(缺少授权验证)
  2. improper ownership or privileges corresponding to user role(用户和用户权限之间的miss-match)
  3. untrusted session variables(不可靠的session值)

设计与实现

设计

为了挖掘Web应用程序中存在越权漏洞,作者设计并实现了一款名为MACE的工具。

  • a) Authorization state

定义了一个四元组<U, R, S, P>。这四元组分别表示:

  • U:the set of authenticated users,经过身份验证的用户;
  • R:the set of role defined over the users,capturing different authorizations,定义在U的基础上,表示不同的用户角色,比如admin或者是非admin角色;
  • S:the set of session identifiers or session variables,标识用户的session;
  • R:the permissions defined on the resources(e.g. read, write),某个资源对应的限制权限。

简而言之该四元组即为<user-ids, roles, session identifiers, permissions>

比如Listing 4中在进行删除操作之前没有对当前的用户身份进行检查,所以对应的四元组为<-, -, -, ->

3

又比如Listing 6,当前的deleteAll操作应该仅限于admin用户,但是程序并没有检查当前的用户是不是admin,所以对应的四元组为<user, -, -, canWrite>

5

  • b) Authorization Context

基于Authorization State,作者提出了一个叫做Authorization Context,授权上下文的概念。结合Control Flow和Data Flow,可以计算某一个点的实际授权情况。比如下图是前面例子的授权上下文情况:

20

  • c) Authorization Context Consistency

因为不知道某一个资源点的正确的授权权限应该是怎么样的,所以作者提出了Authorization Context Consistency的概念。当应用程序使用相同的授权上下文沿着不同的路径去访问相同的资源时,我们就认为该点资源的授权上下文是一致的。

在下面这个例子中,利用$_SESSION['userID']将article和用户的身份信息关联在了一起,对应的four-tuple就是<$_SESSION['userID'], -, -, ->

16

然后是删除语句,发现在进行删除操作时,SQL语句仅需要提供被删除的post_id即可,并没有对进行删除操作的用户进行检查,对应的四元组是<-, -, -, ->,那么就可以造成一个水平越权:

17

正确的删除操作应该对文章的所有者进行检查,只有该文章的拥有者才有权限进行删除操作(article_author = $_SESSION['userID']):

18

但其实从这个例子我们可以看出一些问题。MACE在判断某个资源的上下文授权一致性的时候其实是依赖于对该资源进行的INSERT操作。如果INSERT语句处的授权是存在问题的,那么可能会造成False Negative增加。

实现

下图是MACE的系统架构:

7

主要分为以下几个部分:

  1. Inputs

程序的输入有两个:(a). 源代码;(b). Hints or annotation。

这里的Hints是指一些全局变量,图6是论文附录中给出的hints:

8

  1. Control Flow Analysis

MACE是基于静态分析的,先利用开源的工具Pixy和库TAPS生成CFG图,然后进行遍历,找到sink点(如query语句)。

  1. Data Dependency Analysis

在Web应用程序中,数据依赖关系通常是inter-procedural(程序间)的,比如说Listing 2中用到的用户验证函数verifyUser()就定义在文件verifyUser.php中,所以这一步的主要目的就是生成程序间的关系依赖图SSD(system dependence graph)。

  1. Slicing

这一步利用前面生成的SDG数据关系图和Hints,找到从source点sink点的所有路径,将结果放到Source-Sink Path List中。

  1. Authorization Context Analysis

这一步主要是生成带有上下文授权信息四元组的路径。

  1. Resource Access Analysis

虽然已经有了以四元组形式的上下文授权信息,但是有一些信息是隐藏在SQL查询语句之中的,比如以Listing 3为例:

23

比如第3行的query可以得到四元组<user, non-admin, -, canWrite>,但是在这个query语句中其实还有隐藏信息,需要满足两个WHERE语句:

1
2
article_ID = sanit($_GET['article_ID'])	# 用户可控
author_ID = $userID # 身份验证

其中当满足author_ID = $userID的时候,用户才能进行对应的文章删除操作,所以这是隐藏的权限校验。MACE经过symbolic execution之后得到了:

24

同时,MACE从得到的query中提取出新的约束Authorization Columns,对于这个例子就是author_ID = $_SESSION['userID']

  1. Context Comparison

最后一步就是在每次访问资源的时候进行授权上下文的一致性比较。

21

算法2中,先对INSERT语句进行分析。在line 2,先根据数据表名进行分类,然后进行上下文授权比对。最后的输出结果为表的authorization contexts和authorization columns。这里的输入是query语句及其authorization contexts,输出的结果是table的authorization contexts和authorization columns,并且先对INSERT语句进行了分析,因为authorization columns信息是先在INSERT语句处被定义的。接着需要对UPDATE语句和DELETE语句进行分析:

22

将INSERT语句处的authorization contexts和authorization columns与此处的进行对比,如果authorization contexts不一致,则说明存在一个Vertical Privilege Escalation;如果authorization columns不一致,则说明存在一个Horizontal Privilege Escalation。

实验评估

总体情况

作者使用了开源的工具Pixy和库TAPS来生成CFG并且枚举execution path。实验并不需要很高的配置,是在一台2.4GHz Intel, 4.0 GB RAM的MacBook Pro上完成的。

实验利用7个PHP CMS对MACE进行了测试,从下表Table 2可以看出,采用的CMS的代码行数跨度从1k到89k。

9

上表最后一列是程序进行漏洞分析花费的时间,其中95%的分析时间都是花费在生成关系依赖图和列举路径上。

漏洞实例

  1. phpns

phpns是一个开源的新闻系统,该系统一共有三种用户角色:(a). guest users,只能阅读一些新闻文章;(b). normal users,可以登录系统,可以访问文章管理面板,对文章进行管理;(c). admin user,可以管理整个系统,可以访问文章管理面板和用户管理面板。下面是normal users添加文章时程序进行的sql insert操作(Listing 8)以及文章删除操作(Listing 9):

11

可以看到,在删除文章时,只需要通过post请求提供相应文章的ID即可,这将导致未授权的guest users亦可以删除权限更高的normal users的文章,这是一个垂直越权漏洞。

  1. dcp-portal

dcp-portal是一个CMS,一共有两种用户角色:(a). admin user;(b). non-admin user。该CMS使用$_COOKIE['dcp5_member_admin']来判断当前的用户是不是admin。

12

当在agenda插入一个item的时候,是使用$_COOKIE['dcp5_member_admin']来标识user_id,但是在删除相应的item的时候,仅仅通过一个request请求参数agid来决定。所以只要是该系统中的任意yoghurt都可以根据agid来删除item,这是一个水平越权漏洞。

  1. SCARF

SCARF中存在一个垂直越权漏洞,SCARF使用$_SESSION['privilege']来区分普通用户和admin。在generaloptions.php中,admin可以删除任意user,但是在该文件中并没有对用户的身份进行验证,就导致了非admin权限用户可以删除用户,只需要提供想要删除的用户的email:

13

正确的做法,应该在删除用户操作之前对用户的身份进行校验,只有admin用户有权限进行该操作:

14

总体评价

作者提出的通过校验上下文授权一致性来寻找Web应用程序中的越权漏洞,是一种白盒测试,需要喂给MACE应用程序的源码。而且从作者给出的Evaluation情况来看,测试的一些CMS都没有很复杂的执行逻辑,比如Drupal:

25

而且对于这种动态调用,因为是基于静态分析的,但是目前的静态分析工具是很难解决动态调用的问题的,所以MACE还是存在一些局限性的。

思维导图

下面是在阅读论文时顺手整理的思维导图:

MACE