Full Report
The Common Unix Printing System (CUPS) is installed on most Linux distros by default. When setting up a new laptop, the author of this post found that port 631 was open on 0.0.0.0 that was associated with this. The cups-browsed subsystem is a system responsible for discovering new printers and adding them to the system. The article is about the journey into madness reading through this. The service can be connected to by anyone with no restrictions. There is a configuration file that allows this to be restricted but it's not down by default on any systems that they reviewed. Running this through AFL gave them 5 unique crashes. Two of them appeared to be pointers being derefenerenecd before the exit condition was verified. The second one was a denial of service from a lock being held onto for too long. They didn't even try to exploit these, as they thought lower hanging fruit might be available. They hacked together some Python code to communicate with the service and got back a connection over the Internet Printing Protocol (IPP) to their computer from the box on the Internet. Now, the Linux box thinks that our friend EvilSocket is a printer with many requests being sent via HTTP for information such as the model, vendor and other things. They found a Python library called ippserver to interact with the computer properly. Using this, they were able to add a fake printer to the computer without any user interaction. Now, we have a good way to interact with the Linux computer as a fake printer to further go deep. While reading the logs of the service, they saw references to a PPD or PostScript Printer Description file. This text file is provided by vendors to describe printer capabilities to CUPS and instructs an interface via various commands on how to use it properly via a DSL. Notability, the fake printer is writing this to the users system to describe how to interact with their printer. After reading the documentation for some time, they came across the cupsFilter2 directive. This will execute binaries located within a particular location on the system and the checks for which binaries are executed is pretty solid. Luckily, there are some of programs to work with, including foomatic-rip. This program accepts an arbitrary command to be executed from bash! This sounds crazy (and it is) but it's apparently a necessary evil. This issue has been known for a while but it's difficult to fix because of the way existing drivers from older printers use it. They found one doozy that was running a Perl command in it even. This issue was once patched in FoomaticRipCommandLine but was not added when this functionality was ported to CUPS. Sometimes, security can be in direct conflict with backwards compatibility and usability. This isn't a zero click RCE luckily but is still scary. First, an attacker would add their printer to the machine. Next, they return the malicious directive that gives us arbitrary command execution. Finally, the user must send a print job to the fake printer, which will pop a shell when executed. To get this to run, they needed to find a parsing bypass (which was easy with added a few spaces) to get this to be executed in the cupsFilter. An amazing bug that only took them a weekend to find. The remediation process seemed quite terrible for them and time consuming. Most of the considerations were is this a real issue that needs to be addressed at all?. When you have arguments like "I am just pointing out that the public Internet attack is limited to servers that are directly connected to the Internet" to try to limit the expected impact, it's hard, especially with 200-300K devices that were likely effected on Shodan alone. I feel bad for how this was handled, as it was pretty terrible. The people working on CUPS want to add features to make users lives better and security is just a thorn in the side of that goal. They're also volunteers in all likelihood. As a developer, we need to be open to fixing our mistakes and evaluating the impact for what it truly is. Great write up on both the technical and non-technical side!
Analysis Summary
# Vulnerability: Unauthenticated Remote Code Execution in CUPS Printing Stack
## CVE Details
- **CVE ID:** CVE-2024-47176 (cups-browsed), CVE-2024-47076 (libcupsfilters), CVE-2024-47175 (libppd), CVE-2024-47177 (cups-filters)
- **CVSS Score:** 9.0 (Critical) - *Note: Based on the researcher's findings of unauthenticated RCE.*
- **CWE:** CWE-20 (Improper Input Validation), CWE-78 (OS Command Injection)
## Affected Systems
- **Products:** Common Unix Printing System (CUPS) and related browsing/filtering subsystems.
- **Versions:** Most versions utilized by modern Linux distributions and Unix-like OSs (e.g., Ubuntu, Debian, Fedora, FreeBSD, Solaris).
- **Configurations:** Systems running the `cups-browsed` daemon with UDP port 631 exposed (often default on many distributions).
## Vulnerability Description
This is a chain of vulnerabilities that allows a remote, unauthenticated attacker to execute arbitrary commands when a user initiates a print job.
1. **Discovery & Trust (CVE-2024-47176):** `cups-browsed` binds to UDP port 631 on `0.0.0.0` by default. It trusts any packet from any source, allowing an attacker to point the victim to a malicious IPP (Internet Printing Protocol) server.
2. **Printer Addition:** The victim's system connects to the attacker's malicious printer. The attacker provides a "PostScript Printer Description" (PPD) file containing malicious metadata.
3. **Command Injection (CVE-2024-47177):** The malicious PPD file utilizes the `foomatic-rip` filter via the `cupsFilter2` directive. This filter historically allows execution of arbitrary shell commands through the `FoomaticRipCommandLine` parameter, a flaw that was reintroduced or bypassed during code refactoring in the CUPS stack.
## Exploitation
- **Status:** PoC available; widely documented by the researcher (EvilSocket).
- **Complexity:** Low to Medium (requires a print job to be triggered).
- **Attack Vector:** Network (UDP 631).
## Impact
- **Confidentiality:** High (Full shell access to the user/system).
- **Integrity:** High (Ability to modify system files and configurations).
- **Availability:** High (Ability to disable services or crash the system).
## Remediation
### Patches
- Users should update `cups-browsed`, `cups-filters`, `libcupsfilters`, and `libppd` via their distribution's package manager immediately. Modern distros have released security patches for these CVEs.
### Workarounds
- **Disable Service:** Stop and disable the `cups-browsed` service:
`sudo systemctl stop cups-browsed && sudo systemctl disable cups-browsed`
- **Network Filtering:** Block incoming traffic on UDP port 631 at the firewall (e.g., `iptables` or `nftables`).
- **Configuration:** Edit `/etc/cups/cups-browsed.conf` to restrict browsing or turn it off entirely.
## Detection
- **Indicators of Compromise:**
- Presence of unknown or "phantom" printers in the CUPS web interface (`localhost:631`).
- Unusual outbound IPP (TCP 631) traffic to unknown external IPs.
- Audit logs showing `foomatic-rip` executing unexpected shell commands (e.g., `/bin/sh`).
- **Detection Methods:** Vulnerability scanners like Shodan can identify if port 631 is exposed to the public internet.
## References
- **Vendor Advisories:** Check specific Linux distribution security trackers (Debian, Red Hat, Ubuntu).
- **Relevant Links:**
- hxxps://www.evilsocket[.]net/2024/09/26/Attacking-UNIX-systems-via-CUPS-Part-I/
- hxxps://github[.]com/OpenPrinting/cups-browsed/security/advisories/GHSA-76hr-fvfw-p39w