|
|
Message-ID: <20260129162602.46ymqnlk2ixipsjn@jwilk.net>
Date: Thu, 29 Jan 2026 17:26:02 +0100
From: Jakub Wilk <jwilk@...lk.net>
To: oss-security@...ts.openwall.com
Subject: Re: CVE-2025-56005 Undocumented RCE in PLY via
`picklefile` Parameter
It looks like the pickling feature was removed in
https://github.com/dabeaz/ply/commit/1fac9fed647909b9 (Feb 2020,
"Massive refactoring/cleanup"), but that didn't make it into a release.
But anyway...
* Alan Coopersmith <alan.coopersmith@...cle.com>, 2026-01-28 14:10:
>https://www.cve.org/CVERecord?id=CVE-2025-56005 has added to the
>references a link to https://github.com/tom025/ply_exploit_rejection
>which argues that this CVE should be rejected because:
[...]
>>Run
>>
>> uv run main.py
>>
>>This will run the proof of concept. This results in the program
>>exiting early with a `AttributeError: 'function' object has no
>>attribute 'input'`.
I don't know what uv is, but the PoC almost works for me:
$ python3 -m pip install ply
Collecting ply
Downloading ply-3.11-py2.py3-none-any.whl.metadata (844 bytes)
Downloading ply-3.11-py2.py3-none-any.whl (49 kB)
Installing collected packages: ply
Successfully installed ply-3.11
$ cat /tmp/pwned
cat: /tmp/pwned: No such file or directory
$ python3 main.py
WARNING: yacc table file version is out of date
WARNING: no p_error() function is defined
Traceback (most recent call last):
File "/home/jwilk/ply_exploit_rejection/main.py", line 35, in <module>
parser.parse('example')
File ".../lib/python3.12/site-packages/ply/yacc.py", line 333, in parse
return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.12/site-packages/ply/yacc.py", line 1018, in parseopt_notrack
lexer = lex.lexer
^^^^^^^^^
AttributeError: module 'ply.lex' has no attribute 'lexer'. Did you mean: 'Lexer'?
The AttributeError is PLY's weird way of saying that you forgot to
create the lexer. Indeed, the PoC imports the lex() function from
ply.lex, and then never uses it. But despite that, the planted code was
executed:
$ cat /tmp/pwned
VULNERABLE
>>## Argument 2: The proof of concept does not demonstrate Arbitrary
>>Code Execution as claimed ##
>>
>>Referring to the proof of concept code this does not demonstrate
>>Arbitrary Code Execution as there is a single program running and no
>>untrusted data has been passed between processes. This is not a
>>demonstration of CWE-502 as claimed.
Meh. The author of the PoC took a shortcut by putting the code that
generates the malicious pickle and the code that runs the parser in the
same process, but it doesn't have to be that way. It'd be trivial to
move the two parts into separate programs.
I've attached a revised PoC:
$ printf example | python3 parser.py
example
$ python3 naughty-pickle.py cowsay pwned > parser.pkl
$ printf example | python3 parser.py
_______
< pwned >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
WARNING: yacc table file version is out of date
example
So there is no doubt that if you let PLY read pickles from untrusted
source, code execution is possible. But is it really a bug in PLY, or a
bug in the code that uses PLY in such a foolish way?
--
Jakub Wilk
View attachment "parser.py" of type "text/x-python" (341 bytes)
View attachment "naughty-pickle.py" of type "text/x-python" (188 bytes)
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.