// HackTricks · Network Services

Internet Printing Protocol

Internet Printing Protocol

The Internet Printing Protocol (IPP) is the standard application protocol for network printing. The current IPP/1.1 specifications are RFC 8010 (encoding/transport) and RFC 8011 (model/semantics), which obsolete RFCs 2910 and 2911. IPP is carried over HTTP and supports print jobs, printer capability queries, and queue management. IPP-based profiles such as IPP Everywhere also support driverless printing, while PWG extensions reuse the model for additive-manufacturing/3D printers and bind the Cloud Imaging Model so printers can obtain jobs from shared network or cloud services.[7][8][9][10][11]

IPP normally uses TCP/631. UDP/631 is associated with legacy CUPS browsing/cups-browsed discovery rather than the IPP request transport itself. Exposing either surface can create risk on printers and Linux/Unix hosts running CUPS.[3][7]


Quick PoC – crafting raw IPP with Python

import struct
import requests

def attribute(tag, name, value):
    name = name.encode()
    value = value.encode()
    return bytes([tag]) + struct.pack(">H", len(name)) + name + struct.pack(">H", len(value)) + value

printer_uri = "ipp://printer:631/ipp/print"
ipp = struct.pack(">BBHI", 2, 0, 0x000B, 1)  # version 2.0, operation, request-id
ipp += b"\x01"  # operation-attributes-tag
ipp += attribute(0x47, "attributes-charset", "utf-8")
ipp += attribute(0x48, "attributes-natural-language", "en")
ipp += attribute(0x45, "printer-uri", printer_uri)
ipp += b"\x03"  # end-of-attributes

r = requests.post("http://printer:631/ipp/print", headers={"Content-Type": "application/ipp"}, data=ipp)
print(r.status_code, r.content[:40])

Enumeration & Recon

1. Nmap NSE

# run all CUPS/IPP scripts
nmap -sV -p631 --script=cups* <target>
# or only basic info
nmap -p631 --script=cups-info,cups-queue-info <target>

The cups-info script extracts model, state and queue statistics while cups-queue-info enumerates pending jobs.

2. IPP utilities from CUPS

  • ippfind – multicast/UDP discovery (works against cups-browsed):
    ippfind --timeout 3 --txt -v "@local and port=631"  # list printers
  • ipptool – arbitrary requests defined in a .test file:
    ipptool -tv ipp://<IP>/ipp/print get-printer-attributes.test
    The bundled get-printer-attributes.test file queries firmware version, supported document formats, etc.

3. Shodan / Censys dorks

shodan search 'product:"CUPS (IPP)" port:631'

More than 70 000 hosts were publicly exposing CUPS in April 2025.[1]

4. Emulating a rogue IPP printer in the lab

For client-side testing you do not need real hardware: ippeveprinter exposes a minimal IPP Everywhere server, can advertise itself over DNS-SD, optionally require HTTP Basic auth with -A, and can either write rendered jobs to a directory with -D or execute a helper for every printed document with -c.[4]

mkdir -p /tmp/ipp-spool /tmp/ipp-out

# Save rendered jobs into /tmp/ipp-out and listen on TCP/8631
ippeveprinter -v -p 8631 -d /tmp/ipp-spool -D /tmp/ipp-out \
  -f application/pdf,image/jpeg,image/pwg-raster "LabPrinter"

# Auth-enabled variant for testing client credential prompts
ippeveprinter -v -A -p 8631 "AuthLabPrinter"

Recent Vulnerabilities (2023-2025)

YearCVE ID(s)Affected componentImpact
2024CVE-2023-50739Lexmark firmware (IPP parser)Heap-overflow → RCE over Wi-Fi/LAN[5]
2024CVE-2024-47076, 47175, 47176, 47177cups-browsed, libcupsfilters, libppd, cups-filtersUnauthenticated rogue-printer installation leading to command execution when a victim prints[3]
2024CVE-2024-35235cupsd before the vendor fixSymlink-assisted permission change that can support local privilege escalation[2]
2023CVE-2023-0856 (Canon) + Pwn2OwnStack-overflow in sides attribute → remote code execution[6]

cups-browsed RCE chain (September 2024)

The 2024 cups-browsed bug chain is the most practical modern IPP attack path against UNIX endpoints.[3]

  1. cups-browsed listens on UDP/631 for printer advertisements.
  2. An attacker sends a single spoofed packet pointing to a malicious IPP URL (CVE-2024-47176).
  3. libcupsfilters automatically fetches the remote PPD without validation (CVE-2024-47076 & 47175).
  4. A crafted PPD abuses the foomatic-rip filter to execute arbitrary shell commands whenever anything is printed (CVE-2024-47177).

Public PoCs exist, and the attacker can either auto-install a new rogue printer or silently replace an existing printer URI so the payload triggers on the next print job.[3]

On LANs, the same path can be reached by spoofing Zeroconf/mDNS/DNS-SD advertisements instead of attacking a public UDP/631 listener directly, so it is worth pairing this with mDNS/DNS-SD abuse during local network operations.[3]

Execution normally happens when a user prints to the malicious queue, and the resulting code runs in the lp context on default Linux installs.[3]

Temporary mitigations

sudo systemctl stop cups-browsed
sudo systemctl disable cups-browsed
sudo ufw deny 631/udp  # or equivalent firewall rule

Update the whole printing stack together — cups-browsed, libcupsfilters/cups-filters, libppd, and CUPS — instead of treating this as a single-package issue.[1][3]

Install the coordinated fixed packages supplied by the target distribution. Do not rely on a single upstream version number because affected components and backported fixes vary by distribution.[1][3]

Placing a symbolic link in cupsd.conf’s Listen directive can make cupsd (often running as root) change permissions on an attacker-chosen path to world-writable, which is a solid local privilege-escalation primitive when you can influence the configuration or win the bind-time race.[2]


Offensive Techniques

  • Rogue printer replacement / auto-install – abuse cups-browsed discovery over UDP/631 or spoofed DNS-SD to register a malicious printer or replace a trusted printer URI, then wait for the next print job to reach attacker-controlled IPP metadata.[3]
  • Unauthenticated raw print job – test whether the printer accepts POST /ipp/print without authorization. Some PostScript-capable devices expose unsafe interpreter extensions, but system(...) command execution is device/firmware-specific and is not guaranteed by PostScript or IPP.
  • Job hijacking – if authorization checks are missing, operations such as Cancel-Job and Send-Document may let an attacker disrupt or replace another user’s job. The operation names alone do not bypass access control.[8]
  • SNMP → IPP combination – a default SNMP community such as public may reveal the queue or printer URI needed for subsequent IPP testing.

Defensive Best Practices

  1. Patch CUPS and printer firmware promptly; subscribe to vendor PSIRT feeds.
  2. Disable cups-browsed and UDP/631 unless zeroconf printing is required.
  3. Restrict TCP/631 to trusted subnets/VPN and enforce TLS (ipps://).
  4. Require Kerberos/Negotiate or certificate auth instead of anonymous printing.
  5. Monitor logs: /var/log/cups/error_log with LogLevel debug2 can reveal unsolicited PPD downloads or suspicious filter invocations.
  6. In high-security networks, move printing to a hardened, isolated print server that proxies jobs to devices via USB only.

References