Table of Contents
- Module 1: The OpenPrinting CUPS Remote Code Execution Exploit Chain
- Background: What Is CUPS?
- Disclosure Overview
- The Four Vulnerabilities in the Exploit Chain
- Affected Packages and Versions
- Step-by-Step Exploitation Flow
- The User-Interaction Requirement and Real-World Likelihood
- Determining Whether a System Is Vulnerable
- Proof-of-Concept Availability
- Evidence of Scanning and Active Exploitation
- CVSS Scoring Breakdown
- Remediation and Mitigation
- Summary
Module 1: The OpenPrinting CUPS Remote Code Execution Exploit Chain
Background: What Is CUPS?
CUPS (Common Unix Printing System) is a collection of tools used to manage printers and print jobs in a standardized way across Unix and Linux systems. It allows a machine to act as a print server: accepting print jobs from clients, processing them, and dispatching them to a physical or virtual printer. Functionally, it plays a role similar to the print spooler service on Windows.
Because print-related packages from the OpenPrinting/CUPS ecosystem ship installed by default on many Linux distributions — Debian being a particularly well-known example — a vulnerability in these components has broad reach across the Linux server and desktop landscape, even though CUPS is not tied to any single distribution.
Disclosure Overview
On September 26th, a security researcher operating under the handle @evilsocket (Simone Margaritelli) published a blog post describing a set of vulnerabilities in the Common Unix Printing System. Under specific conditions, these vulnerabilities can be chained together to achieve arbitrary remote code execution, with the initial network exposure occurring over UDP port 631.
Key characteristics of the disclosure:
- The exploit chain can only be triggered if the victim system starts a print job — at the time of disclosure, that print job had to be initiated by a user (no known way to force it remotely).
- Chatter in security forums at the time suggested further vulnerabilities might be disclosed that could remove the need for user interaction.
- Research at the time of disclosure estimated several hundred thousand vulnerable, internet-facing machines with the affected UDP port exposed.
mindmap
root((CUPS Exploit Chain Disclosure))
Researcher
evilsocket / Simone Margaritelli
Published Sept 26
Scope
Several hundred thousand internet-facing machines
UDP port 631 exposed
Constraint
Requires victim to print a job
No remote-trigger known at disclosure time
Outlook
More disclosures rumored
Possible removal of user-interaction requirement
The Four Vulnerabilities in the Exploit Chain
The exploit chain is made up of four distinct vulnerabilities spread across four different components of the CUPS/OpenPrinting ecosystem. Each one plays a specific role in enabling the next stage of the attack.
| # | Component | Role of the Component | Nature of the Flaw |
|---|---|---|---|
| 1 | cups-browsed (helper daemon) | Discovers and browses network printers for CUPS | Causes the CUPS print service to bind to 0.0.0.0 instead of localhost, exposing it to remote hosts and letting a remote attacker register an attacker-controlled printer |
| 2 | libcupsfilters | Library providing filter and API functions for printer applications/drivers | Fails to properly validate/sanitize printer attributes supplied by an untrusted (remote) source |
| 3 | libppd | Library providing functions/APIs for handling PostScript Printer Description (PPD) files, which describe a printer’s capabilities | Allows an attacker to write malicious printer attributes into a temporary PPD file |
| 4 | cups-filters | Collection of filters and back-ends letting CUPS 2.x run on non-Mac systems | Contains the actual code-injection vulnerability, allowing arbitrary code execution when the malicious printer is used |
The vulnerabilities effectively cascade: the first flaw exposes the service to the network, the second and third let an attacker smuggle malicious data into a file CUPS trusts, and the fourth turns that trusted file into a code-execution primitive.
flowchart TD
A["cups-browsed flaw:\nservice binds to 0.0.0.0"] --> B["Remote attacker can register\na malicious printer"]
B --> C["libcupsfilters flaw:\nmalicious printer attributes accepted\nwithout sanitization"]
C --> D["libppd flaw:\nmalicious attributes written\ninto a temporary PPD file"]
D --> E["cups-filters flaw:\ncode injection when the\nmalicious printer is used"]
E --> F["Arbitrary remote code execution\non the victim host"]
Affected Packages and Versions
Because these are package-level vulnerabilities rather than distribution-specific ones, exposure depends on which package versions are installed rather than which Linux distribution is in use.
| Package | Vulnerable Versions |
|---|---|
cups-browsed | Up to and including 2.01 |
cups-filters | Up to and including 2.01 |
libcupsfilters | Up to and including 2.1b1 |
libppd | Up to and including 2.1b1 |
Step-by-Step Exploitation Flow
Because this is an exploit chain rather than a single-shot vulnerability, an attacker needs to walk through several steps to reach code execution:
- Network exposure. The
cups-browsedflaw causes the CUPS print service to listen on all network interfaces instead of only locally, making it reachable over UDP port 631. - Malicious printer announcement. The attacker sends a UDP packet to port 631 containing a URL pointing to an Internet Printing Protocol (IPP) server under the attacker’s control.
- Outbound information gathering. The victim’s CUPS installation makes an outbound HTTP POST request to the attacker-controlled IPP server to gather information about this newly announced printer.
- Malicious PPD generation. CUPS uses the (attacker-supplied) information to build a PPD file describing the printer’s capabilities and supported features. Because CUPS reads this PPD configuration data directly from the attacker-controlled IPP server, the attacker can inject arbitrary values into it.
- Command injection via FoomaticRIPCommandLine. The
FoomaticRIPCommandLinedirective is a filter that can be invoked from the command line (or by an application) to execute a print job, using values sourced from the PPD file. Since the PPD content is attacker-controlled, the attacker can specify arbitrary commands through this directive. - Trigger. The final step requires the victim machine to attempt to print something using the malicious printer. This step cannot be triggered remotely by the attacker — but once a real print job is sent to the malicious printer, the PPD file is read and the injected arbitrary command executes.
sequenceDiagram
participant Attacker
participant CUPS as Victim CUPS / cups-browsed (UDP 631)
participant IPP as Attacker-Controlled IPP Server
participant User as Victim User/App
Attacker->>CUPS: UDP packet to port 631 with URL to malicious IPP server
CUPS->>IPP: Outbound HTTP POST to gather "printer" info
IPP-->>CUPS: Malicious printer attributes / capabilities
CUPS->>CUPS: Generate PPD file from attacker-controlled data\n(contains malicious FoomaticRIPCommandLine value)
Note over CUPS: Malicious printer now appears as available
User->>CUPS: Sends a print job to the malicious printer
CUPS->>CUPS: Reads PPD file, executes FoomaticRIPCommandLine
CUPS-->>Attacker: Arbitrary command executes on victim host
The User-Interaction Requirement and Real-World Likelihood
A natural question is: how likely is a victim to print to a malicious printer they didn’t set up? A few points temper that skepticism:
- Linux is far less common than Windows as a day-to-day desktop OS, but it underpins a large amount of infrastructure — many web applications run on Linux systems, and those applications may themselves need to submit print jobs.
- A user (or an application acting on a user’s behalf) might select a printer that simply appears as “available” in a print dialog, with no visible indication that it is attacker-controlled.
- Once that printer is chosen and a print job is sent to it, the exploit chain runs automatically through to code execution.
So while the attack cannot be triggered purely remotely, the requirement is lower-friction than it might initially appear, especially on systems where print jobs are issued programmatically by backend applications rather than by a human consciously picking a printer.
Determining Whether a System Is Vulnerable
Several checks can be performed (commands shown here are for Debian-based systems; the specific tooling will vary by distribution):
- Confirm a vulnerable version of
cups-browsedis installed (versions 2.01 or lower are vulnerable):
dpkg -l | grep cups-browsed
- Confirm the
cups-browsedservice is actually running. If the service shows asinactive (dead), it is not running and this vector is not active:
systemctl status cups-browsed
- Confirm the service is listening on UDP port 631 on all interfaces — this is indicative of the CVE affecting
cups-browsed(binding to0.0.0.0):
netstat -anu | grep 631
Look specifically for a UDP listener bound to 0.0.0.0:631 rather than 127.0.0.1:631.
- Check the
cups-browsedconfiguration for theBrowseRemoteProtocolsdirective. If it contains the valuecups, and all of the previous checks are positive, the system is vulnerable to this exploit chain:
grep -i BrowseRemoteProtocols /etc/cups/cups-browsed.conf
flowchart TD
A[Start assessment] --> B{"cups-browsed version\n<= 2.01 installed?"}
B -- No --> Z[Not vulnerable via this package]
B -- Yes --> C{"cups-browsed service\nrunning / enabled?"}
C -- "inactive (dead)" --> Z
C -- Running --> D{"Listening on UDP 631\non 0.0.0.0 (all interfaces)?"}
D -- No / localhost only --> Z
D -- Yes --> E{"BrowseRemoteProtocols\ncontains 'cups'?"}
E -- No --> Z
E -- Yes --> F[System is vulnerable\nto the exploit chain]
Proof-of-Concept Availability
At the time of recording, several proof-of-concept exploits existed publicly:
- A couple of the early published PoCs contained syntactical errors that were relatively easy to fix but left them non-functional out of the box.
- A separate tool, CUPSHax, was confirmed to work. Rather than directly querying the
cups-browsedservice over UDP port 631, it uses DNS-SD printer discovery via broadcast messages. It is reliable, but its downside is that the attacker and the victim must be on the same local network segment for the broadcast-based discovery to work.
Evidence of Scanning and Active Exploitation
At the time of recording, tens of thousands — potentially hundreds of thousands — of internet-facing systems had UDP port 631 exposed, making them potentially vulnerable. However, the requirement that a victim must trigger a print job to the malicious printer significantly limits real-world exploitability.
Security researchers identified a number of IP addresses actively scanning the internet for vulnerable systems. Some of that scanning activity is presumably attributable to security researchers assessing the scale of the problem, but in some observed cases the scanning traffic also included an actual exploitation payload rather than pure reconnaissance.
flowchart LR
subgraph Exposure
A["~100k-hundreds of thousands\nof hosts with UDP 631 exposed"]
end
subgraph Activity
B[Internet-wide scanning observed]
C[Some scans include\nexploitation payloads]
D[Some scans likely\nresearcher reconnaissance]
end
subgraph Limiting Factor
E["Attack still requires victim\nto print to the malicious printer"]
end
A --> B --> C
B --> D
C --> E
D --> E
CVSS Scoring Breakdown
At the time of recording, NIST NVD had not yet completed its own assessment of these CVEs, so the scores discussed were those published by GitHub, an approved CVE Numbering Authority (CNA).
| CVE | Component | Attack Complexity | User Interaction | Confidentiality/Integrity/Availability Impact | CVSS Score |
|---|---|---|---|---|---|
| CVE-2024-47076 (libcupsfilters) | libcupsfilters | Low | None | Integrity impact only (untrusted data flowing into PPD file) | 8.6 |
| CVE-2024-47175 (libppd) | libppd | Low | None | Integrity impact only (untrusted data flowing into PPD file) | 8.6 |
| CVE-2024-47176 (cups-browsed) | cups-browsed | High | Required (victim must send a print job) | Confidentiality and availability impacted in addition to integrity | 8.3 |
| CVE-2024-47177 (cups-filters, command injection) | cups-filters | High | Not required | Confidentiality, integrity, and availability all rated high | 9.0 |
Note: the narration itself only explicitly names CVE-2024-47176 for the
cups-browsedbinding flaw; the other three CVE identifiers above are included as commonly referenced public identifiers for this same disclosure and are provided for reference alongside the CVSS details that were discussed directly.
The first two vulnerabilities (libcupsfilters and libppd) share an identical CVSS vector: low attack complexity, exploitable across the network, with no privileges and no user interaction required — because both stem from a lack of sanitization of untrusted data flowing into the PPD file, both are rated 8.6 with an integrity-only impact.
CVE-2024-47176 (the cups-browsed binding flaw) scores slightly lower on paper due to higher attack complexity and a requirement for user interaction (sending a print job) — but because it also affects confidentiality and availability rather than integrity alone, its score is pulled back up to 8.3.
The final vulnerability — the command-injection flaw in cups-filters — has high attack complexity but does not require user interaction, and impacts confidentiality, integrity, and availability at a high level, giving it the highest individual score of 9.0.
There are various informal guidelines for combining multiple CVSS scores across an exploit chain, but none of them are part of the official CVSS standard — they exist only to help analysts reason about aggregate risk in their own environment, not to produce an authoritative combined score.
xychart-beta
title "CVSS Scores Across the Exploit Chain"
x-axis ["libcupsfilters", "libppd", "cups-browsed", "cups-filters (RCE)"]
y-axis "CVSS Score" 0 --> 10
bar [8.6, 8.6, 8.3, 9.0]
Remediation and Mitigation
- Patch. Vendors have begun rolling out fixes for the affected packages. Because the disclosure happened earlier than the researcher had originally planned, some vendors were still catching up at the time of recording. Canonical, for example, published status updates for Ubuntu indicating which packages had been fixed in which releases — other vendors are expected to publish similar tracking pages.
- Mitigate if a patch isn’t yet available. If an update is not yet available for a given distribution, or it cannot be applied immediately, the recommended mitigation is to stop the
cups-browsedservice and disable it so it does not restart on reboot:
systemctl stop cups-browsed
systemctl disable cups-browsed
- General hardening. As a broader security best practice, disable or remove any protocol or service that isn’t actively needed — an exposed, unused service (such as UDP 631 open to the internet) is unnecessary attack surface.
flowchart TD
A[Is a vendor patch available?] -- Yes --> B[Apply the vendor update\nfor cups-browsed / cups-filters /\nlibcupsfilters / libppd]
A -- No --> C["systemctl stop cups-browsed\nsystemctl disable cups-browsed"]
B --> D[Verify service no longer\nbinds to 0.0.0.0:631]
C --> D
D --> E[Continue monitoring vendor\nadvisories for follow-up CVEs]
E --> F[Apply general hardening:\ndisable unused network services/protocols]
Summary
This exploit chain in the OpenPrinting CUPS ecosystem combines four separate vulnerabilities — a network-exposure flaw in cups-browsed, unsanitized-attribute flaws in libcupsfilters and libppd, and a command-injection flaw in cups-filters — into a path to arbitrary remote code execution triggered by a victim printing to an attacker-controlled printer announced over UDP port 631. Hundreds of thousands of internet-facing systems were estimated to have the relevant port exposed at the time of disclosure, and while exploitation is gated on user interaction (sending a print job), scanning activity — including scans carrying live exploitation payloads — was already being observed. CVSS scores across the four component CVEs ranged from 8.3 to 9.0, and while NVD had not finalized its own assessment at the time, GitHub’s CNA-issued scores made clear this was a high-severity issue deserving prompt attention.
Mitigation Checklist
- Identify all systems with
cups-browsed,cups-filters,libcupsfilters, orlibppdinstalled. - Check installed package versions against the vulnerable ranges (≤ 2.01 for
cups-browsed/cups-filters; ≤ 2.1b1 forlibcupsfilters/libppd). - Confirm whether
cups-browsedis running and, if so, whether it is bound to0.0.0.0on UDP port 631. - Check the
BrowseRemoteProtocolsdirective in thecups-browsedconfiguration for acupsvalue. - Apply vendor-provided patches as soon as they are available for your distribution.
- If a patch is not yet available, stop and disable the
cups-browsedservice to prevent it from restarting on reboot. - Restrict or firewall UDP port 631 from untrusted/internet-facing networks where CUPS network browsing is not required.
- As a general hardening practice, disable any printing/browsing protocols and services that are not actively in use.
- Continue monitoring vendor and researcher advisories, since additional related vulnerabilities were anticipated to be disclosed after this initial batch.
Search Terms
openprinting · cups · remote · execution · know · vulnerability · briefings · networking · systems · security · chain · exploit · exploitation · mitigation