Friday, November 30, 2012

Mac OSX Printer forensics


I have processed a few incidents in the past where I needed to determine what files a particular Mac OSX user may have printed, and what printers processed the requests.

This blog post outlines portions of the OSX printing system on Snow Leopard (10.6) Lion, (10.7) and Mountain Lion (10.8), and demonstrates a tool that is helpful when investigating printing history on an OSX system.

Mac OSX versions 10.2 and above use the CUPS printing system to manage print jobs, spoolers, and queues.

The printers available to the system are defined in the /etc/cups/printers.conf and /Library/Preferences/org.cups.printers.plist file(s).

When a user prints to a network printer, the print job contents are stored in the /var/spool/cups directory as they are printed. The two types of files stored in this directory are print control files and data files.

The control files are named with a “c” followed by 5 digits that increment for each print job (c00001, c00002..). The control files are IPP files that contain metadata about each print job.

The data files are named with a “d” followed by 5 digits that increment for each print job (d00001, d00002..) The data files are the actual content of the print job that was submitted.

The data files are typically deleted after printing, but the control files tend
to stay.

The following cups log files contain a few details about print jobs
/private/var/log/cups/access_log
/private/var/log/cups/error_log
/private/var/log/cups/page_log

The log files and control files are valuable sources of information for piecing together what a user printed. The following example shows how an investigator can determine documents that users have printed.

In this example a OSX disk image is mounted read-only on the /mnt mount point of a Linux analysis system via a hardware write blocker.

The cups_control program found on the JAFAT website parses the CUPS control files and outputs their contents in a readable format. The program is a modification of the original CUPS v1.1.21 testipp.c source code.

To compile cups_control on Linux: Download the source code, unzip it, and run make
# unzip cups_control-1.0.zip
# cd cups_control-1.0
# make

To run the program on a printer control file named c00613
# ./cups_control /mnt/private/var/spool/cups/c00613

Example output from the above command is included below. Note the control file contains the name of the document, the name of the printer, the user who printed, and the date/time the document was printed.

/mnt/private/var/spool/cups/c00613:

  operation-attributes-tag:

    attributes-charset : "utf-8"
    attributes-natural-language : "en-us"

  job-attributes-tag:

    printer-uri : "ipp://localhost:631/printers/home_canon"
    job-originating-user-name : "jake"
    job-name : "sample_doc.pdf"
    document-format : "application/pdf"
    AP_ColorMatchingMode : "AP_ApplicationColorMatching"
    AP_D_InputSlot : ""
    collate : true
    com.apple.print.DocumentTicket.PMSpoolFormat : "application/pdf"
    com.apple.print.JobInfo.PMApplicationName : "Preview"
    com.apple.print.JobInfo.PMJobName : "sample_doc.pdf"
    com.apple.print.JobInfo.PMJobOwner : "Jake"
    com.apple.print.PageToPaperMappingMediaName : "Letter"
    com.apple.print.PageToPaperMappingType..n. : "1"
    com.apple.print.PrinterInfo.PMColorDeviceID..n. : "42288"
    com.apple.print.PrintSettings.PMColorMatchingMode..n. : "0"
    com.apple.print.PrintSettings.PMColorSpaceModel..n. : "3"
    com.apple.print.PrintSettings.PMColorSyncProfileID..n. : "1294"
    com.apple.print.PrintSettings.PMCopies..n. : "1"
    com.apple.print.PrintSettings.PMCopyCollate..b. : true
    com.apple.print.PrintSettings.PMDestinationType..n. : "1"
    com.apple.print.PrintSettings.PMFirstPage..n. : "1"
    com.apple.print.PrintSettings.PMLastPage..n. : "2147483647"
    com.apple.print.PrintSettings.PMPageRange..a.0..n. : "1"
    com.apple.print.PrintSettings.PMPageRange..a.1..n. : "2147483647"
    copies : 1
    DestinationPrinterID : "home_canon"
    media : "Letter"
    ModelName : "Canon MG6220"
    PaperInfoIsSuggested..b. : true
    PDFIsProtected..b. : false
    pserrorhandler-requested : "standard"
    XRJobSheetMediaSource : "Tray1"
    XROrientation : "Portrait"
    XRSeparatorSheetMediaSource : "Tray1"
    XRSeparatorSheetType : "NoSeparators"
    job-priority : 50
    job-uuid : "urn:uuid:12e1040c-0314-343c-7987-612616c5616d"
    job-originating-host-name : "localhost"
    time-at-creation : (1352297058) Wed Nov  7 14:04:18 2012
    time-at-processing : (1352297058) Wed Nov  7 14:04:18 2012
    time-at-completed : (1352297065) Wed Nov  7 14:04:25 2012
    job-id : 613
    job-state : 9
    job-media-sheets-completed : 0
    job-printer-uri : "ipp://192.168.2.1/printers/home_canon"
    job-k-octets : 50
    job-sheets : "none" "none"
    job-hold-until : "no-hold"
    job-impressions : 2
    com.apple.print.PrintSettings.PMTotalSidesImaged..n. : 2
    com.apple.print.PrintSettings.PMTotalBeginPages..n. : 2
    job-printer-state-message : ""
    job-printer-state-reasons : "none"


In conclusion, the files that define the printers available to the system, the log files and the control files from print jobs allow an investigator to piece together
what files a user printed and what printer processed the print job.

3 comments: