逻辑越权漏洞(Business Logic Vulnerability)是指攻击者利用应用程序业务逻辑中的漏洞,绕过正常的安全控制,执行未授权的操作。与常见的技术性漏洞不同,逻辑越权漏洞通常与应用程序的功能和流程有关,需要对应用程序的业务逻辑有深入理解才能发现和利用。
逻辑越权漏洞的类型
-
水平越权:攻击者以普通用户身份,执行只有其他普通用户或特定用户组才能执行的操作。例如,修改他人的订单信息或查看他人的私人数据。
-
垂直越权:攻击者以低权限用户身份,执行只有高权限用户(如管理员)才能执行的操作。例如,普通用户提升自己的权限或访问管理后台。
接下来我们以pikachu靶场中的逻辑越权漏洞靶场来进行逻辑越权漏洞的原理阐述:
示例
Ⅰ.水平越权
1.点开漏洞靶场页面,显示一个登录页面;在此处我们选择kobe账户进行登录(kobe/123456);不知道当前系统中存在哪些账户可以直接查看Mysql中的pikachu数据库中的member表中的内容即可。
2.登录完成后显示一个查看个人信息的按钮点击按钮后会显示当前登录用户的相关信息。
3.此时我们开始进行测试:打开Burpsuite工具,然后点击查看个人信息按钮进行请求数据包的抓取。
可以看到实际上请求包中就包含了我们要查询信息的账户名;
4.若这个时候我们尝试将请求包中的username字段后的数据;将其改为其他账户的用户名(在实际情况下就要求我们先获得其他账户的用户名);在此处我们将username字段后的数据改为lucy。
接着放行数据包,查看响应页面的内容:可以看到此时显示的信息就是lucy的信息了。
此时我作为攻击者就以是普通用户身份,执行其他普通用户才能够执行的操作;即以kobe用户执行了只有lucy才能执行的查看lucy账户信息的操作。
相关程序代码:
php
$html='';
if(isset($_GET['submit']) && $_GET['username']!=null){
//没有使用session来校验,而是使用的传进来的值,权限校验出现问题,这里应该跟登录态关系进行绑定
$username=escape($link, $_GET['username']);
$query="select * from member where 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;
}
}
示例中可以看出,这段代码存在水平越权漏洞。当前的代码根据传入的username
参数来查询用户信息,但没有验证当前登录用户的身份,导致攻击者可以通过修改username
参数来访问其他用户的敏感信息。
以下是改进建议,以防止水平越权漏洞:
-
使用会话(Session)验证当前登录用户:通过会话来存储和验证用户身份,确保用户只能访问自己的信息。
-
参数验证:确保请求参数的合法性,并进行必要的过滤和转义。
Ⅱ.垂直越权
A用户权限高于B用户,B用户越权操作A用户的权限的情况称为垂直越权
1.打开靶场后发现页面还是一个登录框,这个时候我们可以点击提示进行提示获取;(事实上在实际场景时普通用户我们可以直接自己注册,而管理员用户可以尝试弱口令爆破)
首先我们登录pikachu用户查看页面信息:可以看到普通账户pikachu对于账户只有查看信息的权限。
接着我们查看一下admin账户的相关页面信息:在admin用户权限,我们可以对用户列表进行管理;如用户添加和用户删除、用户查看。
漏洞利用:
在admin权限我们创建用户并抓包;这里我创建一个wolvenchan用户:
接着我们将抓到的数据包发送至重放模块(快捷键ctrl + R);其实除了创建用户这个请求包之外,对于删除用户的数据包我们也可以进行抓取;(管理员权限所能进行的操作的相关数据包都可以进行抓取);后续在进行越权操作的时候我们就需要使用到这些数据包。
OK,接下去退出admin用户,转到普通账户pikachu中;接着打开BP进行抓包,刷新一下网页获取pikachu用户操作的数据包,在数据包中有我们需要的字段--PHPSESSID ,此时我获取到的PHPSESSID为:
php
ei3u0rv2admrg014gn2aq9do77
接着来到重放模块,找到在上一步我们抓取到的管理员账户进行创建账户操作的数据包,将数据包中的PHPSESSID修改为普通账户pikachu的PHPSESSID,并且编辑我们想要进行添加的账户:(如此时想要添加一个hackerman账户,密码性别那些就随便了)
数据包发送完毕后我们以普通用户权限查看页面:
可以看到此时出现了hackerman用户;这就说明了我们使用了普通账户的身份做了需要管理员账户权限才能做的事情。接着我们通过源代码来分析一下漏洞产生的原因:
php
// 判断是否登录,没有登录不能访问
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']}')";
$result=execute($link, $query);
if(mysqli_affected_rows($link)==1){//判断是否插入
header("location:op2_admin.php");
}else {
$html.="<p>修改失败,请检查下数据库是不是还是活着的</p>";
}
}
}
在该段代码中只检查了当前客户端是否处于登录状态,如果在登录状态则可以进行用户新建操作;事实上这个时候代码并没有判断此时登录的客户端的相关权限,所以产生了越权漏洞。这个漏洞需要我们获取到管理员账户进行各种操作的数据包;所以基本上需要我们先通过各种渠道获取管理员账户密码/权限,在获得到相关的数据包后,基本上就算后续管理员的密码更改了,我们也可以通过这个漏洞使用需要管理员权限的功能。