5.4.2 垂直权限提升

垂直权限提升是升级或者获得更高账户状态或者权限水平的能力。有4种典型的场景导致垂直权限提升:

·用户可修改的角色: 应用不恰当地允许未授权用户改变其角色信息。

·劫持账户: 发生在未授权用户可能劫持另一个特权用户的账户或者会话时。

·利用其他安全缺陷: 通过其他安全缺陷获得管理区域的访问权,修改权限的能力。

·不安全的管理功能: 没有正确授权的管理功能。

我们来看看现实中以上场景的实例。

用户可修改的角色

我们在本章中已经多次看到,许多Web应用在用户可修改的位置存储授权数据,如权限级别或者角色级别。我们刚刚看到一个Web购物应用将角色信息以普通文本值存储在cookie中。举一个具有垂直提升风格的相似例子,考虑一个虚构的Web应用,特权管理界面在http://www.site.com/siteAdmin/menu.aspx。当我们正常地访问这个页面时,服务器响应HTTP 302 redirect,回到管理登录屏幕。对HTTP的进一步分析揭示了从客户端向服务器传递了如下cookie:


Cookie: Auth=
897ec5aef2914fd153091011a4f0f1ca8e64f98c33a303eddfbb7ea29d217b34;
Roles=End User; HomePageHits=True;ASP.NET_SessionId=
dbii2555qecqfimijxzfaf55

Roles=End User值几乎就是这个应用将授权参数暴露给客户端操纵的确凿证据。为了测试能否操纵Roles cookie进行垂直权限提升攻击,我们用不同的Roles值,如Roles=admin、Roles=root和Roles=administrator,向应用服务器重发请求。在多次失败的尝试之后,我们更仔细地审视命名惯例,并且尝试Roles=Admin User,这导致了对管理页面的正常访问。令人伤心的是,我们在现实世界中的测试经历充满了更简单的场景,只要在URL中附加admin=true或admin=1就行了。

让我们来看一个更有挑战性的例子。在下面的虚构Web应用中,我们以普通用户登录到应用。在每个请求中发送的cookie看上去是这个样子:


Cookie: ASPSESSIONIDAACAACDA=AJBIGAJCKHPMDFLLMKNFLFME; X=
C910805903&Y=1133214680303; role=ee11cbb19052e40b07aac0ca060c23ee

我们立刻注意到名为role=的cookie,但是因为这个值的加密特性(又是一大串的字母数字!),我们在这里没有停留太久。在后续的水平提升测试中,我们创建第二个账户,以便进行差异分析(本章前面已作描述)。登录第二个账户时,每个请求所携带的cookie如下:


Cookie: ASPSESSIONIDAACAACDA=KPCIGAJCGBODNLNMBIPBOAHI; C=0&T=
1133214613838&V=1133214702185; role=ee11cbb19052e40b07aac0ca060c23ee

注意到什么不寻常的?role cookie和我们创建的第一个账户相同,说明这个值是静态的,不是为每个用户专门生成的。实际上,更仔细地观察发现,它类似于一个MD5 hash。Role值中的字符数为32个字符,你可以回忆一下我们之前对会话ID指纹识别的讨论,32字节值是代表MD5 hash的公认方法之一(是128位MD5 hash的十六进制表示)。这时,我们估计应用用户使用固定的role值,然后使用MD5算法计算散列值。

我的天!这可怕的密码。仅仅停下来一会儿,我们就实施了本质上和以前一样的权限提升攻击,将cookie改为role=admin,只使用MD5计算admin的散列值。计算散列并插入到请求之后,我们发出的cookie如下:


Cookie: ASPSESSIONIDAACAACDA=KPCIGAJCGBODNLNMBIPBOAHI; C=0&T=
1133214613838&V=1133214702185; role=21232f297a57a5a743894a0e4a801fc3

同样,role=的值是使用MD5计算的admin散列值。当我们用这个cookie请求账户主屏幕时,应用发回一个“302 redirect”,回到登录页面——不行。经过几次使用“administrator”和“root”(通常的嫌疑)的MD5 hash的人工尝试,我们决定继续前进,编写一个脚本自动化这个进程,从一个常见用户账户名词典中读取。同样,如果应用返回一个不为302 redirect的响应,那么我们就发现了正确的角色。这一进程没有花费太长的时间;运行这个脚本之后大约5分钟,我们发现Supervisor是正确的角色名,它为我们提供了应用的超级用户权限。

使用劫持的账户

水平权限提升通常很容易变成垂直提升。例如,如果授权令牌使用顺序标识符实现(就像你在前一个虚构Web购物网站示例中看到的),那么发现垂直权限提升的机会可能容易得只需猜测最低的有效账户ID,这个账户通常属于超级用户,因为这些账户一般最早创建。通常,较低的账户ID是开发人员或者应用管理员的账户,许多时候这些账户具有较高的权限。我们将在接下来的关于使用cURL映射权限的小节中讨论用顺序猜测识别管理账户的系统方法。

利用其他安全缺陷

这只是一个假设。通过其他安全缺陷如COTS组件中的缓冲区溢出或者SQL注入通常足于做出提升你的账户所需要的改变。例如,无处不在的Web统计页面泄露出管理界面的位置http://www.site.com/cgi-bin/manager.cgi,而这种页面不需要任何验证(我们在第8章中讨论寻找Web统计页面的常见方法)。你不信?别这么想——在我们多年的Web应用渗透测试的经历中,这种事例太经常发生了。

不安全的管理功能

在我们的经历中,我们发现许多Web应用的管理功能没有合适的验证或者授权。例如,考虑一个应用,用POST调用脚本http://www.site.com/admin/utils/updatepdf.asp,明显这是基于其存储文件夹的管理脚本。应用开发人员大概是这么想的:脚本应该只能从网站的管理部分访问,而管理部分需要验证。当然,具有修补倾向和在猜测目录命名惯例上有点运气的潜在入侵者很容易找到/admin/utils目录。对updatepdf脚本作点简单的操作就能指出它用ID号和文件名作为参数,将一个PDF文件上传到网站。即使作为普通用户运行,这个脚本也能替换任何当前提供给用户的PDF,就像你是合适的内容管理人员一样。拒绝服务就是在此之上编写出来的。更具有毁灭性的是,我们最终能够使用updatepdf脚本上传自己的ASP页面,这使我们几乎具有服务器的全部权限。