Pikachu靶场通关笔记(38) — Over Permission (垂直越权)

23次阅读
没有评论

1. 漏洞概述

在上一关中,我们了解了 水平越权 (同级别用户之间的数据越权访问)。这一次面对的是 垂直越权(Vertical Privilege Escalation)。

垂直越权 是指:由于后台只验证了用户是否登录,而没有验证用户的 权限级别,导致低权限用户(如普通会员)可以通过猜测、抓包等方式,直接访问并执行高权限用户(如管理员)才能访问的接口和功能。

本关卡的背景是:系统存在超级管理员 admin 和普通用户 pikachu。我们需要尝试用 pikachu 的身份,去执行只有 admin 才能执行的“添加用户”操作。


2. 闯关实操 (Privilege Escalation)

第一步:角色权限信息收集

首先,我们分别登录系统提示的两个测试账号,观察它们拥有的权限差异:

  1. 登录普通用户 pikachu/000000:页面提示“您只有查看权限!”,只能看到用户列表,没有任何操作按钮。
  2. 登录超级管理员 admin/123456:页面不仅有用户列表,右上角还多出了 “添加用户” 功能,列表中也多出了 “删除” 操作。

第二步:获取敏感操作 URL

admin 登录状态下,我们点击“添加用户”进入表单页面。此时我们要注意观察浏览器地址栏,记录下这个仅限管理员访问的 URL 路径:
http://localhost:8899/vul/overpermission/op2/op2_admin_edit.php

第三步:利用低权限账号实现垂直越权

有了高权限接口的地址,我们开始进行越权测试:

  1. 退出 admin 账号。
  2. 使用低权限普通账号 pikachu/000000 重新登录。
  3. 在浏览器地址栏中,直接强制输入 刚才记录的管理员功能地址:.../op2/op2_admin_edit.php 并回车。

结果: 页面没有拦截我们!我们成功以 pikachu 的身份进入了管理员专属的“添加用户”页面。

第四步:发包验证

为了验证这不是前端页面的障眼法,我们在该页面随便填写一些用户信息(例如创建一个名为 dwg 的新用户),点击“创建”。随后我们查看数据库表(见文章附图),发现新用户 dwg 的数据被结结实实地写入了数据库。垂直越权攻击彻底成功!

Pikachu 靶场通关笔记(38) — Over Permission (垂直越权)
Pikachu 靶场通关笔记(38) — Over Permission (垂直越权)

3. 源码分析 (Code Review)

为什么低权限账号可以直接访问高权限页面?我们来看看核心文件 op2_admin_edit.php 的源码逻辑:

$link=connect();
// 判断是否登录,没有登录不能访问
// 这里只是验证了登录状态,并没有验证级别,所以存在越权问题。if(!check_op2_login($link)){header("location:op2_login.php");
    exit();}

if(isset($_POST['submit'])){if($_POST['username']!=null && $_POST['password']!=null){// 用户名密码必填
        $getdata=escape($link, $_POST);// 转义
        $query="insert into member(username,pw,sex,phonenum,email,address) values('{$getdata['username']}',md5('{$getdata['password']}'),'{$getdata['sex']}','{$getdata['phonenum']}','{$getdata['email']}','{$getdata['address']}')";
        // ... 执行插入操作 ...
    }
}

漏洞成因一针见血:

代码中使用的 check_op2_login($link) 函数仅仅做了一件事:认证(Authentication),即检查当前是否有用户登录(Session 是否存在)。

但是,代码 完全缺失了授权(Authorization)校验。它没有去检查当前登录的这个用户,到底是个普通打工人还是超级大 Boss。只要你处于“已登录”状态,程序就默认给你放行,导致接下来的 INSERT INTO 数据库插入逻辑被无条件执行。


4. 修复建议

修复垂直越权漏洞的核心原则是:任何敏感 / 高权限操作接口,都必须在服务端进行严格的角色权限(Role/Level)校验。

通常的做法是在用户登录时,将用户的角色标识(如 level = 1 代表管理员,level = 2 代表普通用户)存入 Session 中。在访问特权页面时增加一层判断:

// 修复示例:不仅要验证是否登录,还要验证权限级别
if(!check_op2_login($link)){header("location:op2_login.php");
    exit();}

// 增加角色权限校验 (假设 session 中 level 为 1 是管理员)
if($_SESSION['op2']['level'] != 1){
    // 权限不足,拒绝访问
    die("您没有权限执行此操作!此行为已记录。");
    // 或者重定向到普通页面
    // header("location:op2_user.php");
    // exit();}
// 权限校验通过后,再执行后续的添加用户逻辑...
正文完
 0
评论(没有评论)