diff --git a/documentation/modules/auxiliary/server/capture/printjob_capture.md b/documentation/modules/auxiliary/server/capture/printjob_capture.md new file mode 100644 index 0000000000..78623d6449 --- /dev/null +++ b/documentation/modules/auxiliary/server/capture/printjob_capture.md @@ -0,0 +1,73 @@ +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 +``` diff --git a/modules/auxiliary/server/capture/printjob_capture.rb b/modules/auxiliary/server/capture/printjob_capture.rb index ec2a3ddf30..b85771adce 100644 --- a/modules/auxiliary/server/capture/printjob_capture.rb +++ b/modules/auxiliary/server/capture/printjob_capture.rb @@ -22,36 +22,29 @@ class MetasploitModule < Msf::Auxiliary }, 'Author' => ['Chris John Riley', 'todb'], 'License' => MSF_LICENSE, - 'References' => + 'References' => [ # Based on previous prn-2-me tool (Python) ['URL', 'http://blog.c22.cc/toolsscripts/prn-2-me/'], # Readers for resulting PCL/PC ['URL', 'http://www.ghostscript.com'] ], - 'Actions' => - [ - [ 'Capture' ] - ], - 'PassiveActions' => - [ - 'Capture' - ], - 'DefaultAction' => 'Capture' + 'Actions' => [[ 'Capture' ]], + 'PassiveActions' => ['Capture'], + 'DefaultAction' => 'Capture' ) register_options([ - OptPort.new('SRVPORT', [ true, 'The local port to listen on', 9100 ]), - OptBool.new('FORWARD', [ true, 'Forward print jobs to another host', false ]), - OptPort.new('RPORT', [ false, 'Forward to remote port', 9100 ]), - OptAddress.new('RHOST', [ false, 'Forward to remote host' ]), - OptBool.new('METADATA', [ true, 'Display Metadata from printjobs', true ]), - OptEnum.new('MODE', [ true, 'Print mode', 'RAW', ['RAW', 'LPR']]) # TODO: Add IPP + OptPort.new('SRVPORT', [ true, 'The local port to listen on', 9100 ]), + OptBool.new('FORWARD', [ true, 'Forward print jobs to another host', false ]), + OptPort.new('RPORT', [ false, 'Forward to remote port', 9100 ]), + OptAddress.new('RHOST', [ false, 'Forward to remote host' ]), + OptBool.new('METADATA', [ true, 'Display Metadata from printjobs', true ]), + OptEnum.new('MODE', [ true, 'Print mode', 'RAW', ['RAW', 'LPR']]) # TODO: Add IPP ]) - deregister_options('SSL', 'SSLVersion', 'SSLCert') - + deregister_options('SSL', 'SSLVersion', 'SSLCert', 'RHOSTS') end def setup @@ -63,21 +56,20 @@ class MetasploitModule < Msf::Auxiliary @srvhost = datastore['SRVHOST'] @srvport = datastore['SRVPORT'] || 9100 @mode = datastore['MODE'].upcase || 'RAW' - print_status("Starting Print Server on %s:%s - %s mode" % [@srvhost, @srvport, @mode]) if datastore['FORWARD'] @forward = datastore['FORWARD'] @rport = datastore['RPORT'] || 9100 - if not datastore['RHOST'].nil? - @rhost = datastore['RHOST'] - print_status("Forwarding all printjobs to #{@rhost}:#{@rport}") - else - raise ArgumentError, "Cannot forward without a valid RHOST" + if datastore['RHOST'].nil? + fail_with(Failure::BadConfig, "Cannot forward without a valid RHOST") end + @rhost = datastore['RHOST'] + print_status("Forwarding all printjobs to #{@rhost}:#{@rport}") end if not @mode == 'RAW' and not @forward - raise ArgumentError, "Cannot intercept LPR/IPP without a forwarding target" + fail_with(Failure::BadConfig, "Cannot intercept LPR/IPP without a forwarding target") end @metadata = datastore['METADATA'] + print_status("Starting Print Server on %s:%s - %s mode" % [@srvhost, @srvport, @mode]) exploit() @@ -145,7 +137,6 @@ class MetasploitModule < Msf::Auxiliary #extract everything between PCL start and end markers (various) @state[c][:raw_data] = Array(@state[c][:data].unpack("H*")[0].match(/((1b45|1b25|1b26).*(1b45|1b252d313233343558))/i)[0]).pack("H*") end - # extract Postsript Metadata metadata_ps(c) if @state[c][:data] =~ /^%%/i @@ -155,7 +146,7 @@ class MetasploitModule < Msf::Auxiliary # extract IPP Metadata metadata_ipp(c) if @state[c][:data] =~ /POST \/ipp/i or @state[c][:data] =~ /application\/ipp/i - if not @state[c][:prn_type] + if @state[c][:prn_type].empty? print_error("Unable to detect printjob type, dumping complete output") @state[c][:prn_type] = "Unknown Type" @state[c][:raw_data] = @state[c][:data] @@ -172,7 +163,7 @@ class MetasploitModule < Msf::Auxiliary end # set name to unknown if not discovered via Metadata - @state[c][:prn_title] = 'Unnamed' if not @state[c][:prn_title] + @state[c][:prn_title] = 'Unnamed' if @state[c][:prn_title].empty? #store loot storefile(c) if not @state[c][:raw_data].empty?