越权访问(Broken Access Contrlo简称BAC)是Web应用程序中一种常见的漏洞,由于其存在范围广,危害大在2019年OWASP列为Web应用中十大安全隐患第二名
该漏洞是指应用在检查授权时存在纰漏,使得攻击者在获得低权限用户账号后,利用一些方式绕过权限检查,访问或操作其他用户或者更高权限。越权漏洞的成因主要是因为开发人员在对数据进行增,删,改,查询时对客户端请求的数据过分相信而遗漏了权限的判定。越权访问漏洞主要分为水平越权和垂直越权访问。
水平越权访问是一种“基于数据的访问控制”设计缺陷引起的漏洞。由于服务器端在接受收到请求书进行操作时没有进行判断的所属人/所属部门而导致的越权数据访问漏洞
假设用户A和用户B属于同一角色,拥有相同的权限等级,他们能获取自己的私有数据(数据A和数据B),但如果系统只验证了能访问数据的角色,而没有对数据做细分或者校验,导致用户A能访问到用户B的数据(数据B),那么用户A访问数据的这种行为就叫做水平越权访问。
水平越权如何知道其他用户的id或者用户名
第一种:有些网站需要注册,你可以通过注册一些用户名,如果存在的话会出现提示"用户已存在",也就是说这个用户是存在的,那么这个就是她的用户名,在通过用户名寻找她的id编号
第二种:有些网站可以通过访问一些个人的空间/主页等看见这个人的用户名/id,这些也是属于渠道
可以通过各种渠道,主要看网站情况。
垂直越权是一种"基于URL的访问控制"设置引起的漏洞,又叫权限提升攻击。
例如:有A(Admin)B(普通用户),现在B通过一些特殊的方式使得获取到了A的权限。
特点就是使用了低权限身份的账号,发送高权限账号才有的请求,获得其高的权限操作,
通过删除请求中的认证信息后修改数据包后重新放改请求,依旧可以访问或完成操作。
获取一些高权限才能发起的数据包请求,比如添加用户的数据包等。
1.普通用户前端有操作界面,可以通过抓取数据包。
2.通过网站的源码,比如说这个网站可能是cms搭建的,就在信息收集的时候下载她cms的源码,本地搭建模拟,去抓取数据包。
3.盲猜 根据她的界面等网站情况自己去构造
1.前端造成的安全
界面。只对用户登录时候的等级进行判断,根据等级判断代码界面进行显示。没有对其他操作进行等级的判断
2.后端造成的安全
数据库
user表(管理员和普通用户同表)
usertype判断
从pikachu靶场可以看出她是以level来判断用户等级的。
uid:基本是判断用户的唯一标识符。有的管理员编号在10以内的是管理员,会员注册一般在10以后。(具体网站情况具体判断)
groupid:像论坛贴吧这种等级情况是非常鲜明的,比如大吧主,小吧主。初级贴吧会员,中级贴吧会员,高级贴吧会员等,这种就是通过你的groupid组编号来进行判定你的等级的,看你在哪个组,你就是什么权限。
1.前后端同时对用户输入信息进行校验,双重验证机制
2.调用功能前验证用户是否有权限调用相关功能
3.执行关键操作前必须验证用户身份,验证用户是否具备操作数据的权限
4.直接对象应用的加密资源id,防止攻击者枚举id,敏感数据特殊化处理
5.永远不要相信来自用户的输入,对于可控参数进行严格的检查于过滤
以上内容借鉴:水平越权访问与垂直越权访问漏洞_慢就是【快】的博客-CSDN博客
基于pikachu靶场演示-水平越权
提示有三个用户账号我们就随便挑一个账号进行登录
可以看到我登录是kobe的账号,现在我想登录到lucy的账号
开启bp抓包,刷新一下页面
可以看到这里只有一个数据包,我们就修改kobe的用户名,看看能不能 登录到lucy的账号
成功登录到lucy的账号
查看源代码
$link=connect();
//判断是是否登录,如果已经登录,点击时,直接进入会员中心
if(check_op_login($link)){
header("location:op1_mem.php");
}
$html='';
if(isset($_POST['submit'])){
if($_POST['username']!=null && $_POST['password']!=null){
$username=escape($link, $_POST['username']);
$password=escape($link, $_POST['password']);//转义,防注入
$query="select * from member where username='$username' and pw=md5('$password')";
$result=execute($link, $query);
if(mysqli_num_rows($result)==1){
$data=mysqli_fetch_assoc($result);
$_SESSION['op']['username']=$username;
$_SESSION['op']['password']=sha1(md5($password));
header("location:op1_mem.php");
}else{
$html.="登录失败,请重新登录
";
}
}
}
?>
$link=connect();
// 判断是否登录,没有登录不能访问
if(!check_op_login($link)){
header("location:op1_login.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.=<<
基于pikachu靶场演示-垂直越权
这里有两个用户admin有管理等权限,pikachu只有普通用户读的权限。
首先我先使用admi账号登录
这里可以看出admin有删除和添加用户的权限
登录pikachu用户
pikachu的用户只有查看的权限,那么我们的目标就是使用admin的权限添加一个数据包
再次登入admin账号,添加一个用户,开启bp进行抓取添加用户的数据包
抓取到数据包,把他发送到Repeater模块
发送完把这个数据包丢弃
使用pikachu用户登录
打开f12,将pikachu用户的cookie进行复制
打开bp,把之前抓取到修改的数据库的cookie进行替换
发送,在pikachu用户的界面进行刷新
可以看出在页面的kaikai用户被成功添加了
我们在来分析一下源代码
login.php登录界面的源代码
$html="";
if(isset($_POST['submit'])){
if($_POST['username']!=null && $_POST['password']!=null){
$username=escape($link, $_POST['username']);
$password=escape($link, $_POST['password']);//转义,防注入
$query="select * from users where username='$username' and password=md5('$password')";
$result=execute($link, $query);
if(mysqli_num_rows($result)==1){
$data=mysqli_fetch_assoc($result);
if($data['level']==1){//如果级别是1,进入admin.php
$_SESSION['op2']['username']=$username;
$_SESSION['op2']['password']=sha1(md5($password));
$_SESSION['op2']['level']=1;
header("location:op2_admin.php");
}
if($data['level']==2){//如果级别是2,进入user.php
$_SESSION['op2']['username']=$username;
$_SESSION['op2']['password']=sha1(md5($password));
$_SESSION['op2']['level']=2;
header("location:op2_user.php");
}
从源码中可以看出他对用户登录的界面使用了lever的等级进行判断,如果等级=1的话进入admin.php的界面,如果级别等于2的话进入user.php的界面
查看如果用admin用户登入的界面源代码
这里进入的界面做了限制,必须lever等于==1才可以进入到这个界面
从这里的代码可以看出admim界面有查看和添加用户的功能
在查看一些普通用户的源代码
从这里的代码可以看出没有添加用户的功能
查看admin.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']}')"; $result=execute($link, $query); if(mysqli_affected_rows($link)==1){//判断是否插入 header("location:op2_admin.php"); }else { $html.="
修改失败,请检查下数据库是不是还是活着的
"; } } } if(isset($_GET['logout']) && $_GET['logout'] == 1){ session_unset(); session_destroy(); setcookie(session_name(),'',time()-3600,'/'); header("location:op2_login.php"); }
从代码中可以看出他只验证了账号是否登录的状态,并没有对级别进行验证。 所以我们前面在操作的时候更换了cookie的原因就在这里,cookie是表示用户身份的唯一标识符,在前面我们抓取到admin添加数据包的时候,把他进行拦截丢弃了,说明创建的用户不成功,cookie也不存在,所以我们要利用已经有的用户的cookie进行替换。
墨者靶场 身份认证失效漏洞-水平越权
首先给了一个用户账号和密码,是已经存在的,我们进行test的账号 登录
开启 bp重新刷新一下界面,看看有没有可以获取的信息
刷新后发现有两个数据包
第一个
第二个
从第二个数据包可以看出这里有一个关键的键名card_id ,id统称是用户的唯一身份标识符,那我们猜测这是个标识符,将参数进行修改看看会不会有什么新的发现
修改/json.php?card_id=20128880322 参数进行访问
访问后发现页面有发现
使用bp把刚刚的数据包设置为一个变量进行一个一个用户的访问获取数据
爆破出后根据页面回显的长度判断出存在用户
太多用户了,如果在现实情况下,我们不可以一个一个进行查看,所以我们要寻找有关
目标用户马春生的信息
回到登录界面
打开F12控制台
使用光标,将鼠标移动到马春生的头像中
从js页面元素中我们可以看到
这个值很像我们在数据包抓取到的care_id,猜测后面的数字就是对应的他的care_id
回到bp寻找对应尾数16对应的care_id编号
user:"m233241"
password:"71cc568f1ed55738788751222fb6d8d9"
把密码进行md5的解密
解密后:9732343
拿到key
测试越权漏洞工具:
https://qithub.com/ztosec/secscan-authcheck
secscan-authcheck(越权漏洞检测工具) 安装总结_Asiaforest的博客-CSDN博客_越权漏洞检测
http://pan.baidu.com/s/1pLjaQKF (privilegechecker)
小米范工具系列之八:小米范越权漏洞检测工具 - 走看看
推荐使用bp工具(安装插件Authz)
将需要进行测试的目标,设置成一个变量发送到Intruder模块
攻击完后将所以结果选中发送到Authz模块
设置一个存在的用户的cookie
run
页面如果有绿色的话就存在有越权漏洞