Skip to content

Commit

Permalink
Land #10981, start printjob docs and bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
busterb committed Nov 21, 2018
2 parents 77723ba + 7ecdaa0 commit 5d9195f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 28 deletions.
73 changes: 73 additions & 0 deletions documentation/modules/auxiliary/server/capture/printjob_capture.md
Original file line number Diff line number Diff line change
@@ -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
```
47 changes: 19 additions & 28 deletions modules/auxiliary/server/capture/printjob_capture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,29 @@ def initialize
},
'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
Expand All @@ -63,21 +56,20 @@ def setup
@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()

Expand Down Expand Up @@ -145,7 +137,6 @@ def on_client_close(c)
#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

Expand All @@ -155,7 +146,7 @@ def on_client_close(c)
# 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]
Expand All @@ -172,7 +163,7 @@ def on_client_close(c)
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?
Expand Down

0 comments on commit 5d9195f

Please sign in to comment.