皮卡丘靶场解题记录-越权

水平越权

1、漏洞原理总结:

越权 = 用 A 用户的权限,去操作 B 用户的数据或功能 (A 的权限 ≤ B)。

分两种,水平越权和垂直越权。水平越权是A干了同级别的B才能干的事情,垂直越权是A干了比它权限更高的C才能干的事情。越权属于 OWASP Top 10 里的Broken Access Control(失效的访问控制),常年霸榜第一,SRC里极常见。

image-20260820180906111

2、我的测试过程:

James先登录

image-20260820181812763

不经登录,直接把url里面的username修改即可查看其他用户信息image-20260820181941259

post传参同样可用,漏洞不因传参方式改变而改变。(前面讲过)

3、核心漏洞代码分析:

在代码op1_mem.php中可以找到内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if(isset($_GET['submit']) && $_GET['username']!=null){
//没有使用session来校验,而是使用的传进来的值,权限校验出现问题,这里应该跟登录态关系进行绑定
$username=escape($link, $_GET['username']);
//这个函数前面的关卡查验过,只做了防注入,没做权限校验
$query="select * from member where username='$username'";
//用前端查的username查数据,很显然,只要有心,可以任意修改
$result=execute($link, $query);
if(mysqli_num_rows($result)==1){
$data=mysqli_fetch_assoc($result);
$uname=$data['username'];
$sex=$data['sex'];
$phonenum=$data['phonenum'];
$add=$data['address'];
$email=$data['email'];

$html.=<<<A
<div id="per_info">
<h1 class="per_title">hello,{$uname},你的具体信息如下:</h1>
<p class="per_name">姓名:{$uname}</p>
<p class="per_sex">性别:{$sex}</p>
<p class="per_phone">手机:{$phonenum}</p>
<p class="per_add">住址:{$add}</p>
<p class="per_email">邮箱:{$email}</p>
</div>
A;
}
}

它查个人信息用的 $_GET[‘username’] —— 是浏览器 URL 里传的值 ,而不是登录时的 $_SESSION[‘op’][‘username’] (登录态)所以:以 lucy 登录,把 URL 里的 username 改成 lili ,后端照样查 lili 的信息给你看。

防御方法:

查数据应该用 $_SESSION 里的登录用户名,或者加一句判断”要查的用户名 == 当前登录用户名”,否则拒绝。

4、实战延伸:

image-20260820182146925

垂直越权:

1、漏洞原理总结:

见上文,此处略

2、我的测试过程:

登录admin的账号进入添加用户界面

image-20260821004219785

这里可以看到管理界面的url,http://101.43.30.86/pikachu/vul/overpermission/op2/op2_user.php

登录pikachu

image-20260821004338993

可以看到是只有查看权限的

image-20260821004425644

但是这里存在垂直越权,只对登录状态进行了查验,账号权限没有查验,所以,可以在登录pikachu这个普通账户的情况下,用之前的那个url直接进入前面看到的管理员编辑页面

image-20260821004624245

3、核心漏洞代码分析:

对比可以发现,在删除用户页op2_admin.php 第 23 行,同时对用户登录和用户级别做了校验

image-20260821003657118

但是在用户添加页op2_admin_edit.php 第 22 行,只查了登录,没查级别,造成垂直越权的存在

image-20260821003810748

防御:

凡是管理员功能,都要像 op2_admin.php 那样, 同时校验登录 + 级别 : check_op2_login($link) || $_SESSION[‘op2’][‘level’]!=1

4、实战延伸:

image-20260821004034621

章节答疑:

1、实战中比较常见的越权形式是什么样的?靶场里的这两种感觉很离谱,应该不会这么简单?

水平越权:

标准术语叫 IDOR(不安全的直接对象引用),本质就是改ID,在信息里把自己的id改成别人的,看能不能看到不应该由自己这个账户的权限看到的东西。

image-20260821005632705

改 id 、 userId 、 orderId 、 uuid 这类参数 ,而且有时ID是随机串/加密,得先摸规律。

垂直越权:

本质就是,低权限+高权限资源,看能不能通。

image-20260821005827945 image-20260821005906492

2、黑盒情况下怎么判断越权漏洞的存在呢?尤其是垂直越权,在不知道管理员账号密码的情况下,不进去看到管理员的编辑路径的话,好像没办法确认垂直越权的存在?

水平越权:注册两个账号来尝试。

  1. 注册两个账号 A 和 B 。
  2. A 登录,访问”我的订单/资料”, 抓包 ,找到代表”身份”的参数( id / userId / uuid )。
  3. B 登录,同样操作,抓包拿到 B 的 id 。
  4. 用 A 的 Cookie/token,把请求里的 id 改成 B 的 id 重放。
  5. 如果能返回 B 的数据 → 水平越权成立 。

A 的登录态 + B 的 id = 看到 B 的数据,就是水平越权。

垂直越权:不知道管理员密码,也能测

第一步,先找管理员接口,方法如下:

image-20260821010215620

第二步,用低权限账号去够。用普通账号登录,带着自己的 Cookie/token, 直接访问找到的管理接口尝试

第三步,参数篡改(如果请求里有角色字段),如果接口请求里带 role 、 level 、 isAdmin 、 type 这类字段,试着改一下

1
2
3
isAdmin=0  →  isAdmin=1
role=user → role=admin
level=2 → level=1
  1. 一个 低权限账号 (或甚至未登录);
  2. 找到 高权限接口(靠 JS 泄露/爆破/文档);
  3. 用低权限账号去 访问 ,看它”给不给不该给的东西”。

判定标准永远是: 低权限者 + 高权限资源 = 是否成功 。