the_open_door
coffee
ESEN
← Back to index

Secret leakage via print jobs

When a document is printed, the printing system doesn't send the file "as is": it renders it to an intermediate format (usually PostScript or PDF) and stores it temporarily in a print queue (spool) while it waits its turn. In CUPS that directory is /var/spool/cups. If the document contained sensitive information (a password, a key, personal data), that information ends up written in cleartext inside the stored job.

Why it's reachable. The user managing the print queue (on many systems, lp) has access to those files. Even if the directory isn't listable (ls may return Permission denied), CUPS names each job predictably: a control file c<NNNNN> and a data file d<NNNNN>-<NNN> (a d, five digits, a hyphen, and three digits). The first job is d00001-001, the second d00002-001, etc. So even without listing, you can read a specific job by its name:

cd /var/spool/cups
ls                    # Permission denied: we can't list the directory...
cat d00001-001        # ...but we can read a job by its predictable name

What to look for inside. The file is PostScript/PDF: the text strings drawn on the page appear as literals (in PostScript, inside parentheses: (text) show). Just read it to the end or filter by strings to find passwords or other secrets that were printed:

strings d00001-001 | grep -iE 'pass|pwd|secret'

Once a password is recovered, the next step is often as simple as su into the user it belongs to (on EvilCups, root directly). It's a flavor of credential reuse: the secret isn't obtained with an exploit but by reading an artifact the system left behind.

How to detect it. The signature is the read of /var/spool/cups files (c*/d*) by a process or user that isn't cupsd/lp: auditd -w /var/spool/cups -p r records that access, and a strings/grep over those spool files is unnatural. At rest, a CUPS with PreserveJobFiles Yes accumulating completed jobs is the exposure to audit; the subsequent su with a password extracted from the spool closes the chain (an unusual login in /var/log/auth.log).

Defence. Don't print documents with cleartext secrets. Configure CUPS to purge completed jobs (PreserveJobFiles No, PreserveJobHistory) instead of keeping them indefinitely, and restrict access to the spool. In general, remember that queues, spools, temp files and caches retain data long after the user thinks it's gone: reviewing them is part of post-exploitation. On EvilCups this leak was the path to root after the RCE from the CUPS chain.

Machines where it's used