Printjob Capture Service - Metasploit


This page contains detailed information about how to use the auxiliary/server/capture/printjob_capture metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Printjob Capture Service
Module: auxiliary/server/capture/printjob_capture
Source code: modules/auxiliary/server/capture/printjob_capture.rb
Disclosure date: -
Last modification time: 2020-05-12 22:15:21 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): 9100
List of CVEs: -

This module is designed to listen for PJL or PostScript print jobs. Once a print job is detected it is saved to loot. The captured printjob can then be forwarded on to another printer (required for LPR printjobs). Resulting PCL/PS files can be read with GhostScript/GhostPCL. Note, this module does not yet support IPP connections.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


msf > use auxiliary/server/capture/printjob_capture
msf auxiliary(printjob_capture) > show targets
    ... a list of targets ...
msf auxiliary(printjob_capture) > set TARGET target-id
msf auxiliary(printjob_capture) > show options
    ... show and set options ...
msf auxiliary(printjob_capture) > exploit

Knowledge Base


This module creates a mock print server which accepts print jobs.

Verification Steps


  1. Start msfconsole
  2. Do: use auxiliary/server/capture/printjob_capture
  3. Do: set MODE [mode]
  4. Do: run

Options


FORWARD

After the print job is captured, should it be forwarded to another printer. Default is false.

RPORT

If forward is set, this is the port of the remote printer to forward the print job to. Default is 9100.

RHOST

If forward is set, this is the IP of the remote printer to forward the print job to.

METADATA

If set to true the print job metadata will be printed to screen. Default is true.

MODE

Set the printer mode. RAW format, which typically runs on port 9100, is a raw TCP data stream that would send to a printer. LPR, Line Printer remote, which typically runs on port 515, is the newer more widely accepted standard. Default is RAW.

Scenarios


Capturing a RAW print job

Server:

msf5 > use auxiliary/server/capture/printjob_capture 
msf5 auxiliary(server/capture/printjob_capture) > run
[*] Auxiliary module running as background job 0.

[*] Starting Print Server on 0.0.0.0:9100 - RAW mode
[*] Started service listener on 0.0.0.0:9100 
[*] Server started.
msf5 auxiliary(server/capture/printjob_capture) > [*] Printjob Capture Service: Client connection from 127.0.0.1:44678
[*] Printjob Capture Service: Client 127.0.0.1:44678 closed connection after 249 bytes of data
[-] Unable to detect printjob type, dumping complete output
[+] Incoming printjob - Unnamed saved to loot
[+] Loot filename: /root/.msf4/loot/20181117205902_default_127.0.0.1_prn_snarf.unknow_003464.bin

msf5 auxiliary(server/capture/printjob_capture) > cat /root/.msf4/loot/20181117205902_default_127.0.0.1_prn_snarf.unknow_003464.bin
[*] exec: cat /root/.msf4/loot/20181117205902_default_127.0.0.1_prn_snarf.unknow_003464.bin

PRETTY_NAME="Kali GNU/Linux Rolling"
NAME="Kali GNU/Linux"
ID=kali
VERSION="2018.4"
VERSION_ID="2018.4"
ID_LIKE=debian
ANSI_COLOR="1;31"
HOME_URL="https://www.kali.org/"
SUPPORT_URL="https://forums.kali.org/"
BUG_REPORT_URL="https://bugs.kali.org/"

Client:

root@kali:~# cat /etc/os-release | nc 127.0.0.1 9100
^C

Go back to menu.

Msfconsole Usage


Here is how the server/capture/printjob_capture auxiliary module looks in the msfconsole:

msf6 > use auxiliary/server/capture/printjob_capture

msf6 auxiliary(server/capture/printjob_capture) > show info

       Name: Printjob Capture Service
     Module: auxiliary/server/capture/printjob_capture
    License: Metasploit Framework License (BSD)
       Rank: Normal

Provided by:
  Chris John Riley
  todb <[email protected]>

Available actions:
  Name     Description
  ----     -----------
  Capture  Run print job capture server

Check supported:
  No

Basic options:
  Name      Current Setting  Required  Description
  ----      ---------------  --------  -----------
  FORWARD   false            yes       Forward print jobs to another host
  METADATA  true             yes       Display Metadata from printjobs
  MODE      RAW              yes       Print mode (Accepted: RAW, LPR)
  RHOST                      no        Forward to remote host
  RPORT     9100             no        Forward to remote port (TCP)
  SRVHOST   0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
  SRVPORT   9100             yes       The local port to listen on

Description:
  This module is designed to listen for PJL or PostScript print jobs. 
  Once a print job is detected it is saved to loot. The captured 
  printjob can then be forwarded on to another printer (required for 
  LPR printjobs). Resulting PCL/PS files can be read with 
  GhostScript/GhostPCL. Note, this module does not yet support IPP 
  connections.

References:
  http://blog.c22.cc/toolsscripts/prn-2-me/
  http://www.ghostscript.com

Module Options


This is a complete list of options available in the server/capture/printjob_capture auxiliary module:

msf6 auxiliary(server/capture/printjob_capture) > show options

Module options (auxiliary/server/capture/printjob_capture):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   FORWARD   false            yes       Forward print jobs to another host
   METADATA  true             yes       Display Metadata from printjobs
   MODE      RAW              yes       Print mode (Accepted: RAW, LPR)
   RHOST                      no        Forward to remote host
   RPORT     9100             no        Forward to remote port (TCP)
   SRVHOST   0.0.0.0          yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT   9100             yes       The local port to listen on

