Landw-hub/CVE-2025-50420
GitHub: Landw-hub/CVE-2025-50420
Poppler pdfseparate 工具中因循环引用检测失效导致的无限递归拒绝服务漏洞的概念验证代码。
Stars: 1 | Forks: 0
Poppler 25.07.0 之前的版本在其 pdfseparate 工具的 PDFDoc 处理逻辑中存在漏洞:精心构造的“/Annots”字典(指向自身或相互引用)会导致“PDFDoc::markAnnotations --> PDFDoc::markPageObjects --> PDFDoc::markObject --> PDFDoc::markDictionary”中的无限递归,因为循环检测使用的字典指针地址在每次调用 fetch() 时都会发生变化。远程攻击者可以通过处理恶意 PDF 文件导致拒绝服务(应用程序挂起或崩溃)。
这里我构造了一个恶意 PDF 文件(poppler-pdfseparate-poc),其中“/Annots”解析为自引用或相互引用的字典,导致 Poppler 的 markAnnotations --> markPageObjects --> markObject --> markDictionary 递归无法检测到循环,从而耗尽调用栈(无限递归)。利用此漏洞只需打开或处理 PDF 文件(例如,通过 pdfseparate)。
复现步骤如下:
```
afl_env(base) user@ubuntu:~/zgd/AFLProject/pdf_parsers/poppler-25.04.0/build/utils$ ./pdfseparate ./../../../../pdf_fuzz/p
oppler-master/pdfseparate/analyze_crashes/only_custom/all_crashes/poppler-pdfseparate-poc /dev/null
Segmentation fault (core dumped)
afl_env(base) user@ubuntu:~/zgd/AFLProject/pdf_parsers/poppler-25.04.0/build/utils$ gdb ./pdfseparate core.2332378
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./pdfseparate...
[New LWP 2332378]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
--Type for more, q to quit, c to continue without paging--
Core was generated by `./pdfseparate ./../../../../pdf_fuzz/poppler-master/pdfseparate/analyze_crashes'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007a27410a3dee in _int_malloc (av=av@entry=0x7a274121ac80 , bytes=bytes@entry=40)
at ./malloc/malloc.c:3903
3903 ./malloc/malloc.c: No such file or directory.
(gdb) bt
#0 0x00007a27410a3dee in _int_malloc (av=av@entry=0x7a274121ac80 , bytes=bytes@entry=40)
at ./malloc/malloc.c:3903
#1 0x00007a27410a5262 in __GI___libc_malloc (bytes=40) at ./malloc/malloc.c:3321
#2 0x00007a27414ae98c in operator new(unsigned long) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007a274192a080 in __gnu_cxx::new_allocator >::allocate (this=0x5c29c1b2a498, __n=1)
at /usr/include/c++/11/ext/new_allocator.h:127
#4 0x00007a2741929c8f in std::allocator >::allocate (__n=1, this=0x5c29c1b2a498)
at /usr/include/c++/11/bits/allocator.h:185
#5 std::allocator_traits > >::allocate (__a=..., __n=1)
at /usr/include/c++/11/bits/alloc_traits.h:464
#6 0x00007a274192974f in std::_Rb_tree, std::less, std::allocator >::_M_get_node
(this=0x5c29c1b2a498) at /usr/include/c++/11/bits/stl_tree.h:561
#7 0x00007a2741973466 in std::_Rb_tree, std::less, std::allocator >::_M_create_node (this=0x5c29c1b2a498) at /usr/include/c++/11/bits/stl_tree.h:611
#8 0x00007a2741970c97 in std::_Rb_tree, std::less, std::allocator >::_Alloc_node::operator() (this=0x7ffeba55f200, __arg=@0x7ffeba55f2a0: 4) at /usr/include/c++/11/bits/stl_tree.h:529
#9 0x00007a274196ba22 in std::_Rb_tree, std::less, std::allocator >::_M_insert_, std::less, std::allocator >::_Alloc_node> (
this=0x5c29c1b2a498, __x=0x0, __p=0x5c29c1b2a4a0, __v=@0x7ffeba55f2a0: 4, __node_gen=...)
at /usr/include/c++/11/bits/stl_tree.h:1784
#10 0x00007a2741963f5e in std::_Rb_tree, std::less, std::allocator >::_M_insert_unique (this=0x5c29c1b2a498, __v=@0x7ffeba55f2a0: 4) at /usr/include/c++/11/bits/stl_tree.h:2129
#11 0x00007a274195c4f6 in std::set, std::allocator >::insert (this=0x5c29c1b2a498,
--Type for more, q to quit, c to continue without paging--
__x=@0x7ffeba55f2a0: 4) at /usr/include/c++/11/bits/stl_set.h:512
#12 0x00007a2741957c6d in RefRecursionChecker::insert (this=0x5c29c1b2a498, ref=...)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/Object.h:133
#13 0x00007a2741b0e09c in XRef::fetch (this=0x5c29c1b2a370, num=4, gen=0, recursion=0, endPos=0x0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/XRef.cc:1202
#14 0x00007a2741b0dfb4 in XRef::fetch (this=0x5c29c1b2a370, ref=..., recursion=0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/XRef.cc:1190
#15 0x00007a2741a94e1d in Object::fetch (this=0x5c29c208a1c0, xref=0x5c29c1b2a370, recursion=0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/Object.cc:110
#16 0x00007a27419785d3 in Array::get (this=0x5c29c208a160, i=0, recursion=0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/Array.cc:92
#17 0x00007a2741ab0514 in PDFDoc::markAnnotations (this=0x5c29c1b2a0a0, annotsObj=0x7ffeba55f6b0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldPageNum=3, newPageNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1856
#18 0x00007a2741aaf6b3 in PDFDoc::markDictionary (this=0x5c29c1b2a0a0, dict=0x5c29c208a100, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1716
#19 0x00007a2741aaf8d8 in PDFDoc::markObject (this=0x5c29c1b2a0a0, obj=0x7ffeba55f800, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1744
#20 0x00007a2741ab03af in PDFDoc::markPageObjects (this=0x5c29c1b2a0a0, pageDict=0x5c29c208a0a0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1840
--Type for more, q to quit, c to continue without paging--
#21 0x00007a2741ab0827 in PDFDoc::markAnnotations (this=0x5c29c1b2a0a0, annotsObj=0x7ffeba55f9a0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldPageNum=3, newPageNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1889
#22 0x00007a2741aaf6b3 in PDFDoc::markDictionary (this=0x5c29c1b2a0a0, dict=0x5c29c2089f10, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1716
#23 0x00007a2741aaf8d8 in PDFDoc::markObject (this=0x5c29c1b2a0a0, obj=0x7ffeba55faf0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1744
#24 0x00007a2741ab03af in PDFDoc::markPageObjects (this=0x5c29c1b2a0a0, pageDict=0x5c29c2089eb0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1840
#25 0x00007a2741ab0827 in PDFDoc::markAnnotations (this=0x5c29c1b2a0a0, annotsObj=0x7ffeba55fc90, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldPageNum=3, newPageNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1889
#26 0x00007a2741aaf6b3 in PDFDoc::markDictionary (this=0x5c29c1b2a0a0, dict=0x5c29c2089d20, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1716
#27 0x00007a2741aaf8d8 in PDFDoc::markObject (this=0x5c29c1b2a0a0, obj=0x7ffeba55fde0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1744
#28 0x00007a2741ab03af in PDFDoc::markPageObjects (this=0x5c29c1b2a0a0, pageDict=0x5c29c2089cc0, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
--Type for more, q to quit, c to continue without paging--
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1840
#29 0x00007a2741ab0827 in PDFDoc::markAnnotations (this=0x5c29c1b2a0a0, annotsObj=0x7ffeba55ff80, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldPageNum=3, newPageNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1889
#30 0x00007a2741aaf6b3 in PDFDoc::markDictionary (this=0x5c29c1b2a0a0, dict=0x5c29c2089b30, xRef=0x5c29c1b2b080,
countRef=0x5c29c1b2b240, numOffset=0, oldRefNum=3, newRefNum=259, alreadyMarkedDicts=0x5c29c1b2c9f0)
at /home/user/zgd/AFLProject/pdf_parsers/poppler-25.04.0/poppler/PDFDoc.cc:1716
```
供应商(freedesktop,Poppler 的维护者)已确认该问题并修复了该漏洞。修复程序已提交到其官方代码库。
以下是供应商提供的补丁/提交的公开链接:
https://gitlab.freedesktop.org/poppler/poppler/-/issues/1613
https://gitlab.freedesktop.org/poppler/poppler/-/merge_requests/1849
https://gitlab.freedesktop.org/poppler/poppler/-/commit/08d7894e4dd0e313c179e30f06ad8f546619b1b3 这证实了该漏洞已被确认并已修复。
https://gitlab.freedesktop.org/poppler/poppler/-/merge_requests/1849
https://gitlab.freedesktop.org/poppler/poppler/-/commit/08d7894e4dd0e313c179e30f06ad8f546619b1b3 这证实了该漏洞已被确认并已修复。
标签:AFL, C++, DoS, pdfseparate, PDF解析, POC验证, Poppler, SEGFAULT, 内存破坏, 崩溃复现, 库安全, 循环引用, 恶意文件, 拒绝服务攻击, 数据擦除, 无限递归, 栈溢出, 消息认证码, 配置错误