From 41ffe64d71f438f13fd049b597cd2368e9985c7f Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Fri, 27 Jun 2025 18:01:59 +0200 Subject: [PATCH] feat(parser): add Windows PE parser Built from #5159, this alternative has the following advantages: - it doesn't create a fake "line" that is passed to binary checker - python binary checker doesn't have to be updated - it allows the end-user to disable this new behavior through "-s pe" - any specific PE handling such as setting the product to lower case or converting "Python Software Foundation" to "python" is done in pe.py For now, pe parser runs only on pyd files but this could be updated. Credits shall be given to @alex-cheng-techman which created most of the original code Signed-off-by: Fabrice Fontaine --- .github/actions/spelling/allow.txt | 1 + README.md | 1 + cve_bin_tool/parsers/pe.py | 60 ++++++++++++++++++++++++++++++ doc/MANUAL.md | 7 +++- doc/PARSERS.rst | 2 + requirements.txt | 1 + 6 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 cve_bin_tool/parsers/pe.py diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 2a7bd6772a..ef80cc25c0 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -603,6 +603,7 @@ putty pybabel pycon pycqa +pyd pypa pypi pytest diff --git a/README.md b/README.md index 2465fb0778..f1b00a92da 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,7 @@ A number of checkers are available for finding vulnerable components in specific | Ruby | `Gemfile.lock` | | R | `renv.lock` | | Swift | `Package.resolved` | +| Windows PE | `.pyd` files | More information on [language-specific checkers](https://github.com/intel/cve-bin-tool/blob/main/doc/MANUAL.md#language-specific-checkers) can be found in the [CVE Binary Tool manual](https://cve-bin-tool.readthedocs.io/en/latest/MANUAL.html). diff --git a/cve_bin_tool/parsers/pe.py b/cve_bin_tool/parsers/pe.py new file mode 100644 index 0000000000..18e8769c07 --- /dev/null +++ b/cve_bin_tool/parsers/pe.py @@ -0,0 +1,60 @@ +# Copyright (C) 2025 Orange +# SPDX-License-Identifier: GPL-3.0-or-later +"""Python script containing all functionalities related to parsing of Windows PE files.""" + +import pefile + +from cve_bin_tool.parsers import Parser +from cve_bin_tool.util import ProductInfo, ScanInfo + + +class PeParser(Parser): + """ + Parser for Windows PE files + """ + + PARSER_MATCH_FILENAMES = [ + ".pyd", + ] + + def __init__(self, cve_db, logger): + """Initialize the pe package metadata parser.""" + super().__init__(cve_db, logger) + + def run_checker(self, filename): + """ + This generator runs only for Windows PE files. + There are no actual checkers. + """ + self.filename = filename + try: + with pefile.PE(filename) as pe: + for fileinfo in pe.FileInfo: + for entry in fileinfo: + if entry.Key == b"StringFileInfo": + for st in entry.StringTable: + entries = st.entries + vendor = entries.get(b"CompanyName", b"").decode( + errors="ignore" + ) + if vendor == "Python Software Foundation": + vendor = "python" + product = ( + entries.get(b"ProductName", b"") + .decode(errors="ignore") + .lower() + ) + version = entries.get(b"ProductVersion", b"").decode( + errors="ignore" + ) + self.logger.debug(product) + vendorlist: list[ScanInfo] = [ + ScanInfo( + ProductInfo(vendor, product, version), + self.filename, + ) + ] + yield from vendorlist + except pefile.PEFormatError: + self.logger.debug(f"Failed to parse PE file {filename}") + self.logger.debug(f"Done scanning file: {filename}") diff --git a/doc/MANUAL.md b/doc/MANUAL.md index 2eaffd1408..4cec3a3277 100644 --- a/doc/MANUAL.md +++ b/doc/MANUAL.md @@ -94,6 +94,7 @@ - [Dart](#dart) - [C/C++](#cc) - [OpenWrt opkg](#openwrt-opkg) + - [Windows PE](#windows-pe) - [Feedback \& Contributions](#feedback--contributions) - [Security Issues](#security-issues) @@ -573,7 +574,7 @@ The CVE binary tool is utilized to identify vulnerabilities within a software. W Once the database is populated, the CVE binary tool conducts searches for CVEs using two distinct methods: -- The first approach involves examining language component lists (e.g., requirement.txt, package.json) for different programming languages. Presently, the CVE binary tool provides support for 12 languages: Dart, Go, Java, JavaScript, OpenWrt Opkg, Python, Perl, PHP, R, Ruby, Rust, and Swift. If your desired language is not listed, you can refer to this guide on [how to add a parser](../cve_bin_tool/parsers/README.md) for it. +- The first approach involves examining language component lists (e.g., requirement.txt, package.json) for different programming languages. Presently, the CVE binary tool provides support for 12 languages: Dart, Go, Java, JavaScript, OpenWrt Opkg, Python, Perl, PHP, R, Ruby, Rust, Swift and Windows PE. If your desired language is not listed, you can refer to this guide on [how to add a parser](../cve_bin_tool/parsers/README.md) for it. - The second method employs checkers to gather information about software vulnerabilities. Checkers consist of predefined information about software entities. The CVE binary tool scans binaries for patterns matching the descriptions provided by the checkers, thereby extracting details like software version and vendor. At present, the CVE binary tool includes over 300 checkers. Crafting new checkers is a straightforward process and can serve as a beginner-friendly task. You can learn more about [adding checkers here](../cve_bin_tool/checkers/README.md). @@ -1605,6 +1606,10 @@ Here's an example of what a [`conan.lock`](https://github.com/intel/cve-bin-tool The scanner examines the `.control` file within an embedded system to identify components. The CPE-IDs and versions are used to search the database for vulnerabilities. Packages with no CPE-ID are ignored to avoid wrong results. +### Windows PE + +The scanner examines the Windows PE file to identify components. The product name (in lower case), company name and versions are used to search the database for vulnerabilities. + ## Feedback & Contributions Bugs and feature requests can be made via [GitHub issues](https://github.com/intel/cve-bin-tool/issues). diff --git a/doc/PARSERS.rst b/doc/PARSERS.rst index 9a51112316..a9e5b74090 100644 --- a/doc/PARSERS.rst +++ b/doc/PARSERS.rst @@ -17,6 +17,7 @@ The following parsers have been added to the project: - **JavaParser** - **JavascriptParser** - **OpkgParser** +- **PeParser** - **PerlParser** - **PhpParser** - **PythonParser** @@ -39,6 +40,7 @@ To utilize these parsers, ensure that your project includes the following import from cve_bin_tool.parsers.java import JavaParser from cve_bin_tool.parsers.javascript import JavascriptParser from cve_bin_tool.parsers.opkg import OpkgParser + from cve_bin_tool.parsers.perl import PeParser from cve_bin_tool.parsers.perl import PerlParser from cve_bin_tool.parsers.php import PhpParser from cve_bin_tool.parsers.python import PythonParser, PythonRequirementsParser diff --git a/requirements.txt b/requirements.txt index be45946730..4a3344de2d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,7 @@ lib4sbom==0.8.4 # Pinned due to bug. Was lib4sbom>=0.7.2 lib4vex>=0.2.0 packageurl-python packaging>=22.0 +pefile plotly python-gnupg pyyaml>=5.4