官方示例脚本 examples/recursively_extract_attachments.py 包含一个路径遍历漏洞,允许在预期输出目录之外进行任意文件写入。从解析的邮件中提取的附件文件名未经任何清理直接用于构造输出文件路径,使得攻击者控制的文件名能够逃逸目标目录。
文件:examples/recursively_extract_attachments.py
行号:61–64
for a in m['attachment']:
out_filepath = out_path / a['filename'] # 无清理
print(f'\t正在写入附件: {out_filepath}')
with out_filepath.open('wb') as a_out:
a_out.write(base64.b64decode(a['raw']))
值 a['filename'] 可通过精心构造的邮件附件头由攻击者控制:
Content-Disposition: attachment; filename="../outside/pwned.txt"
写入前未执行任何路径规范化或边界验证。
.eml 文件:Content-Disposition: attachment; filename="../outside/pwned.txt"
python recursively_extract_attachments.py -p ./emails -o ./safe
./safe/pwned.txt./outside/pwned.txt ← 写入预期目录之外已在 Kali Linux 上通过 pip 在虚拟环境中安装 eml-parser 进行验证。
此漏洞仅限于示例脚本,不影响核心 eml-parser 库。然而,由于该脚本属于官方仓库的一部分,且很可能被改编用于生产环境,攻击者提供精心构造的邮件即可在执行上下文中实现任意文件写入。
潜在攻击场景包括:
filename="../../etc/cron.d/backdoor"filename="../../var/www/html/shell.php"filename="../../home/user/.ssh/authorized_keys"import os.path
for a in m['attachment']:
filename = os.path.basename(a['filename'])
out_filepath = out_path / filename
if not out_filepath.resolve().is_relative_to(out_path.resolve()):
print(f'[!] 跳过可疑文件名: {a["filename"]}')
continue
print(f'\t正在写入附件: {out_filepath}')
with out_filepath.open('wb') as a_out:
a_out.write(base64.b64decode(a['raw']))