Auxiliary action:

   Name     Description
   ----     -----------
   Capture  Run print job capture server

Advanced Options


Here is a complete list of advanced options supported by the server/capture/printjob_capture auxiliary module:

msf6 auxiliary(server/capture/printjob_capture) > show advanced

Module advanced options (auxiliary/server/capture/printjob_capture):

   Name            Current Setting  Required  Description
   ----            ---------------  --------  -----------
   CHOST                            no        The local client address
   CPORT                            no        The local client port
   ConnectTimeout  10               yes       Maximum number of seconds to establish a TCP connection
   ListenerComm                     no        The specific communication channel to use for this service
   Proxies                          no        A proxy chain of format type:host:port[,type:host:port][...]
   SSLCipher                        no        String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"
   SSLCompression  false            no        Enable SSL/TLS-level compression
   SSLVerifyMode   PEER             no        SSL verification method (Accepted: CLIENT_ONCE, FAIL_IF_NO_PEER_CERT, NONE, PEER)
   VERBOSE         false            no        Enable detailed status messages
   WORKSPACE                        no        Specify the workspace for this module

Auxiliary Actions


This is a list of all auxiliary actions that the server/capture/printjob_capture module can do:

msf6 auxiliary(server/capture/printjob_capture) > show actions

Auxiliary actions:

   Name     Description
   ----     -----------
   Capture  Run print job capture server

Evasion Options


Here is the full list of possible evasion options supported by the server/capture/printjob_capture auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 auxiliary(server/capture/printjob_capture) > show evasion

Module evasion options:

   Name                Current Setting  Required  Description
   ----                ---------------  --------  -----------
   TCP::max_send_size  0                no        Maxiumum tcp segment size.  (0 = disable)
   TCP::send_delay     0                no        Delays inserted before every send.  (0 = disable)

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

Cannot forward without a valid RHOST


Here is a relevant code snippet related to the "Cannot forward without a valid RHOST" error message:

58:	      @mode = datastore['MODE'].upcase || 'RAW'
59:	      if datastore['FORWARD']
60:	        @forward = datastore['FORWARD']
61:	        @rport = datastore['RPORT'] || 9100
62:	        if datastore['RHOST'].nil?
63:	          fail_with(Failure::BadConfig, "Cannot forward without a valid RHOST")
64:	        end
65:	        @rhost = datastore['RHOST']
66:	        print_status("Forwarding all printjobs to #{@rhost}:#{@rport}")
67:	      end
68:	      if not @mode == 'RAW' and not @forward

Cannot intercept LPR/IPP without a forwarding target


Here is a relevant code snippet related to the "Cannot intercept LPR/IPP without a forwarding target" error message:

64:	        end
65:	        @rhost = datastore['RHOST']
66:	        print_status("Forwarding all printjobs to #{@rhost}:#{@rport}")
67:	      end
68:	      if not @mode == 'RAW' and not @forward
69:	        fail_with(Failure::BadConfig, "Cannot intercept LPR/IPP without a forwarding target")
70:	      end
71:	      @metadata = datastore['METADATA']
72:	      print_status("Starting Print Server on %s:%s - %s mode" % [@srvhost, @srvport, @mode])
73:	
74:	      exploit()

LPR Jobcmd "%s" received


Here is a relevant code snippet related to the "LPR Jobcmd "%s" received" error message:

105:	      response = stream_data(curr_data)
106:	      c.put(response)
107:	    end
108:	
109:	    if (Rex::Text.to_hex(curr_data.first)) == '\x02' and (Rex::Text.to_hex(curr_data.last)) == '\x0a'
110:	      print_status("LPR Jobcmd \"%s\" received" % curr_data[1..-2]) if not curr_data[1..-2].empty?
111:	    end
112:	
113:	    return if not @state[c][:data]
114:	  end
115:	

Unable to detect printjob type, dumping complete output


Here is a relevant code snippet related to the "Unable to detect printjob type, dumping complete output" error message:

145:	
146:	      # extract IPP Metadata
147:	      metadata_ipp(c) if @state[c][:data] =~ /POST \/ipp/i or @state[c][:data] =~ /application\/ipp/i
148:	
149:	      if @state[c][:prn_type].empty?
150:	        print_error("Unable to detect printjob type, dumping complete output")
151:	        @state[c][:prn_type] = "Unknown Type"
152:	        @state[c][:raw_data] = @state[c][:data]
153:	      end
154:	
155:	      # output discovered Metadata if set

No metadata gathered from printjob


Here is a relevant code snippet related to the "No metadata gathered from printjob" error message:

157:	        @state[c][:meta_output].sort.each do | out |
158:	          # print metadata if not empty
159:	          print_status("#{out}") if not out.empty?
160:	        end
161:	      else
162:	        print_status("No metadata gathered from printjob")
163:	      end
164:	
165:	      # set name to unknown if not discovered via Metadata
166:	      @state[c][:prn_title] = 'Unnamed' if @state[c][:prn_title].empty?
167:	

Go back to menu.


References


See Also


Check also the following modules related to this module:

Authors


  • Chris John Riley
  • todb

Version


This page has been produced using Metasploit Framework version 6.1.27-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.